Browse Source

完成register注册功能并利用postman进行测试

master
杨舜 1 year ago
parent
commit
87dd0b7260
28 changed files with 578 additions and 11 deletions
  1. BIN
      figure_require/register_test.png
  2. BIN
      modified/be/__pycache__/__init__.cpython-38.pyc
  3. BIN
      modified/be/__pycache__/app.cpython-38.pyc
  4. BIN
      modified/be/__pycache__/serve.cpython-38.pyc
  5. +0
    -0
      modified/be/model/__init__.py
  6. BIN
      modified/be/model/__pycache__/__init__.cpython-38.pyc
  7. BIN
      modified/be/model/__pycache__/creatTB.cpython-38.pyc
  8. BIN
      modified/be/model/__pycache__/db_conn.cpython-38.pyc
  9. BIN
      modified/be/model/__pycache__/error.cpython-38.pyc
  10. BIN
      modified/be/model/__pycache__/postgreSQLORM.cpython-38.pyc
  11. BIN
      modified/be/model/__pycache__/user.cpython-38.pyc
  12. +5
    -0
      modified/be/model/creatTB.py
  13. +35
    -0
      modified/be/model/db_conn.py
  14. +66
    -0
      modified/be/model/error.py
  15. +121
    -0
      modified/be/model/postgreSQLORM.py
  16. +179
    -0
      modified/be/model/user.py
  17. +38
    -2
      modified/be/serve.py
  18. +0
    -0
      modified/be/view/__init__.py
  19. BIN
      modified/be/view/__pycache__/__init__.cpython-38.pyc
  20. BIN
      modified/be/view/__pycache__/auth.cpython-38.pyc
  21. BIN
      modified/be/view/__pycache__/buyer.cpython-38.pyc
  22. BIN
      modified/be/view/__pycache__/seller.cpython-38.pyc
  23. BIN
      modified/be/view/__pycache__/testconn.cpython-38.pyc
  24. +52
    -0
      modified/be/view/auth.py
  25. +4
    -0
      modified/be/view/buyer.py
  26. +4
    -0
      modified/be/view/seller.py
  27. +21
    -0
      modified/be/view/testconn.py
  28. +53
    -9
      report.md

BIN
figure_require/register_test.png View File

Before After
Width: 951  |  Height: 725  |  Size: 68 KiB

BIN
modified/be/__pycache__/__init__.cpython-38.pyc View File


BIN
modified/be/__pycache__/app.cpython-38.pyc View File


BIN
modified/be/__pycache__/serve.cpython-38.pyc View File


+ 0
- 0
modified/be/model/__init__.py View File


BIN
modified/be/model/__pycache__/__init__.cpython-38.pyc View File


BIN
modified/be/model/__pycache__/creatTB.cpython-38.pyc View File


BIN
modified/be/model/__pycache__/db_conn.cpython-38.pyc View File


BIN
modified/be/model/__pycache__/error.cpython-38.pyc View File


BIN
modified/be/model/__pycache__/postgreSQLORM.cpython-38.pyc View File


BIN
modified/be/model/__pycache__/user.cpython-38.pyc View File


+ 5
- 0
modified/be/model/creatTB.py View File

@ -0,0 +1,5 @@
from model.postgreSQLORM import Base,engine
def createTable():
# 创建所有继承于Base的类对应的表
Base.metadata.create_all(engine)

+ 35
- 0
modified/be/model/db_conn.py View File

@ -0,0 +1,35 @@
from model import postgreSQLORM
from model.postgreSQLORM import User, Store_Book, User_Store
class DBConn:
def __init__(self):
self.session = postgreSQLORM.session
return
# self.conn = store.get_db_conn()
def user_id_exist(self, user_id):
row = self.session.query(User).filter(User.user_id==user_id).first()
# cursor = self.conn.execute("SELECT user_id FROM user WHERE user_id = ?;", (user_id,))
# row = cursor.fetchone()
if row is None:
return False
else:
return True
def book_id_exist(self, store_id, book_id):
row = self.session.query(Store_Book).filter(Store_Book.book_id==book_id and Store_Book.store_id==store_id).first()
# cursor = self.conn.execute("SELECT book_id FROM store WHERE store_id = ? AND book_id = ?;", (store_id, book_id))
# row = cursor.fetchone()
if row is None:
return False
else:
return True
def store_id_exist(self, store_id):
row = self.session.query(User_Store).filter(User_Store.fk_store_id==store_id).first()
# cursor = self.conn.execute("SELECT store_id FROM user_store WHERE store_id = ?;", (store_id,))
# row = cursor.fetchone()
if row is None:
return False
else:
return True

+ 66
- 0
modified/be/model/error.py View File

@ -0,0 +1,66 @@
error_code = {
401: "authorization fail.",
511: "non exist user id {}",
512: "exist user id {}",
513: "non exist store id {}",
514: "exist store id {}",
515: "non exist book id {}",
516: "exist book id {}",
517: "stock level low, book id {}",
518: "invalid order id {}",
519: "not sufficient funds, order id {}",
520: "",
521: "",
522: "",
523: "",
524: "",
525: "",
526: "",
527: "",
528: "",
}
def error_non_exist_user_id(user_id):
return 511, error_code[511].format(user_id)
def error_exist_user_id(user_id):
return 512, error_code[512].format(user_id)
def error_non_exist_store_id(store_id):
return 513, error_code[513].format(store_id)
def error_exist_store_id(store_id):
return 514, error_code[514].format(store_id)
def error_non_exist_book_id(book_id):
return 515, error_code[515].format(book_id)
def error_exist_book_id(book_id):
return 516, error_code[516].format(book_id)
def error_stock_level_low(book_id):
return 517, error_code[517].format(book_id)
def error_invalid_order_id(order_id):
return 518, error_code[518].format(order_id)
def error_not_sufficient_funds(order_id):
return 519, error_code[518].format(order_id)
def error_authorization_fail():
return 401, error_code[401]
def error_and_message(code, message):
return code, message

+ 121
- 0
modified/be/model/postgreSQLORM.py View File

@ -0,0 +1,121 @@
from sqlalchemy import create_engine,MetaData
from sqlalchemy import Integer,String,ForeignKey,Column,TEXT
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import PrimaryKeyConstraint,UniqueConstraint
import sqlalchemy
Base=declarative_base()
class con:
def connect():
'''Returns a connection and a metadata object'''
# We connect with the help of the PostgreSQL URL
url = 'postgresql://stu10205501415:Stu10205501415@dase-cdms-2022-pub.pg.rds.aliyuncs.com:5432/stu10205501415'
# The return value of create_engine() is our connection object
con = create_engine(url, client_encoding='utf8')
# We then bind the connection to MetaData()
meta = MetaData(bind=con)
return con, meta
class User(Base):
__tablename__ = 'user'
user_id = Column(TEXT, primary_key=True, comment="主键")
password = Column(TEXT, nullable=False, comment="密码")
balance = Column(Integer, nullable=False, comment="")
token = Column(TEXT, comment="缓存的令牌")
terminal = Column(TEXT, comment="终端代码")
class Store(Base):
__tablename__ = 'store'
store_id = Column(TEXT, primary_key=True,comment="主键")
stock_level = Column(Integer, comment = "货存")
class Store_Book(Base):
__tablename__ = 'store_book'
store_id = Column(TEXT, comment="主键")
book_id = Column(TEXT, comment="主键")
book_info = Column(TEXT, comment="书籍信息")
stock_level = Column(Integer, comment = "货存")
__table_args__ = (
PrimaryKeyConstraint('store_id', 'book_id'),
)
class User_Store(Base):
__tablename__ = 'user_store'
id = Column(Integer, primary_key=True, autoincrement=True, comment="主键")
fk_user_id = Column(
TEXT,
ForeignKey(
"user.user_id",
ondelete="CASCADE",
onupdate="CASCADE",
),
nullable=False,
comment="user外键"
)
fk_store_id = Column(
TEXT,
ForeignKey(
"store.store_id",
ondelete="CASCADE",
onupdate="CASCADE",
),
nullable=False,
comment="store外键"
)
# 多对多关系的中间表必须使用联合唯一约束,防止出现重复数据
__table_args__ = (
UniqueConstraint("fk_user_id", "fk_store_id"),
)
class New_Order(Base):
__tablename__ = 'new_order'
order_id = Column(TEXT, primary_key = True, comment = '订单id')
fk_user_id = Column(
TEXT,
ForeignKey(
"user.user_id",
ondelete="CASCADE",
onupdate="CASCADE",
),
nullable=False,
comment="user外键"
)
fk_store_id = Column(
TEXT,
ForeignKey(
"store.store_id",
ondelete="CASCADE",
onupdate="CASCADE",
),
nullable=False,
comment="store外键"
)
class New_Order_Detail(Base):
__tablename__ = 'new_order_detail'
order_id = Column(TEXT, comment='订单id')
book_id = Column(TEXT, comment='订单书籍')
count = Column(Integer, comment='购买书籍数')
price = Column(Integer, comment='单价')
__table_args__ = (
PrimaryKeyConstraint('order_id','book_id'),
)
engine, meta = con.connect()
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()

+ 179
- 0
modified/be/model/user.py View File

@ -0,0 +1,179 @@
import jwt
import time
import logging
import sqlite3 as sqlite
from model import error
from model import postgreSQLORM
from model.postgreSQLORM import User
from model import db_conn
# encode a json string like:
# {
# "user_id": [user name],
# "terminal": [terminal code],
# "timestamp": [ts]} to a JWT
# }
def jwt_encode(user_id: str, terminal: str) -> str:
encoded = jwt.encode(
{"user_id": user_id, "terminal": terminal, "timestamp": time.time()},
key=user_id,
algorithm="HS256",
)
return encoded.encode("utf-8").decode("utf-8")
# decode a JWT to a json string like:
# {
# "user_id": [user name],
# "terminal": [terminal code],
# "timestamp": [ts]} to a JWT
# }
def jwt_decode(encoded_token, user_id: str) -> str:
decoded = jwt.decode(encoded_token, key=user_id, algorithms="HS256")
return decoded
class User(db_conn.DBConn):
token_lifetime: int = 3600 # 3600 second
def __init__(self):
db_conn.DBConn.__init__(self)
def __check_token(self, user_id, db_token, token) -> bool:
try:
if db_token != token:
return False
jwt_text = jwt_decode(encoded_token=token, user_id=user_id)
ts = jwt_text["timestamp"]
if ts is not None:
now = time.time()
if self.token_lifetime > now - ts >= 0:
return True
except jwt.exceptions.InvalidSignatureError as e:
logging.error(str(e))
return False
def register(self, user_id: str, password: str):
## 判断用户是否注册过了
if self.user_id_exist(user_id=user_id):
return error.error_exist_user_id(user_id)
else:
# try:
terminal = "terminal_{}".format(str(time.time()))
token = jwt_encode(user_id, terminal)
## 为新注册的用户创建对象
new_user = postgreSQLORM.User(user_id=user_id,password=password,balance=0,token=token,terminal=terminal)
self.session.add(new_user)
# self.conn.execute(
# "INSERT into user(user_id, password, balance, token, terminal) "
# "VALUES (?, ?, ?, ?, ?);",
# (user_id, password, 0, token, terminal), )
# self.conn.commit()
# except sqlite.Error:
# return error.error_exist_user_id(user_id)
return 200, "ok"
# def check_token(self, user_id: str, token: str) -> (int, str):
# cursor = self.conn.execute("SELECT token from user where user_id=?", (user_id,))
# row = cursor.fetchone()
# if row is None:
# return error.error_authorization_fail()
# db_token = row[0]
# if not self.__check_token(user_id, db_token, token):
# return error.error_authorization_fail()
# return 200, "ok"
# def check_password(self, user_id: str, password: str) -> (int, str):
# cursor = self.conn.execute("SELECT password from user where user_id=?", (user_id,))
# row = cursor.fetchone()
# if row is None:
# return error.error_authorization_fail()
# if password != row[0]:
# return error.error_authorization_fail()
# return 200, "ok"
# def login(self, user_id: str, password: str, terminal: str) -> (int, str, str):
# token = ""
# try:
# code, message = self.check_password(user_id, password)
# if code != 200:
# return code, message, ""
# token = jwt_encode(user_id, terminal)
# cursor = self.conn.execute(
# "UPDATE user set token= ? , terminal = ? where user_id = ?",
# (token, terminal, user_id), )
# if cursor.rowcount == 0:
# return error.error_authorization_fail() + ("", )
# self.conn.commit()
# except sqlite.Error as e:
# return 528, "{}".format(str(e)), ""
# except BaseException as e:
# return 530, "{}".format(str(e)), ""
# return 200, "ok", token
# def logout(self, user_id: str, token: str) -> bool:
# try:
# code, message = self.check_token(user_id, token)
# if code != 200:
# return code, message
# terminal = "terminal_{}".format(str(time.time()))
# dummy_token = jwt_encode(user_id, terminal)
# cursor = self.conn.execute(
# "UPDATE user SET token = ?, terminal = ? WHERE user_id=?",
# (dummy_token, terminal, user_id), )
# if cursor.rowcount == 0:
# return error.error_authorization_fail()
# self.conn.commit()
# except sqlite.Error as e:
# return 528, "{}".format(str(e))
# except BaseException as e:
# return 530, "{}".format(str(e))
# return 200, "ok"
# def unregister(self, user_id: str, password: str) -> (int, str):
# try:
# code, message = self.check_password(user_id, password)
# if code != 200:
# return code, message
# cursor = self.conn.execute("DELETE from user where user_id=?", (user_id,))
# if cursor.rowcount == 1:
# self.conn.commit()
# else:
# return error.error_authorization_fail()
# except sqlite.Error as e:
# return 528, "{}".format(str(e))
# except BaseException as e:
# return 530, "{}".format(str(e))
# return 200, "ok"
# def change_password(self, user_id: str, old_password: str, new_password: str) -> bool:
# try:
# code, message = self.check_password(user_id, old_password)
# if code != 200:
# return code, message
# terminal = "terminal_{}".format(str(time.time()))
# token = jwt_encode(user_id, terminal)
# cursor = self.conn.execute(
# "UPDATE user set password = ?, token= ? , terminal = ? where user_id = ?",
# (new_password, token, terminal, user_id), )
# if cursor.rowcount == 0:
# return error.error_authorization_fail()
# self.conn.commit()
# except sqlite.Error as e:
# return 528, "{}".format(str(e))
# except BaseException as e:
# return 530, "{}".format(str(e))
# return 200, "ok"

