Commit a0c785ac authored by Mitchell Pomery's avatar Mitchell Pomery Committed by Mark Tearle
Browse files

Fix up dispense abstraction

parent 408301a9
......@@ -10,67 +10,82 @@ class DispenseInterface(object):
"""
Create a new dispense object.
@param username The username to connect to dispense with
@param secret The secret to use for Auth
"""
def __init__(self, username=None, loggedIn=False, disabled=False):
def __init__(self, username=None, secret=None):
pass
"""
Create a new dispense interface as the supplied user.
@param username The userid of the person authing to dispense
@param pin Thier pin
"""
@staticmethod
def authUsernamePin(username, pin):
def authUsernamePin(self, userId, pin):
pass
"""
Create a new dispense interface as the supplied user.
@param cardId The card that someone is connecting to Dispense with
"""
@staticmethod
def authMifare(cardId):
def authMifare(self, cardId):
pass
"""
Add a MIFARE card for this user
@param cardId Card to add to a user account
@return 1 if added successfully, anything else otherwise
"""
def addCard(self, cardId):
pass
"""
Check if creating the user worked correctly.
@return True if currently logged in as a user, false otherwise
"""
def isLoggedIn(self):
pass
"""
Get the users username.
Get the current users username.
@return The username of the current user. An empty string if not currently logged in.
"""
def getUsername(self, user):
def getUsername(self):
pass
"""
Get the users current balance.
Get the current users balance.
@return the users balance. None if not logged in.
"""
def getBalance(self, user):
def getBalance(self):
pass
"""
Get the name and price of an item.
itemId is the number entered into the vending machine
@param itemId The number entered into the vending machine
@return (itemname, price)
"""
@staticmethod
def getItemInfo(itemId):
pass
"""
Check if the user is disabled.
@return True if the user is disabled
"""
def isDisabled(self):
pass
"""
Dispense an item for the current user.
itemId is the number entered into the vending machine
@param itemId The number entered into the vending machine
"""
def dispenseItem(self, itemId):
pass
"""
Log the current user out
"""
def logOut(self):
pass
from DispenseInterface import DispenseInterface
import os
import re
import pwd
from subprocess import Popen, PIPE
from LDAPConnector import get_uid,get_uname, set_card_id
"""
Author: Mitchell Pomery (bobgeorge33)
......@@ -13,97 +6,128 @@ Most of this code has been copied out of VendServer.py, then had variables updat
This is so VendServer can easily operate regardless of the current accounting backend.
Documentation for this code can be found inder Dispence.DispenceInterface
"""
from DispenseInterface import DispenseInterface
import os
import re
import pwd
from subprocess import Popen, PIPE
from LDAPConnector import get_uid,get_uname, set_card_id
class OpenDispense(DispenseInterface):
_username = None
_disabled = True
_loggedIn = False
_username = ""
_disabled = True
_loggedIn = False
_userId = None
def __init__(self, userId=None, username=None, loggedIn=False):
self._username = username
self._loggedIn = loggedIn
self._userId = userId
acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
# this is fucking appalling
flags = acct[acct.find("(")+1:acct.find(")")].strip()
if 'disabled' in flags:
self._disabled = True
if 'internal' in flags:
self._disabled = True
self._disabled = False
def __init__(self, username=None, secret=False):
pass
@staticmethod
def authUserIdPin(userId, pin):
def authUserIdPin(self, userId, pin):
try:
# Get info from
info = pwd.getpwuid(userId)
except KeyError:
logging.info('getting pin for uid %d: user not in password file'%uid)
return None
if info.pw_dir == None: return False
pinfile = os.path.join(info.pw_dir, '.pin')
try:
s = os.stat(pinfile)
except OSError:
logging.info('getting pin for uid %d: .pin not found in home directory'%uid)
return None
if s.st_mode & 077:
logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%uid)
os.chmod(pinfile, 0600)
try:
f = file(pinfile)
except IOError:
logging.info('getting pin for uid %d: I cannot read pin file'%uid)
return None
pinstr = f.readline().strip()
f.close()
if not re.search('^[0-9]{4}$', pinstr):
logging.info('getting pin for uid %d: %s not a good pin'%(uid,repr(pinstr)))
return None
return OpenDispense(userId, info.pw_name, (int(pin)==int(pinstr)))
info = pwd.getpwuid(userId)
except KeyError:
logging.info('getting pin for uid %d: user not in password file'%userId)
return False
@staticmethod
def authMifareCard(cardId):
return OpenDispense(get_uid(cardId), get_uname(get_uid(cardId)), True)
if info.pw_dir == None: return False
pinfile = os.path.join(info.pw_dir, '.pin')
try:
s = os.stat(pinfile)
except OSError:
logging.info('getting pin for uid %d: .pin not found in home directory'%userId)
return False
if s.st_mode & 077:
logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%userId)
os.chmod(pinfile, 0600)
try:
f = file(pinfile)
except IOError:
logging.info('getting pin for uid %d: I cannot read pin file'%userId)
return False
pinstr = f.readline().strip()
f.close()
if not re.search('^[0-9]{4}$', pinstr):
logging.info('getting pin for uid %d: %s not a good pin'%(userId,repr(pinstr)))
return False
if pinstr == str(pin):
#Login Successful
self._userid = userId
self._loggedIn = True
self._disabled = False
self._username = info.pw_name
return True
# Login Unsuccessful
return False
def authMifareCard(self, cardId):
# Get the users ID
self._userid = get_uid(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 we get this far all is good
self._loggedIn = True
self._disabled = False
self._username = info.pw_name
return True
def addCard(self, cardId):
set_card_id(self._userId, cardId)
if self.isLoggedIn():
set_card_id(self._userId, cardId)
return True
def isLoggedIn(self):
return self._loggedIn
def isLoggedIn(self):
return self._loggedIn
def getUsername(self):
return self._username
def getUsername(self):
return self._username
def getBalance(self):
def getBalance(self):
# Balance checking
acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
# this is fucking appalling
balance = acct[acct.find("$")+1:acct.find("(")].strip()
return balance
if self.isLoggedIn():
acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
else:
return None
balance = acct[acct.find("$")+1:acct.find("(")].strip()
return balance
def getItemInfo(itemId):
def getItemInfo(self, itemId):
itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
args = ('dispense', 'iteminfo', itemId)
info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info)
cents = int(m.group(1))*100 + int(m.group(2))
info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info)
if m == None:
return("dead", 0)
cents = int(m.group(1))*100 + int(m.group(2))
# return (name, price in cents)
return (m.group(3), cents)
return (m.group(3), cents)
def isDisabled(self):
return False
def isDisabled(self):
return self._disabled
def dispenseItem(self, itemId):
itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
if itemId == "":
def dispenseItem(self, itemId):
if not self.isLoggedIn() or self.getItemInfo(itemId)[0] == "dead":
return False
else:
print('dispense -u "%s" %s'%(self._username, itemId))
os.system('dispense -u "%s" %s'%(self._username, itemId))
return True
#os.system('dispense -u "%s" %s'%(self._username, itemId))
return True
def logOut(self):
self._username = ""
self._disabled = True
self._loggedIn = False
self._userId = None
"""
This class abstracts the idea of item numbers.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment