X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=VendServer%2FOpenDispense.py;h=6b93058b19e0dac3bf1b9a921f8e5229ed736f05;hb=aded467b8f44b5bf2bad2ae3cf3327112cc50888;hp=3790348b7f4a55eb8548ac77ae3c189994ef5582;hpb=8be035ce9efb672e5a6b47561c315ee8a1c52d4d;p=uccvend-vendserver.git diff --git a/VendServer/OpenDispense.py b/VendServer/OpenDispense.py index 3790348..6b93058 100644 --- a/VendServer/OpenDispense.py +++ b/VendServer/OpenDispense.py @@ -12,9 +12,21 @@ import os import logging import re import pwd +import base64 +import socket from subprocess import Popen, PIPE from LDAPConnector import get_uid,get_uname, set_card_id +DISPENSE_ENDPOINT = ("localhost", 11020) +DISPSRV_MIFARE = True + +# A list of cards that should never be registered, and should never log in +# - Some of these might have been registered before we knew they were duplicates +CARD_BLACKLIST = [ + 'AAAAAA==', # All zeroes, don't allow that. + 'ISIjJA==', # CommBank credit cards + ] + class OpenDispense(DispenseInterface): _username = "" _disabled = True @@ -25,6 +37,41 @@ class OpenDispense(DispenseInterface): pass def authUserIdPin(self, userId, pin): + return self.authUserIdPin_db(userId, pin) + #return self.authUserIdPin_file(userId, pin) + + def authUserIdPin_db(self, userId, pin): + userId = int(userId) + + try: + # Get username (TODO: Store the user ID in the dispense database too) + info = pwd.getpwuid(userId) + except KeyError: + logging.info('getting pin for uid %d: user not in password file'%userId) + return False + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + sock.connect(DISPENSE_ENDPOINT) + logging.debug('connected to dispsrv') + sockf = sock.makefile() + sockf.write("AUTHIDENT\n"); sockf.flush() + rsp = sockf.readline() + assert "200" in rsp + logging.debug('authenticated') + sockf.write("PIN_CHECK %s %s\n" % (info.pw_name, pin)); sockf.flush() + rsp = sockf.readline() + if not "200" in rsp: + logging.info('checking pin for uid %d: Server said no - %r' % (userId, rsp)) + return False + #Login Successful + logging.info('accepted pin for uid %d \'%s\'' % (userId, info.pw_name)) + self._userid = userId + self._loggedIn = True + self._disabled = False + self._username = info.pw_name + return True + + def authUserIdPin_file(self, userId, pin): userId = int(userId) try: @@ -67,27 +114,96 @@ class OpenDispense(DispenseInterface): return False def authMifareCard(self, cardId): - # Get the users ID - self._userid = get_uid(cardId) + self._loggedIn = False + self._username = None + if DISPSRV_MIFARE: + card_base64 = base64.b64encode(cardId) - # Check for thier username - try: - # Get info from - info = pwd.getpwuid(userId) - except KeyError: - logging.info('getting pin for uid %d: user not in password file'%uid) - return False + if card_base64 in CARD_BLACKLIST: + logging.info("Blacklisted card base64:%s" % (card_base64,)) + return False + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + sock.connect(DISPENSE_ENDPOINT) + logging.debug('connected to dispsrv') + sockf = sock.makefile() + sockf.write("AUTHIDENT\n"); sockf.flush() + rsp = sockf.readline() + assert "200" in rsp + logging.debug('authenticated') + sockf.write("AUTHCARD %s\n" % (card_base64,)); sockf.flush() + rsp = sockf.readline() + if not "200" in rsp: + logging.info("Rejected card base64:%s" % (card_base64,)) + return False + username = rsp.split('=')[1].strip() + logging.info("Accepted card base64:%s for %s" % (card_base64,username,)) + + ## Check for thier username + #try: + # # Get info from the system (by username) + # info = pwd.getpwnam(username) + #except KeyError: + # logging.info('getting info for user \'%s\': user not in password file' % (username,)) + # return False + #self._userid = info.pw_uid + self._userid = None + self._username = username + else: + # Get the users ID + self._userid = get_uid(cardId) + + # Check for thier username + try: + # Get info from the system (by UID) + info = pwd.getpwuid(self._userid) + except KeyError: + logging.info('getting info for uid %d: user not in password file' % (self._userid,)) + return False + self._username = info.pw_name # If we get this far all is good self._loggedIn = True self._disabled = False - self._username = info.pw_name return True + def logOut(self): + self._loggedIn = False + self._disabled = False + self._userId = None + self._username = None + def addCard(self, cardId): - if self.isLoggedIn(): - set_card_id(self._userId, cardId) - return True + if not self.isLoggedIn(): + return False + if DISPSRV_MIFARE: + card_base64 = base64.b64encode(cardId) + if card_base64 in CARD_BLACKLIST: + logging.info("Blacklisted card base64:%s" % (card_base64,)) + return False + logging.info('Enrolling card base64:%s to uid %s (%s)' % (card_base64, self._userId, self._username)) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + sock.connect(DISPENSE_ENDPOINT) + sockf = sock.makefile() + sockf.write("AUTHIDENT\n") + sockf.flush(); rsp = sockf.readline() + assert "200" in rsp + sockf.write("SETEUSER %s\n" % (self._username,)) + sockf.flush(); rsp = sockf.readline() + assert "200" in rsp + sockf.write("CARD_ADD %s\n" % (card_base64,)) + sockf.flush(); rsp = sockf.readline() + if "200" in rsp: + return True + else: + return False + else: + if get_uid(cardId) != None: + return False + else: + logging.info('Enrolling card %s to uid %s (%s)' % (cardId, self._userId, self._username)) + set_card_id(self._userId, cardId) + return True def isLoggedIn(self): return self._loggedIn @@ -105,6 +221,7 @@ class OpenDispense(DispenseInterface): return balance def getItemInfo(self, itemId): + logging.debug("getItemInfo(%s)" % (itemId,)) itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId) args = ('dispense', 'iteminfo', itemId) info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate() @@ -141,8 +258,20 @@ class OpenDispenseMapping(): @staticmethod def vendingMachineToOpenDispense(itemId): + logging.debug("vendingMachineToOpenDispense(%s)" % (itemId,)) _mappingFile = "OpenDispenseMappings.conf" - fh = open(_mappingFile) + try: + fh = open(_mappingFile) + except IOError: + if itemId[1] == '8': + return 'coke:' + itemId[0] + elif itemId[1] == '5': + if itemId[0] == '5': + return 'door' + else: + return None + else: + return 'snack:' + itemId map = "" for line in fh: #line = line.strip() @@ -151,3 +280,5 @@ class OpenDispenseMapping(): print(map) return map + +# vim: noexpandtab ts=4 sw=4