mirror of
https://github.com/pds-nest/nest.git
synced 2024-11-22 04:54:18 +00:00
Login + User creation
Add API calls for login and user creation.
This commit is contained in:
parent
004c9a4528
commit
a4268df8f5
9 changed files with 263 additions and 6 deletions
|
@ -7,20 +7,33 @@ import werkzeug.middleware.proxy_fix
|
||||||
from .routes import *
|
from .routes import *
|
||||||
from .database import Base, tables
|
from .database import Base, tables
|
||||||
import psycopg2
|
import psycopg2
|
||||||
|
from .gestione import *
|
||||||
|
from flask_jwt_extended import *
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
if os.getenv('COOKIE_SECRET'):
|
if os.getenv('COOKIE_SECRET'):
|
||||||
app.secret_key = os.getenv('COOKIE_SECRET')
|
app.secret_key = os.getenv('COOKIE_SECRET')
|
||||||
else:
|
else:
|
||||||
app.secret_key = "testing"
|
app.secret_key = "testing"
|
||||||
|
if os.getenv("JWT_SECRET_KEY"):
|
||||||
|
app.config["JWT_SECRET_KEY"] = os.getenv("JWT_SECRET_KEY")
|
||||||
|
else:
|
||||||
|
app.config["JWT_SECRET_KEY"] = "testing"
|
||||||
|
|
||||||
reverse_proxy_app = werkzeug.middleware.proxy_fix.ProxyFix(app=app, x_for=1, x_proto=0, x_host=1, x_port=0, x_prefix=0)
|
reverse_proxy_app = werkzeug.middleware.proxy_fix.ProxyFix(app=app, x_for=1, x_proto=0, x_host=1, x_port=0, x_prefix=0)
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password@localhost:5432/PdSDev'
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password@localhost:5432/PdSDev'
|
||||||
Base.app = app
|
Base.app = app
|
||||||
Base.init_app(app)
|
Base.init_app(app)
|
||||||
|
jwt = JWTManager(app)
|
||||||
# Routes setup
|
# Routes setup
|
||||||
|
|
||||||
app.add_url_rule("/doa", view_func=page_doa, methods=["GET", "POST"])
|
app.add_url_rule("/doa", view_func=page_doa, methods=["GET", "POST"])
|
||||||
|
app.add_url_rule("/api/login", view_func=page_login, methods=["POST"])
|
||||||
|
app.add_url_rule("/api/user/create", view_func=page_user_create, methods=["POST"])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
Base.create_all()
|
Base.create_all()
|
||||||
|
if not User.query.filter_by(isAdmin=True).all():
|
||||||
|
Base.session.add(User(email="admin@admin.com", password=gen_password("password"), username="admin", isAdmin=True))
|
||||||
|
Base.session.commit()
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|
|
@ -5,3 +5,59 @@ A utilities Python Module.
|
||||||
Gestione adds many fancy thingamajigs to the flask application, such as a login system and such.
|
Gestione adds many fancy thingamajigs to the flask application, such as a login system and such.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from .database import *
|
||||||
|
import bcrypt
|
||||||
|
import functools
|
||||||
|
from flask_jwt_extended import get_jwt_identity
|
||||||
|
|
||||||
|
|
||||||
|
def authenticate(username, password):
|
||||||
|
"""
|
||||||
|
Authentication method. It checks if the combination of username+password is a valid match. If not, it returns None.
|
||||||
|
:param username: the user's email
|
||||||
|
:param password: the user's password
|
||||||
|
:return: if the credentials are correct, it returns the user. Else, it returns None.
|
||||||
|
"""
|
||||||
|
user = User.query.filter_by(email=username).first()
|
||||||
|
try:
|
||||||
|
if bcrypt.checkpw(bytes(password, encoding="utf-8"), user.password):
|
||||||
|
return user
|
||||||
|
except AttributeError:
|
||||||
|
# Se non esiste l'Utente
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def identity(payload):
|
||||||
|
"""
|
||||||
|
Authentication verification method. It checks if the user is in fact registered on the server.
|
||||||
|
It is required by Flask-JWT, and shouldnt be used alone.
|
||||||
|
:param payload: the reqest payload.
|
||||||
|
:return: an User or None. It depends whether the user is actually registered on the platform.
|
||||||
|
"""
|
||||||
|
user_id = payload['identity']
|
||||||
|
user = User.query.filter_by(id=user_id).first()
|
||||||
|
if user:
|
||||||
|
return user.id
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def gen_password(password):
|
||||||
|
"""
|
||||||
|
It generates an hashed password.
|
||||||
|
:param password: the password that needs to be hashed.
|
||||||
|
:return: the password's hash.
|
||||||
|
"""
|
||||||
|
return bcrypt.hashpw(bytes(password, "utf-8"), bcrypt.gensalt())
|
||||||
|
|
||||||
|
|
||||||
|
def find_user(email):
|
||||||
|
return User.query.filter_by(email=email).first()
|
||||||
|
|
||||||
|
|
||||||
|
def admin_or_403(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
def func(*args, **kwargs):
|
||||||
|
current_user = get_jwt_identity()
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
This module imports all the routes that return something to the frontend.
|
This module imports all the routes that return something to the frontend.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .doa import page_doa
|
from .doa import page_doa
|
||||||
|
from .users import *
|
|
@ -7,7 +7,10 @@ from ..database import *
|
||||||
|
|
||||||
|
|
||||||
def page_doa():
|
def page_doa():
|
||||||
utente = User()
|
"""
|
||||||
|
Dead or Alive page. If a client sees this, the server is probably fine.
|
||||||
|
:return: A friendly and calming message, that makes you happy that the server is not on fire.
|
||||||
|
"""
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
return "Get"
|
return "If you see this, the server is fine."
|
||||||
return "If you see this, the server is fine."
|
return "Hello there."
|
||||||
|
|
2
code/backend/nest_backend/routes/users/__init__.py
Normal file
2
code/backend/nest_backend/routes/users/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
from .user_create import page_user_create
|
||||||
|
from .login import page_login
|
21
code/backend/nest_backend/routes/users/login.py
Normal file
21
code/backend/nest_backend/routes/users/login.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from flask import render_template, abort, jsonify, request
|
||||||
|
from ...database import *
|
||||||
|
from ...gestione import *
|
||||||
|
from flask_jwt_extended import create_access_token
|
||||||
|
|
||||||
|
|
||||||
|
def page_login():
|
||||||
|
"""
|
||||||
|
The API call that allows to log-in. It requires:
|
||||||
|
:form email: The user's email
|
||||||
|
:form password: The users's password
|
||||||
|
:return: Json-formatted data. If the login is successful, it will contain the access_token.
|
||||||
|
|
||||||
|
The access_token must be included in the Authorization header, using the format Bearer <token>.
|
||||||
|
"""
|
||||||
|
email = request.json.get("email", None)
|
||||||
|
password = request.json.get("password", None)
|
||||||
|
if authenticate(email, password):
|
||||||
|
access_token = create_access_token(identity=email)
|
||||||
|
return jsonify({"result": "success", "access_token": access_token}), 201
|
||||||
|
return jsonify({"result": "failure", "msg": "Bad username or password."}), 401
|
22
code/backend/nest_backend/routes/users/user_create.py
Normal file
22
code/backend/nest_backend/routes/users/user_create.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
from flask import render_template, abort, jsonify, request
|
||||||
|
from ...database import *
|
||||||
|
from flask_jwt_extended import jwt_required
|
||||||
|
from ...gestione import *
|
||||||
|
|
||||||
|
@jwt_required()
|
||||||
|
def page_user_create():
|
||||||
|
"""
|
||||||
|
The API call that allows to create new users. It requires:
|
||||||
|
:form email: The user's email
|
||||||
|
:form password: The users's password
|
||||||
|
:form username: The users's username
|
||||||
|
:return: Json-formatted data. If something goes wrong, it returns a
|
||||||
|
{'result':'failure', 'content':'something blew up'}, else it returns {'result':'success', 'content':{newUser.to_json()}.
|
||||||
|
"""
|
||||||
|
user = find_user(get_jwt_identity())
|
||||||
|
if not user.isAdmin:
|
||||||
|
abort(403)
|
||||||
|
nUser = User(email=request.json.get("email"), password=gen_password(request.json.get("password")), username=request.json.get("username"))
|
||||||
|
Base.session.add(nUser)
|
||||||
|
Base.session.commit()
|
||||||
|
return jsonify({"result":"success", "content":"something"})
|
139
code/backend/poetry.lock
generated
139
code/backend/poetry.lock
generated
|
@ -1,3 +1,30 @@
|
||||||
|
[[package]]
|
||||||
|
name = "bcrypt"
|
||||||
|
version = "3.2.0"
|
||||||
|
description = "Modern password hashing for your software and your servers"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
cffi = ">=1.1"
|
||||||
|
six = ">=1.4.1"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
tests = ["pytest (>=3.2.1,!=3.3.0)"]
|
||||||
|
typecheck = ["mypy"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cffi"
|
||||||
|
version = "1.14.5"
|
||||||
|
description = "Foreign Function Interface for Python calling C code."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pycparser = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "click"
|
name = "click"
|
||||||
version = "7.1.2"
|
version = "7.1.2"
|
||||||
|
@ -25,6 +52,22 @@ dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxco
|
||||||
docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"]
|
docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"]
|
||||||
dotenv = ["python-dotenv"]
|
dotenv = ["python-dotenv"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flask-jwt-extended"
|
||||||
|
version = "4.1.0"
|
||||||
|
description = "Extended JWT integration with Flask"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6,<4"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Flask = ">=1.0,<2.0"
|
||||||
|
PyJWT = ">=2.0,<3.0"
|
||||||
|
Werkzeug = ">=0.14"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
asymmetric_crypto = ["cryptography (>=3.0,<4.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flask-sqlalchemy"
|
name = "flask-sqlalchemy"
|
||||||
version = "2.5.1"
|
version = "2.5.1"
|
||||||
|
@ -86,6 +129,36 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pycparser"
|
||||||
|
version = "2.20"
|
||||||
|
description = "C parser in Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyjwt"
|
||||||
|
version = "2.0.1"
|
||||||
|
description = "JSON Web Token implementation in Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
crypto = ["cryptography (>=3.3.1,<4.0.0)"]
|
||||||
|
dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1,<4.0.0)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"]
|
||||||
|
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
|
||||||
|
tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.15.0"
|
||||||
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlalchemy"
|
name = "sqlalchemy"
|
||||||
version = "1.4.10"
|
version = "1.4.10"
|
||||||
|
@ -132,9 +205,57 @@ watchdog = ["watchdog"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.8.5"
|
python-versions = "^3.8.5"
|
||||||
content-hash = "71b957004ae80674013de8327f592dd17b9ffb4e5c6a865e69326555f9c2a1ce"
|
content-hash = "6bc937df83a15e8774d6ab63f19f5b6b3780730d935678c81259f53ee7cd8ebc"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
|
bcrypt = [
|
||||||
|
{file = "bcrypt-3.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6"},
|
||||||
|
{file = "bcrypt-3.2.0-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7"},
|
||||||
|
{file = "bcrypt-3.2.0-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1"},
|
||||||
|
{file = "bcrypt-3.2.0-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d"},
|
||||||
|
{file = "bcrypt-3.2.0-cp36-abi3-win32.whl", hash = "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55"},
|
||||||
|
{file = "bcrypt-3.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34"},
|
||||||
|
{file = "bcrypt-3.2.0.tar.gz", hash = "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"},
|
||||||
|
]
|
||||||
|
cffi = [
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"},
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"},
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"},
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"},
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"},
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"},
|
||||||
|
{file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"},
|
||||||
|
{file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"},
|
||||||
|
{file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"},
|
||||||
|
{file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"},
|
||||||
|
{file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"},
|
||||||
|
{file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"},
|
||||||
|
{file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"},
|
||||||
|
{file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"},
|
||||||
|
{file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"},
|
||||||
|
{file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"},
|
||||||
|
{file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"},
|
||||||
|
{file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"},
|
||||||
|
{file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"},
|
||||||
|
{file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"},
|
||||||
|
{file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"},
|
||||||
|
{file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"},
|
||||||
|
{file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"},
|
||||||
|
{file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"},
|
||||||
|
{file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"},
|
||||||
|
{file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"},
|
||||||
|
{file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"},
|
||||||
|
{file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"},
|
||||||
|
{file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"},
|
||||||
|
{file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"},
|
||||||
|
{file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"},
|
||||||
|
{file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"},
|
||||||
|
{file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"},
|
||||||
|
{file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"},
|
||||||
|
{file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"},
|
||||||
|
{file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
|
||||||
|
{file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
|
||||||
|
]
|
||||||
click = [
|
click = [
|
||||||
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
|
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
|
||||||
{file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
|
{file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
|
||||||
|
@ -143,6 +264,10 @@ flask = [
|
||||||
{file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"},
|
{file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"},
|
||||||
{file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"},
|
{file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"},
|
||||||
]
|
]
|
||||||
|
flask-jwt-extended = [
|
||||||
|
{file = "Flask-JWT-Extended-4.1.0.tar.gz", hash = "sha256:77ca23f23e80480ea42b9c1d9b0fca214e08db7192583e782c2421416b4a4655"},
|
||||||
|
{file = "Flask_JWT_Extended-4.1.0-py2.py3-none-any.whl", hash = "sha256:f952f4ebd449182431c6755acfb7cbb52b8034df7a9f9ef95eb51ccfc1e235b0"},
|
||||||
|
]
|
||||||
flask-sqlalchemy = [
|
flask-sqlalchemy = [
|
||||||
{file = "Flask-SQLAlchemy-2.5.1.tar.gz", hash = "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912"},
|
{file = "Flask-SQLAlchemy-2.5.1.tar.gz", hash = "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912"},
|
||||||
{file = "Flask_SQLAlchemy-2.5.1-py2.py3-none-any.whl", hash = "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390"},
|
{file = "Flask_SQLAlchemy-2.5.1-py2.py3-none-any.whl", hash = "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390"},
|
||||||
|
@ -252,6 +377,18 @@ psycopg2 = [
|
||||||
{file = "psycopg2-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7"},
|
{file = "psycopg2-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7"},
|
||||||
{file = "psycopg2-2.8.6.tar.gz", hash = "sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543"},
|
{file = "psycopg2-2.8.6.tar.gz", hash = "sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543"},
|
||||||
]
|
]
|
||||||
|
pycparser = [
|
||||||
|
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
|
||||||
|
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
||||||
|
]
|
||||||
|
pyjwt = [
|
||||||
|
{file = "PyJWT-2.0.1-py3-none-any.whl", hash = "sha256:b70b15f89dc69b993d8a8d32c299032d5355c82f9b5b7e851d1a6d706dffe847"},
|
||||||
|
{file = "PyJWT-2.0.1.tar.gz", hash = "sha256:a5c70a06e1f33d81ef25eecd50d50bd30e34de1ca8b2b9fa3fe0daaabcf69bf7"},
|
||||||
|
]
|
||||||
|
six = [
|
||||||
|
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
|
||||||
|
{file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
|
||||||
|
]
|
||||||
sqlalchemy = [
|
sqlalchemy = [
|
||||||
{file = "SQLAlchemy-1.4.10-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:6c24884bb8d0065cf6f61b643e8f32947ef8386a5bcdad41b921ed81994ea8f1"},
|
{file = "SQLAlchemy-1.4.10-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:6c24884bb8d0065cf6f61b643e8f32947ef8386a5bcdad41b921ed81994ea8f1"},
|
||||||
{file = "SQLAlchemy-1.4.10-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:266fbf4a0d3f4ed614fff60485e3ba83d3eef4a736102b9b7e461402dc930234"},
|
{file = "SQLAlchemy-1.4.10-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:266fbf4a0d3f4ed614fff60485e3ba83d3eef4a736102b9b7e461402dc930234"},
|
||||||
|
|
|
@ -9,6 +9,8 @@ python = "^3.8.5"
|
||||||
psycopg2 = "^2.8.6"
|
psycopg2 = "^2.8.6"
|
||||||
Flask = "^1.1.2"
|
Flask = "^1.1.2"
|
||||||
Flask-SQLAlchemy = "^2.5.1"
|
Flask-SQLAlchemy = "^2.5.1"
|
||||||
|
bcrypt = "^3.2.0"
|
||||||
|
Flask-JWT-Extended = "^4.1.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue