当代数据库管理系统课程实验二
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

  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.encode("utf-8").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"