+ 38
- 2
modified/be/serve.py View File

@ -1,12 +1,48 @@
import logging
import os
from flask import Flask
from flask import Blueprint
from flask import request
import testconn
from creatTB import createTable
from view import testconn
from view import auth
from view import seller
from view import buyer
from model.creatTB import createTable
bp_shutdown = Blueprint("shutdown", __name__)
def shutdown_server():
func = request.environ.get("werkzeug.server.shutdown")
if func is None:
raise RuntimeError("Not running with the Werkzeug Server")
func()
@bp_shutdown.route("/shutdown")
def be_shutdown():
shutdown_server()
return "Server shutting down..."
def be_run():
this_path = os.path.dirname(__file__)
parent_path = os.path.dirname(this_path)
log_file = os.path.join(parent_path, "app.log")
logging.basicConfig(filename=log_file, level=logging.ERROR)
handler = logging.StreamHandler()
formatter = logging.Formatter(
"%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s"
)
handler.setFormatter(formatter)
logging.getLogger().addHandler(handler)
app = Flask(__name__)
createTable()
app.register_blueprint(testconn.bp_testconn)
app.register_blueprint(auth.bp_auth)
app.register_blueprint(seller.bp_seller)
app.register_blueprint(buyer.bp_buyer)
app.run(port=5000)

