Niklas Brachmann
11 years ago
2 changed files with 213 additions and 0 deletions
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
from cash.models import * |
||||
from django.http import HttpResponse |
||||
from django.contrib.auth import authenticate |
||||
from django.views.decorators.csrf import csrf_exempt |
||||
from django.contrib.sessions.backends.db import SessionStore |
||||
import json |
||||
import hashlib |
||||
|
||||
API_VERSION = 2 |
||||
|
||||
err_msgs = {} |
||||
|
||||
#Global errors |
||||
ERR_DATABASE = 1 |
||||
ERR_PARSE_REQUEST = 2 |
||||
ERR_UNKNOWN_ACTION = 3 |
||||
ERR_PARAM = 4 |
||||
ERR_INVALID_SESSION = 5 |
||||
|
||||
err_msgs[ERR_DATABASE] = 'Can\'t connect to database' |
||||
err_msgs[ERR_PARSE_REQUEST] = 'Error while parsing request' |
||||
err_msgs[ERR_UNKNOWN_ACTION] = 'Unknown action specified' |
||||
err_msgs[ERR_PARAM] = 'Given parameters don\'t match the actions requirements' |
||||
err_msgs[ERR_INVALID_SESSION] = 'The session key is invalid' |
||||
|
||||
#Auth key errors |
||||
ERR_INVALID_AUTH_KEY = 6 |
||||
ERR_AUTH_KEY_LOCKED = 7 |
||||
ERR_AUTH_KEY_NOT_PERMITTED = 8 |
||||
|
||||
err_msgs[ERR_INVALID_AUTH_KEY] = 'The given authentication key is invalid' |
||||
err_msgs[ERR_AUTH_KEY_LOCKED] = 'The given authentication key is locked' |
||||
err_msgs[ERR_AUTH_KEY_NOT_PERMITTED] = 'The given authentication key has insufficient permissions for this action' |
||||
|
||||
#Errors for get_user_info |
||||
ERR_USER_NOT_FOUND = 11 |
||||
ERR_INCORRECT_PIN = 12 |
||||
|
||||
err_msgs[ERR_USER_NOT_FOUND] = 'Unknown user' |
||||
err_msgs[ERR_INCORRECT_PIN] = 'Pin/Password is not valid' |
||||
|
||||
#Errors for get_item_infos |
||||
ERR_ITEM_NOT_FOUND = 31 |
||||
|
||||
err_msgs[ERR_ITEM_NOT_FOUND] = 'Can\'t find the given item' |
||||
|
||||
#Errors for buy_items |
||||
ERR_ITEM_NOT_FOUND_ = 41 |
||||
ERR_INSUFFICIENT_CREDIT = 42 |
||||
|
||||
err_msgs[ERR_ITEM_NOT_FOUND_] = 'At least one of the items to buy could not be found' |
||||
err_msgs[ERR_INSUFFICIENT_CREDIT] = 'The user has not enough money left to buy the specified items' |
||||
|
||||
#Errors for cash_prepaid_card |
||||
ERR_CASH_CODE_NOT_VALID = 51 |
||||
|
||||
err_msgs[ERR_CASH_CODE_NOT_VALID] = 'Given code can\'t be found or has already been used' |
||||
|
||||
#Errors for cash_[gs]et_config_key |
||||
ERR_CONFIG_TYPE_MISMATCH = 61 |
||||
ERR_CONFIG_UNKNOWN_TYPE = 62 |
||||
|
||||
err_msgs[ERR_CONFIG_TYPE_MISMATCH] = 'Value in database doesn\'t match the datatype for that key' |
||||
err_msgs[ERR_CONFIG_UNKNOWN_TYPE] = 'Given value is neither int, bool, string nor float' |
||||
|
||||
#Errors for cash_modify_credit |
||||
ERR_USER_NOT_FOUND__ = 71 |
||||
ERR_USER_NOT_AUTHORIZED = 72 |
||||
|
||||
err_msgs[ERR_USER_NOT_FOUND] = 'User not found' |
||||
err_msgs[ERR_USER_NOT_AUTHORIZED] = 'User not authorized to change another user\'s credit' |
||||
|
||||
class ApiError(Exception): |
||||
def __init__(self, code): |
||||
self.code = code |
||||
|
||||
def check_session(data): |
||||
try: |
||||
key = data['session_key'] |
||||
except KeyError: |
||||
raise ApiError(ERR_PARAM) |
||||
|
||||
s = SessionStore(session_key = key) |
||||
|
||||
if not s.exists(key): |
||||
raise ApiError(ERR_INVALID_SESSION) |
||||
|
||||
return s |
||||
|
||||
# Disable CSRF, because clients don't do cookies |
||||
@csrf_exempt |
||||
def cashapi(request): |
||||
retval = {} |
||||
|
||||
error = {'code': 0, 'msg': None} |
||||
|
||||
try: |
||||
try: |
||||
req = json.loads(request.body) |
||||
except: |
||||
raise ApiError(ERR_PARSE_REQUEST) |
||||
|
||||
print req |
||||
|
||||
action = req['action'] |
||||
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) |
||||
|
||||
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) |
||||
|
||||
elif action == 'get_user_info': |
||||
s = check_session(data) |
||||
|
||||
user = User.objects.get(pk = s['userid']) |
||||
|
||||
retval['id'] = user.id |
||||
retval['name'] = user.first_name + ' ' + user.last_name |
||||
retval['nick'] = user.username |
||||
retval['mail'] = user.email |
||||
retval['card_number'] = user.account.card_number |
||||
retval['credit'] = int(user.account.credit * 100) |
||||
|
||||
elif action == 'get_item_info': |
||||
try: |
||||
try: |
||||
item = Product.objects.get(pk = data['id']) |
||||
except KeyError: |
||||
try: |
||||
item = Product.objects.get(productbarcode__barcode = data['ean']) |
||||
except KeyError: |
||||
raise ApiError(ERR_PARAM) |
||||
except Product.DoesNotExist: |
||||
raise ApiError(ERR_ITEM_NOT_FOUND) |
||||
|
||||
retval['id'] = item.id |
||||
retval['name'] = item.name |
||||
retval['ean'] = str(item.productbarcode_set.all()[0]) |
||||
retval['price'] = int(item.price * 100) |
||||
|
||||
elif action == 'buy_items': |
||||
s = check_session(data) |
||||
|
||||
shopping_list = {} |
||||
try: |
||||
for item in data['items']: |
||||
try: |
||||
p = Product.objects.get(pk = item[0]) |
||||
shopping_list[p] = int(item[1]) |
||||
except Product.DoesNotExist: |
||||
raise ApiError(ERR_ITEM_NOT_FOUND_) |
||||
except ValueError: |
||||
raise ApiError(ERR_PARAM) |
||||
except KeyError: |
||||
raise ApiError(ERR_PARAM) |
||||
|
||||
user = User.objects.get(pk = s['userid']) |
||||
try: |
||||
if user.account.buy_products(shopping_list): |
||||
retval['new_credit'] = int(user.account.credit * 100) |
||||
else: |
||||
raise ApiError(ERR_INSUFFICIENT_CREDIT) |
||||
except ValueError: |
||||
raise ApiError(ERR_PARAM) |
||||
|
||||
|
||||
except ApiError as e: |
||||
error = {'code': e.code, 'msg': err_msgs[e.code]} |
||||
|
||||
# Generate return object |
||||
ret = {'err_code': error['code'], 'err_msg': error['msg'], 'return_values': retval, 'api_version': API_VERSION} |
||||
|
||||
print ret |
||||
|
||||
return HttpResponse(json.dumps(ret)) |
Loading…
Reference in new issue