diff --git a/TODO b/TODO index a948cc5..cdbe76d 100644 --- a/TODO +++ b/TODO @@ -4,7 +4,6 @@ User: * Mehrere Sachen kaufen API: - * PIN als AuthMech * MaMue-Funktionen Tools: diff --git a/cash/api.py b/cash/api.py index 6802ef1..99d5c5a 100644 --- a/cash/api.py +++ b/cash/api.py @@ -87,6 +87,22 @@ def check_session(data): return s +def start_session(credentials): + try: + user = authenticate(**credentials) + except KeyError: + raise ApiError(ERR_PARAM) + + if user is not None: + # Credentials are valid, so save user id in session + s = SessionStore() + s['userid'] = user.id + s.save() + + return s.session_key + else: + raise ApiError(ERR_INCORRECT_PIN) + # Disable CSRF, because clients don't do cookies @csrf_exempt def cashapi(request): @@ -106,44 +122,12 @@ def cashapi(request): data = req['data'] if action == 'start_session_password': - try: - user = authenticate(username = data['user'], password = data['password']) - except KeyError: - raise ApiError(ERR_PARAM) - - if user is not None: - # Credentials are valid, so save user id in session - s = SessionStore() - s['userid'] = user.id - s.save() - - retval['session_key'] = s.session_key - else: - apierror(ERR_INCORRECT_PIN) + creds = {'username': data['user'], 'password': data['password']} + retval['session_key'] = start_session(creds) elif action == 'start_session_pin': - try: - if not (data['card_number'].isnumeric()): # and (data['pin'].isnumeric() or data['pin'] == '')): - raise ApiError(ERR_PARAM) - except KeyError: - raise ApiError(ERR_PARAM) - - try: - user = User.objects.get(account__card_number = data['card_number']) - if hashlib.md5(user.account.pin).hexdigest() != data['pin']: - raise ApiError(ERR_INCORRECT_PIN) - except User.DoesNotExist: - raise ApiError(ERR_USER_NOT_FOUND) - - if user is not None: - # Credentials are valid, so save user id in session - s = SessionStore() - s['userid'] = user.id - s.save() - - retval['session_key'] = s.session_key - else: - raise ApiError(ERR_INCORRECT_PIN) + creds = {'card_number': data['card_number'], 'pin': data['pin']} + retval['session_key'] = start_session(creds) elif action == 'get_user_info': s = check_session(data) diff --git a/cash/auth.py b/cash/auth.py new file mode 100644 index 0000000..edcca89 --- /dev/null +++ b/cash/auth.py @@ -0,0 +1,21 @@ +from django.contrib.auth.models import User +from cash.models import Account + +class CashBackend(object): + def authenticate(self, card_number=None, pin=None): + if not card_number.isdigit(): + raise ValueError('card_number has to consist of digits only!') + + if len(pin) > 0 and not pin.isdigit(): + raise ValueError('pin has to consist of digits only or \ + has to be empty!') + + try: + account = Account.objects.get(card_number=card_number) + except Account.DoesNotExist: + return None + + if account.check_pin(pin): + return account.user + + return None diff --git a/cash/models.py b/cash/models.py index e7fa353..66fcecb 100644 --- a/cash/models.py +++ b/cash/models.py @@ -85,6 +85,9 @@ class Account(models.Model): self.pin = '' self.save() + def check_pin(self, pin): + return pin == self.pin + class ProductCategory(models.Model): name = models.CharField(max_length=32, unique=True, verbose_name = _('name')) diff --git a/lugcash2/settings.py b/lugcash2/settings.py index 5e0e8d3..926afe8 100644 --- a/lugcash2/settings.py +++ b/lugcash2/settings.py @@ -180,6 +180,7 @@ LOGIN_REDIRECT_URL = '/' AUTHENTICATION_BACKENDS = ( 'django_auth_ldap.backend.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', + 'cash.auth.CashBackend', ) AUTH_LDAP_SERVER_URI = "ldap://seraph"