server_controller.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import json
  2. from bottle import request, response
  3. import model
  4. from debug import debug
  5. from passlib.hash import sha256_crypt
  6. from util import salt
  7. def missing_attributes(attributes):
  8. for attr in attributes:
  9. if attr not in request.json or request.json[attr] == '' or request.json[attr] is None:
  10. if str(attr) == 'session_id':
  11. return 'You are not signed in.'
  12. return 'Missing value for attribute ' + str(attr)
  13. if str(attr) == 'session_id':
  14. if not model.valid_session_id(request.json['session_id']):
  15. return 'You are not signed in.'
  16. return False
  17. def login():
  18. missing = missing_attributes(['username', 'password'])
  19. if missing:
  20. return bad_request(missing)
  21. username = request.json['username']
  22. password = request.json['password']
  23. session_id = model.login(username, password)
  24. if session_id:
  25. return {'session_id': session_id}
  26. else:
  27. return forbidden('Invalid login data')
  28. def depot():
  29. missing = missing_attributes(['session_id'])
  30. if missing:
  31. return bad_request(missing)
  32. user_id = model.get_user_id_by_session_id(request.json['session_id'])
  33. return {'data': model.get_user_ownership(user_id),
  34. 'own_wealth': model.user_wealth(user_id)}
  35. def register():
  36. missing = missing_attributes(['username', 'password'])
  37. if missing:
  38. return bad_request(missing)
  39. username = request.json['username'].strip()
  40. if username == '':
  41. return bad_request('Username can not be empty.')
  42. hashed_password = sha256_crypt.encrypt(request.json['password'] + salt)
  43. if model.user_exists(username):
  44. return bad_request('User already exists.')
  45. game_key = ''
  46. if 'game_key' in request.json:
  47. game_key = request.json['game_key'].strip().upper()
  48. if game_key != '' and game_key not in model.unused_keys():
  49. return bad_request('Game key is not valid.')
  50. if model.register(username, hashed_password, game_key):
  51. return {'message': "successfully registered user"}
  52. else:
  53. return bad_request('registration not successful')
  54. def activate_key():
  55. missing = missing_attributes(['key', 'session_id'])
  56. if missing:
  57. return bad_request(missing)
  58. if model.valid_key(request.json['key']):
  59. user_id = model.get_user_id_by_session_id(request.json['session_id'])
  60. model.activate_key(request.json['key'], user_id)
  61. return {'message': "successfully activated key"}
  62. else:
  63. return bad_request('Invalid key.')
  64. def order():
  65. missing = missing_attributes(['buy', 'session_id', 'amount', 'ownable', 'time_until_expiration'])
  66. if missing:
  67. return bad_request(missing)
  68. if not model.ownable_name_exists(request.json['ownable']):
  69. return bad_request('This kind of object can not be ordered.')
  70. buy = request.json['buy']
  71. sell = not buy
  72. session_id = request.json['session_id']
  73. amount = request.json['amount']
  74. try:
  75. amount = int(amount)
  76. except ValueError:
  77. return bad_request('Invalid amount.')
  78. if amount < 0:
  79. return bad_request('You can not order a negative amount.')
  80. if amount < 1:
  81. return bad_request('The minimum order size is 1.')
  82. ownable_name = request.json['ownable']
  83. time_until_expiration = float(request.json['time_until_expiration'])
  84. if time_until_expiration < 0:
  85. return bad_request('Invalid expiration time.')
  86. ownable_id = model.ownable_id_by_name(ownable_name)
  87. user_id = model.get_user_id_by_session_id(session_id)
  88. model.own(user_id, ownable_name)
  89. ownership_id = model.get_ownership_id(ownable_id, user_id)
  90. try:
  91. if request.json['limit'] == '':
  92. limit = None
  93. elif request.json['limit'] is None:
  94. limit = None
  95. else:
  96. limit = float(request.json['limit'])
  97. except ValueError: # for example when float fails
  98. limit = None
  99. except KeyError: # for example when limit was not specified
  100. limit = None
  101. try:
  102. if request.json['stop_loss'] == '':
  103. stop_loss = None
  104. elif request.json['stop_loss'] is None:
  105. stop_loss = None
  106. else:
  107. stop_loss = 'stop_loss' in request.json and request.json['stop_loss']
  108. if stop_loss is not None and limit is None:
  109. return bad_request('Can only set stop-loss for limit orders')
  110. except KeyError: # for example when stop_loss was not specified
  111. stop_loss = None
  112. if sell:
  113. if not model.user_owns_at_least(amount, user_id, ownable_id):
  114. return bad_request('You can not sell more than you own.')
  115. model.place_order(buy, ownership_id, limit, stop_loss, amount, time_until_expiration)
  116. return {'message': "Order placed."}
  117. def gift():
  118. missing = missing_attributes(['session_id', 'amount', 'object_name', 'username'])
  119. if missing:
  120. return bad_request(missing)
  121. if not model.ownable_name_exists(request.json['object_name']):
  122. return bad_request('This kind of object can not be given away.')
  123. if request.json['username'] == 'bank' or not model.user_exists(request.json['username']):
  124. return bad_request('There is no user with this name.')
  125. try:
  126. amount = float(request.json['amount'])
  127. except ValueError:
  128. return bad_request('Invalid amount.')
  129. ownable_id = model.ownable_id_by_name(request.json['object_name'])
  130. sender_id = model.get_user_id_by_session_id(request.json['session_id'])
  131. recipient_id = model.get_user_id_by_name(request.json['username'])
  132. if not model.user_owns_at_least(amount, sender_id, ownable_id):
  133. amount = model.available_amount(sender_id, ownable_id)
  134. model.send_ownable(sender_id, recipient_id, request.json['object_name'], amount)
  135. return {'message': "Gift sent."}
  136. def orders():
  137. missing = missing_attributes(['session_id'])
  138. if missing:
  139. return bad_request(missing)
  140. data = model.get_user_orders(model.get_user_id_by_session_id(request.json['session_id']))
  141. return {'data': data}
  142. def orders_on():
  143. missing = missing_attributes(['session_id', 'ownable'])
  144. if missing:
  145. return bad_request(missing)
  146. if not model.ownable_name_exists(request.json['ownable']):
  147. return bad_request('This kind of object can not be ordered.')
  148. data = model.get_ownable_orders(model.ownable_id_by_name(request.json['ownable']))
  149. return {'data': data}
  150. def cancel_order():
  151. missing = missing_attributes(['session_id', 'order_id'])
  152. if missing:
  153. return bad_request(missing)
  154. if not model.user_has_order_with_id(request.json['session_id'], request.json['order_id']):
  155. return bad_request('You do not have an order with that number.')
  156. model.delete_order(request.json['order_id'])
  157. return {'message': "Successfully deleted order"}
  158. def change_password():
  159. missing = missing_attributes(['session_id', 'password'])
  160. if missing:
  161. return bad_request(missing)
  162. hashed_password = sha256_crypt.encrypt(request.json['password'] + salt)
  163. model.change_password(request.json['session_id'], hashed_password)
  164. model.sign_out_user(request.json['session_id'])
  165. return {'message': "Successfully changed password"}
  166. def news():
  167. return {'data': model.news()}
  168. def transactions():
  169. missing = missing_attributes(['session_id', 'ownable'])
  170. if missing:
  171. return bad_request(missing)
  172. if not model.ownable_name_exists(request.json['ownable']):
  173. return bad_request('This kind of object can not have transactions.')
  174. return {'data': model.transactions(model.ownable_id_by_name(request.json['ownable']))}
  175. def leaderboard():
  176. missing = missing_attributes(['session_id'])
  177. if missing:
  178. return bad_request(missing)
  179. return {'data': model.leaderboard()}
  180. def not_found(msg=''):
  181. response.status = 404
  182. if debug:
  183. msg = str(response.status) + ': ' + msg
  184. response.content_type = 'application/json'
  185. return json.dumps({"error_message": msg})
  186. def forbidden(msg=''):
  187. response.status = 403
  188. if debug:
  189. msg = str(response.status) + ': ' + msg
  190. response.content_type = 'application/json'
  191. return json.dumps({"error_message": msg})
  192. def bad_request(msg=''):
  193. response.status = 400
  194. if debug:
  195. msg = str(response.status) + ': ' + msg
  196. response.content_type = 'application/json'
  197. return json.dumps({"error_message": msg})