Merge pull request #24 from WebEngineering2/api

Updated API
- Updated database model
- Update telegram user id in database
- Updated documentation
This commit is contained in:
Florian Kaiser 2022-03-27 18:02:46 +02:00 committed by GitHub
commit e8b9107f65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 489 additions and 308 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,16 +45,21 @@ 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()
db.session.commit()
return make_response({}, 200, "Successfully removed keyword") 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()
return make_response({}, 200, "Successfully removed keyword")
@keyword_blueprint.route('/keywords', methods=['GET']) @keyword_blueprint.route('/keywords', methods=['GET'])
@ -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,16 +45,21 @@ 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()
db.session.commit()
return make_response({}, 200, "Successfully removed symbol") 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()
return make_response({}, 200, "Successfully removed symbol")
@shares_blueprint.route('/shares', methods=['GET']) @shares_blueprint.route('/shares', methods=['GET'])
@ -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

@ -0,0 +1,42 @@
import os
from apiflask import APIBlueprint, abort
from db import db
from helper_functions import make_response, get_email_or_abort_401
from auth import auth
from schema import TelegramIdSchema, UsersSchema
from models import User
telegram_blueprint = APIBlueprint('telegram', __name__, url_prefix='/api')
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
@telegram_blueprint.route('/telegram', methods=['POST'])
@telegram_blueprint.output(UsersSchema(many=False), 200)
@telegram_blueprint.input(schema=TelegramIdSchema)
@telegram_blueprint.auth_required(auth)
@telegram_blueprint.doc(summary="Connects telegram user id", description="Connects telegram user id to user account")
def add_keyword(data):
email = get_email_or_abort_401()
check_if_telegram_user_id_data_exists(data)
query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist
abort(500, message="Unable to login")
query_user.telegram_user_id = data['telegram_user_id']
db.session.commit()
return make_response(query_user.as_dict(), 200, "Successfully connected telegram user")
def check_if_telegram_user_id_data_exists(data):
if "telegram_user_id" not in data:
abort(400, message="User ID missing")
if data['telegram_user_id'] == "" or data['telegram_user_id'] is None:
abort(400, message="User ID missing")

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

@ -5,13 +5,14 @@ from apiflask import APIFlask
from dotenv import load_dotenv from dotenv import load_dotenv
from flask_cors import CORS from flask_cors import CORS
from api.api_blueprint_keyword import keyword_blueprint
from api.api_blueprint_portfolio import portfolio_blueprint
from api.api_blueprint_shares import shares_blueprint
from api.api_blueprint_transactions import transaction_blueprint
from api.api_blueprint_telegram import telegram_blueprint
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():
@ -33,25 +34,28 @@ def create_app():
application.register_blueprint(transaction_blueprint) application.register_blueprint(transaction_blueprint)
application.register_blueprint(portfolio_blueprint) application.register_blueprint(portfolio_blueprint)
application.register_blueprint(users_blueprint) application.register_blueprint(users_blueprint)
application.register_blueprint(telegram_blueprint)
@application.before_first_request @application.before_first_request
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

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"info": { "info": {
"_postman_id": "b478b800-af91-45a7-8713-b199bcc41866", "_postman_id": "eed3eb48-b932-4d72-979a-38de9ae2cbf0",
"name": "APIFlask", "name": "APIFlask",
"description": "Webengineering 2 | Telegram Aktienbot", "description": "Webengineering 2 | Telegram Aktienbot",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
@ -35,7 +35,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -68,7 +68,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -96,7 +96,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {},\n \"status\": 261201,\n \"text\": \"aliqua amet consectetur elit\"\n}" "body": "{\n \"data\": {},\n \"status\": -35854777,\n \"text\": \"sint in\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -111,7 +111,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -139,7 +139,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -154,7 +154,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -182,7 +182,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -212,7 +212,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -245,7 +245,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -273,7 +273,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": [\n {\n \"keyword\": \"tempor dolor commodo ipsum non\",\n \"s_id\": -64068772,\n \"user_id\": 82510382\n },\n {\n \"keyword\": \"in aute ex\",\n \"s_id\": 60028598,\n \"user_id\": -36905324\n }\n ],\n \"status\": 63124172,\n \"text\": \"amet\"\n}" "body": "{\n \"data\": [\n {\n \"email\": \"8Es0sp5sb@wvQoAOvD.bzz\",\n \"keyword\": \"eiusmo\",\n \"s_id\": -48384117\n },\n {\n \"email\": \"MZ0cnQ1mwRV@oONtzNaRnVSaUXAReoDzwztMr.fiz\",\n \"keyword\": \"ullamco ad\",\n \"s_id\": -36966818\n }\n ],\n \"status\": 55335664,\n \"text\": \"dolor id ex\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -288,7 +288,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -316,7 +316,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -331,7 +331,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}", "raw": "{\n \"keyword\": \"nisi\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -359,7 +359,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -428,7 +428,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": [\n {\n \"keyword\": \"tempor dolor commodo ipsum non\",\n \"s_id\": -64068772,\n \"user_id\": 82510382\n },\n {\n \"keyword\": \"in aute ex\",\n \"s_id\": 60028598,\n \"user_id\": -36905324\n }\n ],\n \"status\": 63124172,\n \"text\": \"amet\"\n}" "body": "{\n \"data\": [\n {\n \"email\": \"8Es0sp5sb@wvQoAOvD.bzz\",\n \"keyword\": \"eiusmo\",\n \"s_id\": -48384117\n },\n {\n \"email\": \"MZ0cnQ1mwRV@oONtzNaRnVSaUXAReoDzwztMr.fiz\",\n \"keyword\": \"ullamco ad\",\n \"s_id\": -36966818\n }\n ],\n \"status\": 55335664,\n \"text\": \"dolor id ex\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -462,7 +462,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
} }
@ -497,7 +497,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -530,7 +530,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -558,7 +558,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {},\n \"status\": 261201,\n \"text\": \"aliqua amet consectetur elit\"\n}" "body": "{\n \"data\": {},\n \"status\": -35854777,\n \"text\": \"sint in\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -573,7 +573,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -601,7 +601,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -616,7 +616,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -644,7 +644,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -674,7 +674,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -707,7 +707,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -735,7 +735,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": [\n {\n \"s_id\": -53227093,\n \"symbol\": \"veniam ea amet irure\",\n \"user_id\": 7468241\n },\n {\n \"s_id\": -37877246,\n \"symbol\": \"ut tempor labore non\",\n \"user_id\": -72644124\n }\n ],\n \"status\": 87653200,\n \"text\": \"aliquip reprehenderit dolore\"\n}" "body": "{\n \"data\": [\n {\n \"email\": \"j32mUuC@iIJKfYQWSepoVsngEZYbfEmOwCzXXxVMP.alp\",\n \"s_id\": 86469214,\n \"symbol\": \"labore ea\"\n },\n {\n \"email\": \"PwKotAxaLBa8nY@nSsGmaxZeZqnRhOGmHhbICYhqTGLESrq.xy\",\n \"s_id\": 63768957,\n \"symbol\": \"laboris pariatur commodo\"\n }\n ],\n \"status\": -1862021,\n \"text\": \"culpa nulla\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -750,7 +750,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -778,7 +778,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -793,7 +793,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}", "raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -821,7 +821,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -890,7 +890,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": [\n {\n \"s_id\": -53227093,\n \"symbol\": \"veniam ea amet irure\",\n \"user_id\": 7468241\n },\n {\n \"s_id\": -37877246,\n \"symbol\": \"ut tempor labore non\",\n \"user_id\": -72644124\n }\n ],\n \"status\": 87653200,\n \"text\": \"aliquip reprehenderit dolore\"\n}" "body": "{\n \"data\": [\n {\n \"email\": \"j32mUuC@iIJKfYQWSepoVsngEZYbfEmOwCzXXxVMP.alp\",\n \"s_id\": 86469214,\n \"symbol\": \"labore ea\"\n },\n {\n \"email\": \"PwKotAxaLBa8nY@nSsGmaxZeZqnRhOGmHhbICYhqTGLESrq.xy\",\n \"s_id\": 63768957,\n \"symbol\": \"laboris pariatur commodo\"\n }\n ],\n \"status\": -1862021,\n \"text\": \"culpa nulla\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -924,7 +924,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
} }
@ -959,7 +959,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}", "raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -992,7 +992,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}", "raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1020,7 +1020,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {\n \"value\": \"reference #/components/schemas/() not found in the OpenAPI spec\"\n },\n \"status\": 14310780,\n \"text\": \"in sint sit\"\n}" "body": "{\n \"data\": {\n \"count\": 99691073,\n \"email\": \"DAX6XjHTr8eA6M@xsoUe.id\",\n \"price\": -14617384.086570382,\n \"symbol\": \"eu ad deserunt\",\n \"time\": \"ipsum nisi in laboris\"\n },\n \"status\": -51137224,\n \"text\": \"ipsum culpa amet\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -1035,7 +1035,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}", "raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1063,7 +1063,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -1078,7 +1078,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}", "raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1106,7 +1106,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -1175,7 +1175,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {\n \"count\": -19053100,\n \"price\": 39909986.26075193,\n \"symbol\": \"sit nisi\",\n \"time\": \"pariatur eu proident\",\n \"user_id\": 54782742\n },\n \"status\": 87070947,\n \"text\": \"null\"\n}" "body": "{\n \"data\": {\n \"count\": -37878076,\n \"price\": -40419772.172105886,\n \"symbol\": \"velit ut Ut elit esse\",\n \"time\": \"5462-92-97T03:27:22.076Z\"\n },\n \"status\": -509477,\n \"text\": \"proident\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -1209,7 +1209,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
} }
@ -1283,7 +1283,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {\n \"value\": \"reference #/components/schemas/200 not found in the OpenAPI spec\"\n },\n \"status\": 14426134,\n \"text\": \"velit in ad dolore\"\n}" "body": "{\n \"data\": [\n {\n \"count\": 75537465,\n \"last_transaction\": \"dolor enim\",\n \"symbol\": \"enim nostrud non deserunt\"\n },\n {\n \"count\": -69490418,\n \"last_transaction\": \"et\",\n \"symbol\": \"Excepteur irure est enim\"\n }\n ],\n \"status\": 7099250,\n \"text\": \"dolore in ad\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -1317,7 +1317,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
} }
@ -1352,7 +1352,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}", "raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1385,7 +1385,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}", "raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1428,7 +1428,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}", "raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1456,7 +1456,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"cupidatat mollit laborum aute\",\n \"aute in laboris dolor\"\n ]\n }\n },\n \"message\": \"in dolore exercitation eu elit\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -1471,7 +1471,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}", "raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1499,7 +1499,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -1568,7 +1568,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {\n \"admin\": false,\n \"password\": \"voluptate magna esse\",\n \"telegram_name\": \"id\",\n \"user_id\": -55336867,\n \"username\": \"do exercitation\"\n },\n \"status\": -11469710,\n \"text\": \"aute\"\n}" "body": "{\n \"data\": {\n \"admin\": false,\n \"email\": \"VNB@NeqjbTmHnkWDwPacdUoXgpYVTNlD.iip\",\n \"password\": \"fugiat ipsum\",\n \"telegram_user_id\": \"et\",\n \"username\": \"nostrud laborum\"\n },\n \"status\": -78288268,\n \"text\": \"laborum minim\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -1602,7 +1602,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -1632,7 +1632,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1665,7 +1665,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1708,7 +1708,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1736,7 +1736,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -1751,7 +1751,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1779,7 +1779,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -1799,7 +1799,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"email\": \"YKQkCdcOoJ3vH@wbOpjGTXH.avm\",\n \"password\": \"veniam\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1827,7 +1827,7 @@
"header": [], "header": [],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"email\": \"YKQkCdcOoJ3vH@wbOpjGTXH.avm\",\n \"password\": \"veniam\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1856,7 +1856,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {\n \"token\": \"minim\"\n },\n \"status\": 86563099,\n \"text\": \"non tempor quis ullamco est\"\n}" "body": "{\n \"data\": {\n \"token\": \"do ipsu\"\n },\n \"status\": 31961350,\n \"text\": \"Lorem dolor commodo laborum cillum\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -1865,7 +1865,7 @@
"header": [], "header": [],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"email\": \"YKQkCdcOoJ3vH@wbOpjGTXH.avm\",\n \"password\": \"veniam\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1894,7 +1894,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
} }
] ]
}, },
@ -1914,7 +1914,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"email\": \"DJR029Ov-keM@pyhCxnpZmcVMxADSiCjmsGRZksCf.zz\",\n \"password\": \"sed voluptate\",\n \"username\": \"voluptate aute proident\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1942,7 +1942,7 @@
"header": [], "header": [],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"email\": \"DJR029Ov-keM@pyhCxnpZmcVMxADSiCjmsGRZksCf.zz\",\n \"password\": \"sed voluptate\",\n \"username\": \"voluptate aute proident\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -1971,7 +1971,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": {\n \"admin\": false,\n \"password\": \"voluptate magna esse\",\n \"telegram_name\": \"id\",\n \"user_id\": -55336867,\n \"username\": \"do exercitation\"\n },\n \"status\": -11469710,\n \"text\": \"aute\"\n}" "body": "{\n \"data\": {\n \"admin\": false,\n \"email\": \"VNB@NeqjbTmHnkWDwPacdUoXgpYVTNlD.iip\",\n \"password\": \"fugiat ipsum\",\n \"telegram_user_id\": \"et\",\n \"username\": \"nostrud laborum\"\n },\n \"status\": -78288268,\n \"text\": \"laborum minim\"\n}"
}, },
{ {
"name": "Validation error", "name": "Validation error",
@ -1980,7 +1980,7 @@
"header": [], "header": [],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}", "raw": "{\n \"email\": \"DJR029Ov-keM@pyhCxnpZmcVMxADSiCjmsGRZksCf.zz\",\n \"password\": \"sed voluptate\",\n \"username\": \"voluptate aute proident\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -2009,7 +2009,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
} }
] ]
}, },
@ -2039,7 +2039,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}", "raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -2073,7 +2073,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}", "raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -2117,7 +2117,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}", "raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -2146,7 +2146,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}" "body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -2161,7 +2161,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}", "raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -2190,7 +2190,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
}, },
@ -2259,7 +2259,7 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"data\": [\n {\n \"admin\": true,\n \"password\": \"incididunt id dolore\",\n \"telegram_name\": \"id sed\",\n \"user_id\": 15906508,\n \"username\": \"dolor consequat ullamco\"\n },\n {\n \"admin\": true,\n \"password\": \"voluptate non\",\n \"telegram_name\": \"dolor sunt fugiat exercitation\",\n \"user_id\": 95246024,\n \"username\": \"Duis qui culpa Ut labore\"\n }\n ],\n \"status\": 81180129,\n \"text\": \"in ullamco\"\n}" "body": "{\n \"data\": [\n {\n \"admin\": false,\n \"email\": \"paghoo4COL6gQNz@SJXcMSOC.kus\",\n \"password\": \"exercitation laboris Ut cillum nisi\",\n \"telegram_user_id\": \"id in incididunt sint\",\n \"username\": \"sed laborum cill\"\n },\n {\n \"admin\": false,\n \"email\": \"WFYb2q0XXey6WZa@JNSezyFkIVzneuifIXi.la\",\n \"password\": \"velit irure veniam\",\n \"telegram_user_id\": \"pariatur sed commodo\",\n \"username\": \"incididunt consequat\"\n }\n ],\n \"status\": -92106336,\n \"text\": \"commodo ull\"\n}"
}, },
{ {
"name": "Authentication error", "name": "Authentication error",
@ -2293,7 +2293,189 @@
} }
], ],
"cookie": [], "cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}" "body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}
]
},
{
"name": "Telegram",
"item": [
{
"name": "Connects telegram user id",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "<Bearer Token>",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "Accept",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
},
"description": "Connects telegram user id to user account"
},
"response": [
{
"name": "Successful response",
"originalRequest": {
"method": "POST",
"header": [
{
"description": "Added as a part of security scheme: bearer",
"key": "Authorization",
"value": "Bearer <token>"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"admin\": false,\n \"email\": \"VNB@NeqjbTmHnkWDwPacdUoXgpYVTNlD.iip\",\n \"password\": \"fugiat ipsum\",\n \"telegram_user_id\": \"et\",\n \"username\": \"nostrud laborum\"\n },\n \"status\": -78288268,\n \"text\": \"laborum minim\"\n}"
},
{
"name": "Validation error",
"originalRequest": {
"method": "POST",
"header": [
{
"description": "Added as a part of security scheme: bearer",
"key": "Authorization",
"value": "Bearer <token>"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"velit\",\n \"ut laboris\"\n ]\n }\n },\n \"message\": \"dolore nostrud officia ex\"\n}"
},
{
"name": "Authentication error",
"originalRequest": {
"method": "POST",
"header": [
{
"description": "Added as a part of security scheme: bearer",
"key": "Authorization",
"value": "Bearer <token>"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
}
},
"status": "Unauthorized",
"code": 401,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
} }
] ]
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,105 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <diagram program="umletino" version="14.3.0"><zoom_level>10</zoom_level><help_text>Database V0.1</help_text><element><id>UMLClass</id><coordinates><x>705</x><y>360</y><w>210</w><h>80</h></coordinates><panel_attributes>keywords
<diagram program="umlet" version="14.3.0">
<zoom_level>10</zoom_level>
<element>
<id>UMLClass</id>
<coordinates>
<x>580</x>
<y>320</y>
<w>210</w>
<h>80</h>
</coordinates>
<panel_attributes>Stichwort
-- --
PK: s_id PK: s_id int(11)
FK: username FK: email varchar(255)
Stichwort</panel_attributes> keyword varchar(255)</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>425</x><y>240</y><w>210</w><h>130</h></coordinates><panel_attributes>users
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>580</x>
<y>100</y>
<w>210</w>
<h>130</h>
</coordinates>
<panel_attributes>User
-- --
PK: username PK: email varchar(255)
password password varchar(255)
user_id username varchar(255)
telegramname telegram_user_id varchar(255)
Rolle admin tinyint(1)
</panel_attributes> </panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>705</x><y>150</y><w>210</w><h>70</h></coordinates><panel_attributes>shares
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>930</x>
<y>80</y>
<w>210</w>
<h>90</h>
</coordinates>
<panel_attributes>Aktie
-- --
PK: a_id PK: a_id int(11)
FK: username FK: email varchar(255)
Aktiensymbol symbol varchar(255)
</panel_attributes> </panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>135</x><y>150</y><w>210</w><h>130</h></coordinates><panel_attributes>transaction
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>200</x>
<y>320</y>
<w>210</w>
<h>130</h>
</coordinates>
<panel_attributes>Transaktion
-- --
PK: t_id PK: t_id int(11)
FK: username FK: email varchar(255)
FK: Aktiensymbol symbol varchar(255)
Zeitpunkt time datetime
Anzahl(+/-) count int(11)
Preis(+/-) price float
</panel_attributes> </panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>335</x><y>190</y><w>110</w><h>100</h></coordinates><panel_attributes>lt=&lt;&lt;-
<additional_attributes/> group=1</panel_attributes><additional_attributes>10;10;60;10;60;80;90;80</additional_attributes></element><element><id>Relation</id><coordinates><x>625</x><y>190</y><w>100</w><h>100</h></coordinates><panel_attributes>lt=&lt;&lt;-</panel_attributes><additional_attributes>80;10;50;10;50;80;10;80</additional_attributes></element><element><id>Relation</id><coordinates><x>625</x><y>260</y><w>100</w><h>160</h></coordinates><panel_attributes>lt=&lt;&lt;-</panel_attributes><additional_attributes>80;140;50;140;50;10;10;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>140</x><y>410</y><w>100</w><h>30</h></coordinates><panel_attributes>Database V0.1</panel_attributes><additional_attributes></additional_attributes></element></diagram>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>780</x>
<y>120</y>
<w>170</w>
<h>30</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>150.0;10.0;10.0;10.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>400</x>
<y>120</y>
<w>200</w>
<h>260</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;240.0;180.0;10.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>510</x>
<y>200</y>
<w>90</w>
<h>190</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>70.0;170.0;10.0;10.0</additional_attributes>
</element>
</diagram>