@ -0,0 +1,5 @@ | |||
from model.postgreSQLORM import Base,engine | |||
def createTable(): | |||
# 创建所有继承于Base的类对应的表 | |||
Base.metadata.create_all(engine) |
@ -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 |
@ -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 |
@ -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() |
@ -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" | |||
@ -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 +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 |
@ -0,0 +1,4 @@ | |||
from flask import Blueprint | |||
from flask import request | |||
bp_buyer = Blueprint("buyer",__name__,url_prefix="/buyer") |
@ -0,0 +1,4 @@ | |||
from flask import Blueprint | |||
from flask import request | |||
bp_seller = Blueprint("seller",__name__,url_prefix="/seller") |
@ -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" | |||