You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
5.8 KiB

2 years ago
  1. import jwt
  2. import time
  3. import logging
  4. import sqlite3 as sqlite
  5. from be.model import error
  6. from be.model import db_conn
  7. # encode a json string like:
  8. # {
  9. # "user_id": [user name],
  10. # "terminal": [terminal code],
  11. # "timestamp": [ts]} to a JWT
  12. # }
  13. def jwt_encode(user_id: str, terminal: str) -> str:
  14. encoded = jwt.encode(
  15. {"user_id": user_id, "terminal": terminal, "timestamp": time.time()},
  16. key=user_id,
  17. algorithm="HS256",
  18. )
  19. return encoded.decode("utf-8")
  20. # decode a JWT to a json string like:
  21. # {
  22. # "user_id": [user name],
  23. # "terminal": [terminal code],
  24. # "timestamp": [ts]} to a JWT
  25. # }
  26. def jwt_decode(encoded_token, user_id: str) -> str:
  27. decoded = jwt.decode(encoded_token, key=user_id, algorithms="HS256")
  28. return decoded
  29. class User(db_conn.DBConn):
  30. token_lifetime: int = 3600 # 3600 second
  31. def __init__(self):
  32. db_conn.DBConn.__init__(self)
  33. def __check_token(self, user_id, db_token, token) -> bool:
  34. try:
  35. if db_token != token:
  36. return False
  37. jwt_text = jwt_decode(encoded_token=token, user_id=user_id)
  38. ts = jwt_text["timestamp"]
  39. if ts is not None:
  40. now = time.time()
  41. if self.token_lifetime > now - ts >= 0:
  42. return True
  43. except jwt.exceptions.InvalidSignatureError as e:
  44. logging.error(str(e))
  45. return False
  46. def register(self, user_id: str, password: str):
  47. try:
  48. terminal = "terminal_{}".format(str(time.time()))
  49. token = jwt_encode(user_id, terminal)
  50. self.conn.execute(
  51. "INSERT into user(user_id, password, balance, token, terminal) "
  52. "VALUES (?, ?, ?, ?, ?);",
  53. (user_id, password, 0, token, terminal), )
  54. self.conn.commit()
  55. except sqlite.Error:
  56. return error.error_exist_user_id(user_id)
  57. return 200, "ok"
  58. def check_token(self, user_id: str, token: str) -> (int, str):
  59. cursor = self.conn.execute("SELECT token from user where user_id=?", (user_id,))
  60. row = cursor.fetchone()
  61. if row is None:
  62. return error.error_authorization_fail()
  63. db_token = row[0]
  64. if not self.__check_token(user_id, db_token, token):
  65. return error.error_authorization_fail()
  66. return 200, "ok"
  67. def check_password(self, user_id: str, password: str) -> (int, str):
  68. cursor = self.conn.execute("SELECT password from user where user_id=?", (user_id,))
  69. row = cursor.fetchone()
  70. if row is None:
  71. return error.error_authorization_fail()
  72. if password != row[0]:
  73. return error.error_authorization_fail()
  74. return 200, "ok"
  75. def login(self, user_id: str, password: str, terminal: str) -> (int, str, str):
  76. token = ""
  77. try:
  78. code, message = self.check_password(user_id, password)
  79. if code != 200:
  80. return code, message, ""
  81. token = jwt_encode(user_id, terminal)
  82. cursor = self.conn.execute(
  83. "UPDATE user set token= ? , terminal = ? where user_id = ?",
  84. (token, terminal, user_id), )
  85. if cursor.rowcount == 0:
  86. return error.error_authorization_fail() + ("", )
  87. self.conn.commit()
  88. except sqlite.Error as e:
  89. return 528, "{}".format(str(e)), ""
  90. except BaseException as e:
  91. return 530, "{}".format(str(e)), ""
  92. return 200, "ok", token
  93. def logout(self, user_id: str, token: str) -> bool:
  94. try:
  95. code, message = self.check_token(user_id, token)
  96. if code != 200:
  97. return code, message
  98. terminal = "terminal_{}".format(str(time.time()))
  99. dummy_token = jwt_encode(user_id, terminal)
  100. cursor = self.conn.execute(
  101. "UPDATE user SET token = ?, terminal = ? WHERE user_id=?",
  102. (dummy_token, terminal, user_id), )
  103. if cursor.rowcount == 0:
  104. return error.error_authorization_fail()
  105. self.conn.commit()
  106. except sqlite.Error as e:
  107. return 528, "{}".format(str(e))
  108. except BaseException as e:
  109. return 530, "{}".format(str(e))
  110. return 200, "ok"
  111. def unregister(self, user_id: str, password: str) -> (int, str):
  112. try:
  113. code, message = self.check_password(user_id, password)
  114. if code != 200:
  115. return code, message
  116. cursor = self.conn.execute("DELETE from user where user_id=?", (user_id,))
  117. if cursor.rowcount == 1:
  118. self.conn.commit()
  119. else:
  120. return error.error_authorization_fail()
  121. except sqlite.Error as e:
  122. return 528, "{}".format(str(e))
  123. except BaseException as e:
  124. return 530, "{}".format(str(e))
  125. return 200, "ok"
  126. def change_password(self, user_id: str, old_password: str, new_password: str) -> bool:
  127. try:
  128. code, message = self.check_password(user_id, old_password)
  129. if code != 200:
  130. return code, message
  131. terminal = "terminal_{}".format(str(time.time()))
  132. token = jwt_encode(user_id, terminal)
  133. cursor = self.conn.execute(
  134. "UPDATE user set password = ?, token= ? , terminal = ? where user_id = ?",
  135. (new_password, token, terminal, user_id), )
  136. if cursor.rowcount == 0:
  137. return error.error_authorization_fail()
  138. self.conn.commit()
  139. except sqlite.Error as e:
  140. return 528, "{}".format(str(e))
  141. except BaseException as e:
  142. return 530, "{}".format(str(e))
  143. return 200, "ok"