+ 0
- 0
modified/be/view/__init__.py View File


BIN
modified/be/view/__pycache__/__init__.cpython-38.pyc View File


BIN
modified/be/view/__pycache__/auth.cpython-38.pyc View File


BIN
modified/be/view/__pycache__/buyer.cpython-38.pyc View File


BIN
modified/be/view/__pycache__/seller.cpython-38.pyc View File


BIN
modified/be/view/__pycache__/testconn.cpython-38.pyc View File


+ 52
- 0
modified/be/view/auth.py View File

@ -0,0 +1,52 @@
from flask import Blueprint
from flask import request
from flask import jsonify
from model import user
bp_auth = Blueprint("auth",__name__,url_prefix="/auth")
@bp_auth.route("/login", methods=["POST"])
def login():
user_id = request.json.get("user_id", "")
password = request.json.get("password", "")
terminal = request.json.get("terminal", "")
u = user.User()
code, message, token = u.login(user_id=user_id, password=password, terminal=terminal)
return jsonify({"message": message, "token": token}), code
@bp_auth.route("/logout", methods=["POST"])
def logout():
user_id: str = request.json.get("user_id")
token: str = request.headers.get("token")
u = user.User()
code, message = u.logout(user_id=user_id, token=token)
return jsonify({"message": message}), code
@bp_auth.route("/register", methods=["POST"])
def register():
user_id = request.json.get("user_id", "")
password = request.json.get("password", "")
u = user.User()
code, message = u.register(user_id=user_id, password=password)
return jsonify({"message": message}), code
@bp_auth.route("/unregister", methods=["POST"])
def unregister():
user_id = request.json.get("user_id", "")
password = request.json.get("password", "")
u = user.User()
code, message = u.unregister(user_id=user_id, password=password)
return jsonify({"message": message}), code
@bp_auth.route("/password", methods=["POST"])
def change_password():
user_id = request.json.get("user_id", "")
old_password = request.json.get("oldPassword", "")
new_password = request.json.get("newPassword", "")
u = user.User()
code, message = u.change_password(user_id=user_id, old_password=old_password, new_password=new_password)
return jsonify({"message": message}), code

+ 4
- 0
modified/be/view/buyer.py View File

@ -0,0 +1,4 @@
from flask import Blueprint
from flask import request
bp_buyer = Blueprint("buyer",__name__,url_prefix="/buyer")

+ 4
- 0
modified/be/view/seller.py View File

@ -0,0 +1,4 @@
from flask import Blueprint
from flask import request
bp_seller = Blueprint("seller",__name__,url_prefix="/seller")

+ 21
- 0
modified/be/view/testconn.py View File

@ -0,0 +1,21 @@
from flask import Blueprint
from flask import Flask, abort, request, jsonify
import json
from flask import jsonify
from model import postgreSQLORM
from model.postgreSQLORM import User,Store,Store_Book,User_Store,New_Order,New_Order_Detail
bp_testconn = Blueprint("testconn",__name__,url_prefix="/testconn")
@bp_testconn.route("/test",methods=['GET'])
def test():
user_id: str = request.args.get("user_id")
print(user_id)
try:
ss = postgreSQLORM.session.query(User).filter(User.user_id==user_id).all()
for i in ss:
print('user_id',i.user_id)
except:
print("error")
return "connect success"

+ 53
- 9
report.md View File

