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
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:
return False
def authMifareCard(self, cardId):
+ self._loggedIn = False
+ self._username = None
if DISPSRV_MIFARE:
card_base64 = base64.b64encode(cardId)
+
+ 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)
- sock.write("AUTHIDENT\n")
- rsp = sock.readline()
+ logging.debug('connected to dispsrv')
+ sockf = sock.makefile()
+ sockf.write("AUTHIDENT\n"); sockf.flush()
+ rsp = sockf.readline()
assert "200" in rsp
- sock.write("AUTHCARD %s\n" % (card_base64,))
- rsp = sock.readline()
+ logging.debug('authenticated')
+ sockf.write("AUTHCARD %s\n" % (card_base64,)); sockf.flush()
+ rsp = sockf.readline()
if not "200" in rsp:
- raise ValueError, "no UID found for card ID"
- username = rsp.split('=')[1]
-
- # Check for thier username
- try:
- # Get info from the system (by username)
- info = pwd.getpwnam(username)
- except KeyError:
- logging.info('getting pin for uid %d: user not in password file'%uid)
+ 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)
# Get info from the system (by UID)
info = pwd.getpwuid(self._userid)
except KeyError:
- logging.info('getting pin for uid %d: user not in password file'%uid)
+ 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._userid = info.pw_uid
- 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 not self.isLoggedIn():
return False
if DISPSRV_MIFARE:
card_base64 = base64.b64encode(cardId)
- logging.info('Enrolling card %s to uid %s (%s)' % (cardId, self._userId, self._username))
+ 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)
- sock.write("AUTHIDENT\n")
- rsp = sock.readline()
+ sockf = sock.makefile()
+ sockf.write("AUTHIDENT\n")
+ sockf.flush(); rsp = sockf.readline()
assert "200" in rsp
- sock.write("SETEUSER %s\n", self._username)
- rsp = sock.readline()
+ sockf.write("SETEUSER %s\n" % (self._username,))
+ sockf.flush(); rsp = sockf.readline()
assert "200" in rsp
- sock.write("CARD_ADD %s\n", card_base64)
- rsp = sock.readline()
+ sockf.write("CARD_ADD %s\n" % (card_base64,))
+ sockf.flush(); rsp = sockf.readline()
if "200" in rsp:
return True
else:
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()
@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()
print(map)
return map
+
+# vim: noexpandtab ts=4 sw=4