Changed database model

This commit is contained in:
Administrator 2022-03-27 17:23:33 +02:00
parent 2ba8a9bd13
commit 12d59d69ff
10 changed files with 160 additions and 130 deletions

View File

@ -3,7 +3,7 @@ import os
from apiflask import APIBlueprint, abort from apiflask import APIBlueprint, abort
from db import db from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response from helper_functions import make_response, get_email_or_abort_401
from auth import auth from auth import auth
from schema import KeywordResponseSchema, KeywordSchema, DeleteSuccessfulSchema from schema import KeywordResponseSchema, KeywordSchema, DeleteSuccessfulSchema
from models import Keyword from models import Keyword
@ -18,17 +18,17 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@keyword_blueprint.auth_required(auth) @keyword_blueprint.auth_required(auth)
@keyword_blueprint.doc(summary="Add new keyword", description="Adds new keyword for current user") @keyword_blueprint.doc(summary="Add new keyword", description="Adds new keyword for current user")
def add_keyword(data): def add_keyword(data):
username = get_username_or_abort_401() email = get_email_or_abort_401()
check_if_keyword_data_exists(data) check_if_keyword_data_exists(data)
key = data['keyword'] key = data['keyword']
check_keyword = db.session.query(Keyword).filter_by(keyword=key, user_id=get_user_id_from_username(username)).first() check_keyword = db.session.query(Keyword).filter_by(keyword=key, email=email).first()
if check_keyword is None: if check_keyword is None:
# Keyword doesn't exist yet for this user # Keyword doesn't exist yet for this user
new_keyword = Keyword( new_keyword = Keyword(
user_id=get_user_id_from_username(username), email=email,
keyword=key keyword=key
) )
db.session.add(new_keyword) db.session.add(new_keyword)
@ -45,13 +45,18 @@ def add_keyword(data):
@keyword_blueprint.auth_required(auth) @keyword_blueprint.auth_required(auth)
@keyword_blueprint.doc(summary="Removes existing keyword", description="Removes existing keyword for current user") @keyword_blueprint.doc(summary="Removes existing keyword", description="Removes existing keyword for current user")
def remove_keyword(data): def remove_keyword(data):
username = get_username_or_abort_401() email = get_email_or_abort_401()
check_if_keyword_data_exists(data) check_if_keyword_data_exists(data)
key = data['keyword'] key = data['keyword']
db.session.query(Keyword).filter_by(keyword=key, user_id=get_user_id_from_username(username)).delete() check_keyword = db.session.query(Keyword).filter_by(keyword=key, email=email).first()
if check_keyword is None:
return make_response({}, 500, "Keyword doesn't exist for this user")
else:
db.session.query(Keyword).filter_by(keyword=key, email=email).delete()
db.session.commit() db.session.commit()
return make_response({}, 200, "Successfully removed keyword") return make_response({}, 200, "Successfully removed keyword")
@ -62,10 +67,10 @@ def remove_keyword(data):
@keyword_blueprint.auth_required(auth) @keyword_blueprint.auth_required(auth)
@keyword_blueprint.doc(summary="Returns all keywords", description="Returns all keywords for current user") @keyword_blueprint.doc(summary="Returns all keywords", description="Returns all keywords for current user")
def get_keywords(): def get_keywords():
username = get_username_or_abort_401() email = get_email_or_abort_401()
return_keywords = [] return_keywords = []
keywords = db.session.query(Keyword).filter_by(user_id=get_user_id_from_username(username)).all() keywords = db.session.query(Keyword).filter_by(email=email).all()
if keywords is not None: if keywords is not None:
for row in keywords: for row in keywords:

View File

@ -2,9 +2,9 @@ import os
from apiflask import APIBlueprint from apiflask import APIBlueprint
from api.schema import PortfolioResponseSchema
from db import db from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response from helper_functions import make_response, get_email_or_abort_401
from models import Transaction
from auth import auth from auth import auth
portfolio_blueprint = APIBlueprint('portfolio', __name__, url_prefix='/api') portfolio_blueprint = APIBlueprint('portfolio', __name__, url_prefix='/api')
@ -12,21 +12,22 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@portfolio_blueprint.route('/portfolio', methods=['GET']) @portfolio_blueprint.route('/portfolio', methods=['GET'])
@portfolio_blueprint.output(200) @portfolio_blueprint.output(PortfolioResponseSchema(many=True), 200)
@portfolio_blueprint.auth_required(auth) @portfolio_blueprint.auth_required(auth)
@portfolio_blueprint.doc(summary="Returns portfolio", description="Returns all shares of current user") @portfolio_blueprint.doc(summary="Returns portfolio", description="Returns all shares of current user")
def get_portfolio(): def get_portfolio():
username = get_username_or_abort_401() email = get_email_or_abort_401()
return_portfolio = {} return_portfolio = []
transactions = db.session.query(Transaction).filter_by(user_id=get_user_id_from_username(username)).all() transactions = db.session.execute("SELECT symbol, SUM(count), SUM(price), MAX(time) FROM `transactions` WHERE email = '" + email + "' GROUP BY symbol;").all()
if transactions is not None: if transactions is not None:
for row in transactions: for row in transactions:
if row.symbol in return_portfolio: return_portfolio.append({
return_portfolio[row.symbol]['count'] += row.count "symbol": row[0],
return_portfolio[row.symbol]['last_transaction'] = row.time "count": row[1],
else: # "price": row[2],
return_portfolio[row.symbol] = {"count": row.count, "last_transaction": row.time} "last_transaction": row[3]
})
return make_response(return_portfolio, 200, "Successfully loaded symbols") return make_response(return_portfolio, 200, "Successfully loaded symbols")

View File

@ -4,7 +4,7 @@ from apiflask import APIBlueprint, abort
from auth import auth from auth import auth
from db import db from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response from helper_functions import make_response, get_email_or_abort_401
from models import Share from models import Share
from schema import SymbolSchema, SymbolResponseSchema, DeleteSuccessfulSchema from schema import SymbolSchema, SymbolResponseSchema, DeleteSuccessfulSchema
@ -18,17 +18,17 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@shares_blueprint.auth_required(auth) @shares_blueprint.auth_required(auth)
@shares_blueprint.doc(summary="Add new symbol", description="Adds new symbol for current user") @shares_blueprint.doc(summary="Add new symbol", description="Adds new symbol for current user")
def add_symbol(data): def add_symbol(data):
username = get_username_or_abort_401() email = get_email_or_abort_401()
check_if_symbol_data_exists(data) check_if_symbol_data_exists(data)
symbol = data['symbol'] symbol = data['symbol']
check_share = db.session.query(Share).filter_by(symbol=symbol, user_id=get_user_id_from_username(username)).first() check_share = db.session.query(Share).filter_by(symbol=symbol, email=email).first()
if check_share is None: if check_share is None:
# Keyword doesn't exist yet for this user # Keyword doesn't exist yet for this user
new_symbol = Share( new_symbol = Share(
user_id=get_user_id_from_username(username), email=email,
symbol=symbol symbol=symbol
) )
db.session.add(new_symbol) db.session.add(new_symbol)
@ -45,13 +45,18 @@ def add_symbol(data):
@shares_blueprint.auth_required(auth) @shares_blueprint.auth_required(auth)
@shares_blueprint.doc(summary="Removes existing symbol", description="Removes existing symbol for current user") @shares_blueprint.doc(summary="Removes existing symbol", description="Removes existing symbol for current user")
def remove_symbol(data): def remove_symbol(data):
username = get_username_or_abort_401() email = get_email_or_abort_401()
check_if_symbol_data_exists(data) check_if_symbol_data_exists(data)
symbol = data['symbol'] symbol = data['symbol']
db.session.query(Share).filter_by(symbol=symbol, user_id=get_user_id_from_username(username)).delete() check_share = db.session.query(Share).filter_by(symbol=symbol, email=email).first()
if check_share is None:
return make_response({}, 500, "Symbol doesn't exist for this user")
else:
db.session.query(Share).filter_by(symbol=symbol, email=email).delete()
db.session.commit() db.session.commit()
return make_response({}, 200, "Successfully removed symbol") return make_response({}, 200, "Successfully removed symbol")
@ -62,10 +67,10 @@ def remove_symbol(data):
@shares_blueprint.auth_required(auth) @shares_blueprint.auth_required(auth)
@shares_blueprint.doc(summary="Returns all symbols", description="Returns all symbols for current user") @shares_blueprint.doc(summary="Returns all symbols", description="Returns all symbols for current user")
def get_symbol(): def get_symbol():
username = get_username_or_abort_401() email = get_email_or_abort_401()
return_symbols = [] return_symbols = []
symbols = db.session.query(Share).filter_by(user_id=get_user_id_from_username(username)).all() symbols = db.session.query(Share).filter_by(email=email).all()
if symbols is not None: if symbols is not None:
for row in symbols: for row in symbols:

View File

@ -4,9 +4,9 @@ import datetime
from apiflask import abort, APIBlueprint from apiflask import abort, APIBlueprint
from db import db from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response from helper_functions import make_response, get_email_or_abort_401
from models import Transaction from models import Transaction
from schema import TransactionSchema from schema import TransactionSchema, TransactionResponseSchema
from auth import auth from auth import auth
transaction_blueprint = APIBlueprint('transaction', __name__, url_prefix='/api') transaction_blueprint = APIBlueprint('transaction', __name__, url_prefix='/api')
@ -14,17 +14,17 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@transaction_blueprint.route('/transaction', methods=['POST']) @transaction_blueprint.route('/transaction', methods=['POST'])
@transaction_blueprint.output((), 200) @transaction_blueprint.output(TransactionResponseSchema(), 200)
@transaction_blueprint.input(schema=TransactionSchema) @transaction_blueprint.input(schema=TransactionSchema)
@transaction_blueprint.auth_required(auth) @transaction_blueprint.auth_required(auth)
@transaction_blueprint.doc(summary="Adds new transaction", description="Adds new transaction for current user") @transaction_blueprint.doc(summary="Adds new transaction", description="Adds new transaction for current user")
def add_transaction(data): def add_transaction(data):
username = get_username_or_abort_401() email = get_email_or_abort_401()
check_if_transaction_data_exists(data) check_if_transaction_data_exists(data)
new_transaction = Transaction( new_transaction = Transaction(
user_id=get_user_id_from_username(username), email=email,
symbol=data['symbol'], symbol=data['symbol'],
time=datetime.datetime.strptime(data['time'], '%Y-%m-%dT%H:%M:%S.%fZ'), time=datetime.datetime.strptime(data['time'], '%Y-%m-%dT%H:%M:%S.%fZ'),
count=data['count'], count=data['count'],
@ -41,10 +41,10 @@ def add_transaction(data):
@transaction_blueprint.auth_required(auth) @transaction_blueprint.auth_required(auth)
@transaction_blueprint.doc(summary="Returns all transactions", description="Returns all transactions for current user") @transaction_blueprint.doc(summary="Returns all transactions", description="Returns all transactions for current user")
def get_transaction(): def get_transaction():
username = get_username_or_abort_401() email = get_email_or_abort_401()
return_transactions = [] return_transactions = []
transactions = db.session.query(Transaction).filter_by(user_id=get_user_id_from_username(username)).all() transactions = db.session.query(Transaction).filter_by(email=email).all()
if transactions is not None: if transactions is not None:
for row in transactions: for row in transactions:

View File

@ -5,9 +5,9 @@ import jwt
from apiflask import APIBlueprint, abort from apiflask import APIBlueprint, abort
from db import db from db import db
from helper_functions import check_password, hash_password, get_username_or_abort_401, abort_if_no_admin, make_response from helper_functions import check_password, hash_password, abort_if_no_admin, make_response, get_email_or_abort_401
from models import User from models import User
from schema import UsersSchema, TokenSchema, LoginDataSchema, AdminDataSchema, DeleteUserSchema from schema import UsersSchema, TokenSchema, LoginDataSchema, AdminDataSchema, DeleteUserSchema, RegisterDataSchema, UpdateUserDataSchema
from auth import auth from auth import auth
users_blueprint = APIBlueprint('users', __name__, url_prefix='/api') users_blueprint = APIBlueprint('users', __name__, url_prefix='/api')
@ -33,9 +33,9 @@ def users():
@users_blueprint.auth_required(auth) @users_blueprint.auth_required(auth)
@users_blueprint.doc(summary="Get current user", description="Returns current user") @users_blueprint.doc(summary="Get current user", description="Returns current user")
def user(): def user():
username = get_username_or_abort_401() email = get_email_or_abort_401()
res = db.session.query(User).filter_by(username=username).first().as_dict() res = db.session.query(User).filter_by(email=email).first().as_dict()
return make_response(res, 200, "Successfully received current user data") return make_response(res, 200, "Successfully received current user data")
@ -45,40 +45,45 @@ def user():
@users_blueprint.input(schema=LoginDataSchema) @users_blueprint.input(schema=LoginDataSchema)
@users_blueprint.doc(summary="Login", description="Returns jwt token if username and password match, otherwise returns error") @users_blueprint.doc(summary="Login", description="Returns jwt token if username and password match, otherwise returns error")
def login(data): def login(data):
check_if_user_data_exists(data) check_if_email_data_exists(data)
check_if_password_data_exists(data)
username = data['username'] email = data['email']
password = data['password'] password = data['password']
query_user = db.session.query(User).filter_by(username=username).first() query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist if query_user is None: # email doesn't exist
abort(500, message="Unable to login") abort(500, message="Unable to login")
if not check_password(query_user.password, password): # Password incorrect if not check_password(query_user.password, password): # Password incorrect
abort(500, message="Unable to login") abort(500, message="Unable to login")
token = jwt.encode({'username': query_user.username, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=45)}, os.getenv('SECRET_KEY'), "HS256") token = jwt.encode({'email': query_user.email, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=45)}, os.getenv('SECRET_KEY'), "HS256")
return make_response({"token": token}, 200, "Successfully logged in") return make_response({"token": token}, 200, "Successfully logged in")
@users_blueprint.route('/user/register', methods=['POST']) @users_blueprint.route('/user/register', methods=['POST'])
@users_blueprint.output(UsersSchema(), 200) @users_blueprint.output(UsersSchema(), 200)
@users_blueprint.input(schema=LoginDataSchema) @users_blueprint.input(schema=RegisterDataSchema)
@users_blueprint.doc(summary="Register", description="Registers user") @users_blueprint.doc(summary="Register", description="Registers user")
def register(data): def register(data):
check_if_user_data_exists(data) check_if_email_data_exists(data)
check_if_username_data_exists(data)
check_if_password_data_exists(data)
email = data['email']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
query_user = db.session.query(User).filter_by(username=username).first() query_user = db.session.query(User).filter_by(email=email).first()
if query_user is not None: # Username already exist if query_user is not None: # Username already exist
abort(500, message="Username already exist") abort(500, message="Email already exist")
new_user = User( new_user = User(
email=email,
username=username, username=username,
password=hash_password(password), password=hash_password(password),
admin=False admin=False
@ -91,26 +96,21 @@ def register(data):
@users_blueprint.route('/user', methods=['PUT']) @users_blueprint.route('/user', methods=['PUT'])
@users_blueprint.output({}, 200) @users_blueprint.output({}, 200)
@users_blueprint.input(schema=LoginDataSchema) @users_blueprint.input(schema=UpdateUserDataSchema)
@users_blueprint.auth_required(auth) @users_blueprint.auth_required(auth)
@users_blueprint.doc(summary="Update user", description="Changes password and/or username of current user") @users_blueprint.doc(summary="Update user", description="Changes password and/or username of current user")
def update_user(data): def update_user(data):
username = get_username_or_abort_401() email = get_email_or_abort_401()
check_if_user_data_exists(data) query_user = db.session.query(User).filter_by(email=email).first()
new_username = data['username']
new_password = data['password']
query_user = db.session.query(User).filter_by(username=username).first()
if query_user is None: # Username doesn't exist if query_user is None: # Username doesn't exist
abort(500, message="Unable to login") abort(500, message="Unable to login")
if new_password is not None: if "password" in data and data['password'] is not None:
query_user.password = hash_password(new_password) query_user.password = hash_password(data['password'])
if new_username is not None: if "username" in data and data['username'] is not None:
query_user.username = new_username query_user.username = data['username']
db.session.commit() db.session.commit()
@ -125,12 +125,13 @@ def update_user(data):
def set_admin(data): def set_admin(data):
abort_if_no_admin() # Only admin users can do this abort_if_no_admin() # Only admin users can do this
check_if_email_data_exists(data)
check_if_admin_data_exists(data) check_if_admin_data_exists(data)
username = data['username'] email = data['email']
admin = data['admin'] admin = data['admin']
query_user = db.session.query(User).filter_by(username=username).first() query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist if query_user is None: # Username doesn't exist
abort(500, message="Unable to login") abort(500, message="Unable to login")
@ -147,29 +148,31 @@ def set_admin(data):
@users_blueprint.auth_required(auth) @users_blueprint.auth_required(auth)
@users_blueprint.doc(summary="Delete user", description="Deletes user by username") @users_blueprint.doc(summary="Delete user", description="Deletes user by username")
def delete_user(data): def delete_user(data):
check_if_delete_data_exists(data) check_if_email_data_exists(data)
username = data['username'] email = data['email']
if username == get_username_or_abort_401(): # Username is same as current user if email == get_email_or_abort_401(): # Username is same as current user
db.session.query(User).filter_by(username=username).delete() db.session.query(User).filter_by(email=email).delete()
db.session.commit() db.session.commit()
else: # Delete different user than my user -> only admin users else: # Delete different user than my user -> only admin users
abort_if_no_admin() abort_if_no_admin()
db.session.query(User).filter_by(username=username).delete() db.session.query(User).filter_by(email=email).delete()
db.session.commit() db.session.commit()
return make_response({}, 200, "Successfully removed user") return make_response({}, 200, "Successfully removed user")
def check_if_user_data_exists(data): def check_if_email_data_exists(data):
if "username" not in data: if "email" not in data:
abort(400, message="Username missing") abort(400, message="Email missing")
if data['username'] == "" or data['username'] is None: if data['email'] == "" or data['email'] is None:
abort(400, message="Username missing") abort(400, message="Email missing")
def check_if_password_data_exists(data):
if "password" not in data: if "password" not in data:
abort(400, message="Password missing") abort(400, message="Password missing")
@ -177,23 +180,17 @@ def check_if_user_data_exists(data):
abort(400, message="Password missing") abort(400, message="Password missing")
def check_if_admin_data_exists(data): def check_if_username_data_exists(data):
if "username" not in data: if "username" not in data:
abort(400, message="Username missing") abort(400, message="Username missing")
if data['username'] == "" or data['username'] is None: if data['username'] == "" or data['username'] is None:
abort(400, message="Username missing") abort(400, message="Username missing")
def check_if_admin_data_exists(data):
if "admin" not in data: if "admin" not in data:
abort(400, message="Admin state missing") abort(400, message="Admin state missing")
if data['admin'] == "" or data['admin'] is None: if data['admin'] == "" or data['admin'] is None:
abort(400, message="Admin state missing") abort(400, message="Admin state missing")
def check_if_delete_data_exists(data):
if "username" not in data:
abort(400, message="Username missing")
if data['username'] == "" or data['username'] is None:
abort(400, message="Username missing")

View File

@ -7,11 +7,7 @@ from flask_cors import CORS
from api.helper_functions import hash_password from api.helper_functions import hash_password
from models import * from models import *
from api_blueprint_keyword import keyword_blueprint
from api_blueprint_shares import shares_blueprint
from api_blueprint_user import users_blueprint from api_blueprint_user import users_blueprint
from api_blueprint_transactions import transaction_blueprint
from api_blueprint_portfolio import portfolio_blueprint
def create_app(): def create_app():
@ -38,20 +34,22 @@ def create_app():
def init_database(): def init_database():
db.create_all() db.create_all()
if os.getenv("BOT_USER") is not None and os.getenv("BOT_PASSWORD") is not None: if os.getenv("BOT_EMAIL") is not None and os.getenv("BOT_USERNAME") is not None and os.getenv("BOT_PASSWORD") is not None:
if db.session.query(User).filter_by(username=os.getenv("BOT_USER")).first() is None: # Check if user already exist if db.session.query(User).filter_by(email=os.getenv("BOT_EMAIL")).first() is None: # Check if user already exist
bot = User( bot = User(
username=os.getenv("BOT_USER"), email=os.getenv("BOT_EMAIL"),
username=os.getenv("BOT_USERNAME"),
password=hash_password(os.getenv("BOT_PASSWORD")), password=hash_password(os.getenv("BOT_PASSWORD")),
admin=False admin=False
) )
db.session.add(bot) db.session.add(bot)
db.session.commit() db.session.commit()
if os.getenv("ADMIN_USER") is not None and os.getenv("ADMIN_PASSWORD") is not None: if os.getenv("ADMIN_EMAIL") is not None and os.getenv("ADMIN_USERNAME") is not None and os.getenv("ADMIN_PASSWORD") is not None:
if db.session.query(User).filter_by(username=os.getenv("ADMIN_USER")).first() is None: # Check if user already exist if db.session.query(User).filter_by(email=os.getenv("ADMIN_EMAIL")).first() is None: # Check if user already exist
admin = User( admin = User(
username=os.getenv("ADMIN_USER"), email=os.getenv("ADMIN_EMAIL"),
username=os.getenv("ADMIN_USERNAME"),
password=hash_password(os.getenv("ADMIN_PASSWORD")), password=hash_password(os.getenv("ADMIN_PASSWORD")),
admin=True admin=True
) )

View File

@ -17,5 +17,5 @@ def verify_token(token):
try: try:
jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"]) jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])
return True return True
except jwt.exceptions.DecodeError: except:
return False return False

View File

@ -32,53 +32,46 @@ def extract_token_data(token):
if token is not None: if token is not None:
try: try:
return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"]) return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])
except jwt.exceptions.DecodeError: except:
return None return None
else: else:
return None return None
def get_username_from_token_data(): def get_email_from_token_data():
if 'Authorization' in request.headers: if 'Authorization' in request.headers:
token = request.headers['Authorization'].split(" ")[1] token = request.headers['Authorization'].split(" ")[1]
if token is not None: if token is not None:
if ':' in token: # Maybe bot token, check if token valid and return username after ":" then if ':' in token: # Maybe bot token, check if token valid and return username after ":" then
username = token.split(":")[1] email = token.split(":")[1]
token = token.split(":")[0] token = token.split(":")[0]
try: try:
if jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['username'] == "bot": if jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['email'] == os.getenv("BOT_USER"):
return username return email
else: else:
return None return None
except jwt.exceptions.DecodeError: except:
return None return None
else: # "Normal" token, extract username from token else: # "Normal" token, extract username from token
try: try:
return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['username'] return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['email']
except jwt.exceptions.DecodeError: except:
return None return None
return None return None
def get_user_id_from_username(username): def get_email_or_abort_401():
if username is not None:
return db.session.query(User).filter_by(username=username).first().user_id
else:
return None
def get_username_or_abort_401():
# get username from jwt token # get username from jwt token
username = get_username_from_token_data() email = get_email_from_token_data()
if username is None: # If token not provided or invalid -> return 401 code if email is None: # If token not provided or invalid -> return 401 code
abort(401, message="Unable to login") abort(401, message="Unable to login")
return username return email
def abort_if_no_admin(): def abort_if_no_admin():
@ -87,10 +80,10 @@ def abort_if_no_admin():
def is_user_admin(): def is_user_admin():
username = get_username_or_abort_401() email = get_email_or_abort_401()
return db.session.query(User).filter_by(username=username).first().admin return db.session.query(User).filter_by(email=email).first().admin
def make_response(data, status=200, text=""): def make_response(data, status=200, text=""):
return jsonify({"status": status, "text": text, "data": {"token": data}}) return jsonify({"status": status, "text": text, "data": data})

View File

@ -3,10 +3,10 @@ from db import db
class User(db.Model): class User(db.Model):
__tablename__ = 'users' __tablename__ = 'users'
username = db.Column('username', db.String(255), nullable=False, unique=True) email = db.Column('email', db.String(255), primary_key=True, nullable=False, unique=True)
password = db.Column('password', db.String(255), nullable=False, server_default='') password = db.Column('password', db.String(255), nullable=False, server_default='')
user_id = db.Column('user_id', db.Integer(), primary_key=True) username = db.Column('username', db.String(255), nullable=False, server_default='')
telegram_name = db.Column('telegram_name', db.String(255), nullable=True, server_default='') telegram_user_id = db.Column('telegram_user_id', db.String(255), nullable=True, server_default='')
admin = db.Column('admin', db.Boolean(), server_default='0') admin = db.Column('admin', db.Boolean(), server_default='0')
def as_dict(self): def as_dict(self):
@ -16,7 +16,7 @@ class User(db.Model):
class Transaction(db.Model): class Transaction(db.Model):
__tablename__ = 'transactions' __tablename__ = 'transactions'
t_id = db.Column('t_id', db.Integer(), nullable=False, unique=True, primary_key=True) t_id = db.Column('t_id', db.Integer(), nullable=False, unique=True, primary_key=True)
user_id = db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE')) email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE'))
symbol = db.Column('symbol', db.String(255)) symbol = db.Column('symbol', db.String(255))
time = db.Column('time', db.DateTime()) time = db.Column('time', db.DateTime())
count = db.Column('count', db.Integer()) count = db.Column('count', db.Integer())
@ -29,7 +29,7 @@ class Transaction(db.Model):
class Keyword(db.Model): class Keyword(db.Model):
__tablename__ = 'keywords' __tablename__ = 'keywords'
s_id = db.Column('s_id', db.Integer(), nullable=False, unique=True, primary_key=True) s_id = db.Column('s_id', db.Integer(), nullable=False, unique=True, primary_key=True)
user_id = db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE')) email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE'))
keyword = db.Column('keyword', db.String(255)) keyword = db.Column('keyword', db.String(255))
def as_dict(self): def as_dict(self):
@ -39,7 +39,7 @@ class Keyword(db.Model):
class Share(db.Model): class Share(db.Model):
__tablename__ = 'shares' __tablename__ = 'shares'
a_id = db.Column('a_id', db.Integer(), nullable=False, unique=True, primary_key=True) a_id = db.Column('a_id', db.Integer(), nullable=False, unique=True, primary_key=True)
user_id = db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE')) email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE'))
symbol = db.Column('symbol', db.String(255)) symbol = db.Column('symbol', db.String(255))
def as_dict(self): def as_dict(self):