@ -160,7 +160,7 @@
DBSession = sessionmaker(bind=engine)
session = DBSession()
```
2. 在上述创建的table中添加初始数据并利用该数据测试后端服务器与数据库的连接
2. 在上述创建的table中添加初始数据并利用该数据测试后端服务器与数据库的连接(2022.11.29 15:10 杨舜)
![avatar](./figure_require/add_naive_userdata.png)
![avatar](./figure_require/conn_test.png)
@ -172,18 +172,16 @@
```
4. 在/be/model目录下创建User类用书实现User对于数据库的一些交互功能
5. 修改[model/db_conn.py](./be/model/db_conn.py)中查询的操作为orm操作
5. 修改[model/db_conn.py](./be/model/db_conn.py)中查询的操作为orm操作,其中修改DBConn中的连接conn为sqlachlemy中的session,将会话作为连接
```python
from model import postgreSQLORM
from model.postgreSQLORM import User, Store_Book, User_Store
class DBConn:
def __init__(self):
self.session = postgreSQLORM.session
return
# self.conn = store.get_db_conn()
def user_id_exist(self, user_id):
row = postgreSQLORM.session.query(User).filter(User.user_id==user_id).one()
row = self.session.query(User).filter(User.user_id==user_id).first()
# cursor = self.conn.execute("SELECT user_id FROM user WHERE user_id = ?;", (user_id,))
# row = cursor.fetchone()
if row is None:
@ -192,7 +190,7 @@
return True
def book_id_exist(self, store_id, book_id):
row = postgreSQLORM.session.query(Store_Book).filter(Store_Book.book_id==book_id and Store_Book.store_id==store_id).one()
row = self.session.query(Store_Book).filter(Store_Book.book_id==book_id and Store_Book.store_id==store_id).first()
# cursor = self.conn.execute("SELECT book_id FROM store WHERE store_id = ? AND book_id = ?;", (store_id, book_id))
# row = cursor.fetchone()
if row is None:
@ -201,7 +199,7 @@
return True
def store_id_exist(self, store_id):
row = postgreSQLORM.session.query(User_Store).filter(User_Store.fk_store_id==store_id).one()
row = self.session.query(User_Store).filter(User_Store.fk_store_id==store_id).first()
# cursor = self.conn.execute("SELECT store_id FROM user_store WHERE store_id = ?;", (store_id,))
# row = cursor.fetchone()
if row is None:
@ -209,5 +207,51 @@
else:
return True
```
6.
6. 修改/be/model/user.py中User类以及其中函数的定义使其满足题目要求的ORM模型,同时仅对注册功能进行测试(2022.11.30 15:40 杨舜)
```python
class User(db_conn.DBConn):
token_lifetime: int = 3600 # 3600 second
def __init__(self):
db_conn.DBConn.__init__(self)
def __check_token(self, user_id, db_token, token) -> bool:
try:
if db_token != token:
return False
jwt_text = jwt_decode(encoded_token=token, user_id=user_id)
ts = jwt_text["timestamp"]
if ts is not None:
now = time.time()
if self.token_lifetime > now - ts >= 0:
return True
except jwt.exceptions.InvalidSignatureError as e:
logging.error(str(e))
return False
def register(self, user_id: str, password: str):
## 判断用户是否注册过了
if self.user_id_exist(user_id=user_id):
return error.error_exist_user_id(user_id)
else:
# try:
terminal = "terminal_{}".format(str(time.time()))
token = jwt_encode(user_id, terminal)
## 为新注册的用户创建对象
new_user = postgreSQLORM.User(user_id=user_id,password=password,balance=0,token=token,terminal=terminal)
self.session.add(new_user)
# self.conn.execute(
# "INSERT into user(user_id, password, balance, token, terminal) "
# "VALUES (?, ?, ?, ?, ?);",
# (user_id, password, 0, token, terminal), )
# self.conn.commit()
# except sqlite.Error:
# return error.error_exist_user_id(user_id)
return 200, "ok"
```
![avatar](./figure_require/register_test.png)
7.

Loading…
Cancel
Save