View File

@ -1,5 +1,7 @@
from apiflask import Schema from apiflask import Schema
from apiflask.fields import Integer, String, Boolean, Field, Float from apiflask.fields import Integer, String, Boolean, Field, Float
from marshmallow import validate
from marshmallow.fields import Email
class BaseResponseSchema(Schema): class BaseResponseSchema(Schema):
@ -11,13 +13,13 @@ class BaseResponseSchema(Schema):
class UsersSchema(Schema): class UsersSchema(Schema):
admin = Boolean() admin = Boolean()
password = String() password = String()
telegram_name = String()
user_id = Integer()
username = String() username = String()
telegram_user_id = String()
email = Email()
class AdminDataSchema(Schema): class AdminDataSchema(Schema):
username = String() email = Email()
admin = Boolean() admin = Boolean()
@ -26,12 +28,23 @@ class TokenSchema(Schema):
class LoginDataSchema(Schema): class LoginDataSchema(Schema):
email = Email()
password = String()
class RegisterDataSchema(Schema):
email = Email()
username = String() username = String()
password = String() password = String()
class UpdateUserDataSchema(Schema):
username = String(required=False)
password = String(required=False)
class DeleteUserSchema(Schema): class DeleteUserSchema(Schema):
username = String() email = Email()
class ChangePasswordSchema(Schema): class ChangePasswordSchema(Schema):
@ -50,7 +63,7 @@ class KeywordSchema(Schema):
class KeywordResponseSchema(Schema): class KeywordResponseSchema(Schema):
keyword = String() keyword = String()
s_id = Integer() s_id = Integer()
user_id = Integer() email = Email()
class SymbolSchema(Schema): class SymbolSchema(Schema):
@ -60,7 +73,7 @@ class SymbolSchema(Schema):
class SymbolResponseSchema(Schema): class SymbolResponseSchema(Schema):
symbol = String() symbol = String()
s_id = Integer() s_id = Integer()
user_id = Integer() email = Email()
class PortfolioShareResponseSchema(Schema): class PortfolioShareResponseSchema(Schema):
@ -69,12 +82,30 @@ class PortfolioShareResponseSchema(Schema):
class TransactionSchema(Schema): class TransactionSchema(Schema):
user_id = Integer() symbol = String()
time = String(validate=validate.Regexp(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"))
count = Integer()
price = Float()
class TransactionResponseSchema(Schema):
email = Email()
symbol = String() symbol = String()
time = String() time = String()
count = Integer() count = Integer()
price = Float() price = Float()
class TelegramIdSchema(Schema):
telegram_user_id = String()
class PortfolioResponseSchema(Schema):
symbol = String()
last_transaction = String()
count = Integer()
# price = Float()
class DeleteSuccessfulSchema(Schema): class DeleteSuccessfulSchema(Schema):
pass pass