From 2ccc2e82a3fbb05f43d8c43915413b318dbeca46 Mon Sep 17 00:00:00 2001 From: Wojciech Janota Date: Thu, 17 Nov 2022 22:45:43 +0100 Subject: [PATCH] NXPR-3 WIP --- config.yml | 3 +- database.db | 0 fleetcontrol | 2 +- .../__pycache__/communication.cpython-310.pyc | Bin 2532 -> 4698 bytes network/communication.py | 72 +++++++++++++++++- .../config/__pycache__/config.cpython-310.pyc | Bin 1506 -> 1607 bytes utils/config/config.py | 5 ++ .../__pycache__/database.cpython-310.pyc | Bin 6389 -> 7448 bytes utils/database/database.py | 29 ++++++- utils/middleware/__init__.py | 1 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 208 bytes .../__pycache__/auth.cpython-310.pyc | Bin 0 -> 1377 bytes utils/middleware/auth.py | 45 +++++++++++ .../models/__pycache__/models.cpython-310.pyc | Bin 1541 -> 2067 bytes utils/models/models.py | 19 +++-- 15 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 database.db create mode 100644 utils/middleware/__init__.py create mode 100644 utils/middleware/__pycache__/__init__.cpython-310.pyc create mode 100644 utils/middleware/__pycache__/auth.cpython-310.pyc create mode 100644 utils/middleware/auth.py diff --git a/config.yml b/config.yml index 7f1a02d..2e9073a 100644 --- a/config.yml +++ b/config.yml @@ -4,4 +4,5 @@ server_loglevel: "INFO" database_file: "database.db" server_host: "localhost" server_password: "sekret_password" -server_access_username: "user" \ No newline at end of file +server_access_username: "user" +jwt_secret: "sekrit" \ No newline at end of file diff --git a/database.db b/database.db new file mode 100644 index 0000000..e69de29 diff --git a/fleetcontrol b/fleetcontrol index 05192c6..6c508a3 100644 --- a/fleetcontrol +++ b/fleetcontrol @@ -5,7 +5,7 @@ from utils.config.config import ServerConfig config = ServerConfig() server = Server(host=config.server_host, port=config.server_port, name=config.server_name, access_password=config.server_password, - access_username=config.server_access_username, version="v0.0.1alpha", database_file_path=config.database_file, logging_level=config.server_loglevel) + access_username=config.server_access_username, jwt_secret=config.jwt_secret, version="v0.0.1alpha", database_file_path=config.database_file, logging_level=config.server_loglevel) server.run() diff --git a/network/__pycache__/communication.cpython-310.pyc b/network/__pycache__/communication.cpython-310.pyc index 8c65223c1c91a8d75ab8712dce086236912a372b..e8db3a46e0fb8f2793bcdc9e034f92d6851c3923 100644 GIT binary patch literal 4698 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 delta 317 zcmY+=yGjE=6b9hg%j_mQmyLxa0Y%aXi?0xb;2RiQZ@6F;g_BA+kiv*Xs&J}+uc4)# z_zbqzg0GN&rpv$?zM1(sFz4I;8vp2ArLaEU9`2Uq+HbtY$)L_q^PBbi*Mc?Ov*x_5 z#)=D?aRD2+q&b(cg)4gE3U+XZ7Tke7+@%-p!ZmDY#Rl%d=r&ZWu0zg5g_Mg5eQZ=n zk9?#B>nI2HqI|2Ss@aoqI+M>-Gj>XF>)V_9h{ g8$H<{;)B%R-3Icn50C0_8RkIg?sH5J7%Q6yEXAdcC%{iJLfyl~5;bnmB3Fq(2lwX;UR_NoWG4KM)t{IG#!3c5Tz~ zhLEVO5v>XbB#7n!0##~m^nwHyAoaq511C;M9QFn$xNx8<5*OgT@lWDpBVoy(X5PGc zKi|IhcApG?GGgRIAzgvrpV_7KM8}%ZPOh%?cb^~%Rj9{Qv%Z8ct0lCoKjD`$uc>DP ziGW>j%0%I)>7a@ zu&tUtw4-S_usg)4ze7C=%ffy!>x-1S{5l~6VnFXZv&EiT4)sXYULsgYJ!xhNmaUd| z+Y`92x06xvNT2c?gR7$06cycppVe|2f&^PfHyrh&aSh;MnSPE}wwVN(t*0oha6eU= z37#ayVN{hw))=zAS;iL_e-4k1BRIIK5{0g8J#W%ve(oAeJ3sPJHcvD2D;3YL!j(ch zfQtl0i}Ba^hG&&BlUZ!5!{;%GEoBrct5$4MaemjYWLz9+7)sa7l?zG5%Lfta)2L=J z4o9{I1^Z?`2i>%_l<;&HmTU$)E;+Z7%+Twl9~umD(aF)4n!-m@X$pP@V{kIB*UT3z z5f9ItKP_)f#|b}&cV0l4Kv|{mrF2JgjWu%^Z7!8%x5Q83F%Qbomd#L|nX{M=@9C;SQuaxIYD0d>lkL4+O{s>eam%eE3 zBl)wajSq=$M0ygp|EoS$Yo|EGu!>^y=QR{E|s?Jyr~&kD-3d%Ezol7NaREg_CNLdXK{ZFn36l^!{tO!o(ojJFb6LTWaLh-?25xAvBS= z-4rcyoL&4ifVgAid zaX)C<9(=pVcPJmg>vGH=#+4k0&*16=!YPC?0Nb6(SzI>TB+8}`rV(C7xPX8UhhIWS zAiROFF_z2KDGSvPC-^U*OjE)n90>;^dL&?k!aDqYVSmIQ(G5TBjIbWjIBLfYG1=PF z87 XWHR_ZgU}3spb~^yXo9~+!tVb7?>H0( delta 1646 zcma)6TTc@~6z-JW?RIIo6jGoR5D=l|eo-PKm753xYE%-ND35tqXF72Q}>*l`jWE=4Wy&a7KGaAYbEF}$RK5k>*E>dSH)L$ zth(QdABCv5cuqLWyy!&&cv97t*R#wEEX43L zup<{WN`6h`nI#qLIE4!dFF+9m8gXY_vpJ)5xAX@Zqnl+t8@Y5Dm531B32?NH!w$yS zkts7ZK1?PIY&o`4(4z+TVsUAGQBzl0h~ZR%`+?ow_NPRkq4J-%tZFFG z5`4AnWgru5ZON?Um<@xz@Z7mE&ZFi7h|ECDWq>KLWd+ZzC#EaUrGrKikvM)ryDP?p zewKmGcztxU;tlGjwUtBntvawCAOxS>!BNVUh_Uh#{HN1{~g;JX~i2vtCQdj-;U%fy$IX?lI=C{909N*bY=C*Ip5O{RUvUc;3Ym9t8Lym z&7w>}*Vv;24-jbw;Mb@ZR$Ol9U^NU70vKgr7HNqT;Z)U4PpsJPo880Fqg;nDQ`- XUeoaiVjhNzfy?GXWlY{O@)Z3A%zi$P diff --git a/utils/database/database.py b/utils/database/database.py index 1753959..e4bc5dc 100644 --- a/utils/database/database.py +++ b/utils/database/database.py @@ -1,6 +1,7 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from utils.models.models import Client, VMImage +from sqlalchemy.ext.declarative import declarative_base +from utils.models.models import Client, VMImage, User from utils.exceptions.DatabaseException import DatabaseException import logging @@ -163,3 +164,29 @@ class Database: self.logger.error(f"Couldn't modify object in database: {ex}") raise DatabaseException( f"Couldn't modify object in database: {ex}") + + def add_user(self, new_user: User): + try: + with self.session.begin(): + self.session.add(new_user) + self.session.flush() + self.session.merge() + except Exception as ex: + self.logger.error(f"Couldn't add user to the database: {ex}") + raise DatabaseException(f"Couldn't add user to the database: {ex}") + + def get_user_by_id(self, user_id: int) -> User: + try: + with self.session.begin(): + return self.session.query(User).filter(User.user_id == user_id).first() + except Exception as ex: + self.logger.error(f"Error getting data from database: {ex}") + raise DatabaseException(f"Error getting data from database: {ex}") + + def get_user_by_name(self, username: str) -> User: + try: + with self.session.begin(): + return self.session.query(User).filter(User.username == username).first() + except Exception as ex: + self.logger.error(f"Error getting data from database: {ex}") + raise DatabaseException(f"Error getting data from database: {ex}") diff --git a/utils/middleware/__init__.py b/utils/middleware/__init__.py new file mode 100644 index 0000000..25d9ef7 --- /dev/null +++ b/utils/middleware/__init__.py @@ -0,0 +1 @@ +from . import auth diff --git a/utils/middleware/__pycache__/__init__.cpython-310.pyc b/utils/middleware/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8746ad3f1a8028ef2da8b51f8d430d3bc4d08cce GIT binary patch literal 208 zcmYjLK?=e!5KL+hA`}X~qKCR45D~nKAbRi;LbKFJo0Lt0`UgMamwNT&7d)AGa$ske zfnnAb#f(KfHldkEeI@gcEShyZS4L7y@s9QU#5q&ho>h}Kk8#DvTn2yMR@ulXHJ*&} zC_nlf;oy)Q7=1$nJF*vSyaP0?Hi)E6TPth{5iB)lbe^QQRLfz2;C1Jq*GhGGm4qOK XHrflZ81CbA*;^GlT%{jenl0HEdQvpd literal 0 HcmV?d00001 diff --git a/utils/middleware/__pycache__/auth.cpython-310.pyc b/utils/middleware/__pycache__/auth.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3a9f899c5ddaf73c951556dc1003783b6223d0b GIT binary patch literal 1377 zcmYjQ&2J+$6t_JenS7P(Cqy7^4t&j_jkMBoTCFH-wnT)2nl7uI%V;`wrjvSRg6%YI zlpv(81eYQqt{eby*?-Abxa^(Ns;E3qnrc0o-}|ur{QP@A9Cr1v;d z(Lp3xj7^ZMVRE+Nx8RrW04VemI>SGr5vG`u7v33O;su7Yt=$-=uSW$mL&rV%#??@}8`aH#v6MJpq?(!8rIWse=|wNWXnZA5G5 zWN9gPTv?FPR|j7s!L)g9E$xLh_7*nX0N-2Zc$$dy-AU(E!;C)W^l`_bJ25?yZgO6ypl6K0}>Waf*0sdyoXY>z<=SN4GFh* zb#r^F4hxaaBb65UYutHd_?+MTDwQ(LlTHNF9aS8$TsNNP#xjc;^(|e=n3Pe%v`wKF z+F?S#+%K>{Xg=QF-~McS*bATZ2R+>!e7&>N-`xoZy>EL1D09>7Fx3l3DQCLLizI>5 zLe7pE*R^5q^S$1F_+{_8cD@+ifAEQqgIdHB2(Jz^sl6#Yf;`HYkHwub-F|)?@sz%i zZu%=EGQZQ$m08L=u;ZAC&ML`&Va~4$^Hg-@kVTXUsU11tsS+MI1vCWGZd~M}G||?0 zrnF00Tu`Q42~(jtKRh@MO%A%+JBiuE(5Ee_gkRBiBoe9Jqgg4P6@A|N&cWSsyD`I& zD6(+<<{MW^8D0~10-tn- zdetZ50}$e410NcA-@r!zx@2P=pbj2sisIr8Y;oU}@<%&&wpKkp&LnsWBYG>qH; MXdn-`YOFrze=xsqEdT%j literal 0 HcmV?d00001 diff --git a/utils/middleware/auth.py b/utils/middleware/auth.py new file mode 100644 index 0000000..921ebaf --- /dev/null +++ b/utils/middleware/auth.py @@ -0,0 +1,45 @@ +from functools import wraps +import jwt +from flask import request, abort +from flask import current_app +from utils.models.models import User +from utils.database.database import Database + +# Inspired by: https://blog.loginradius.com/engineering/guest-post/securing-flask-api-with-jwt/ [access: 16.11.2022, 18:33 CET] + + +def require_auth(f): + @wraps(f) + def decorated(*args, **kwargs): + token = None + if "Authorization" in request.headers: + token = request.headers["Authorization"].split(" ")[1] + if not token: + return { + "message": "Missing auth token", + "data": None, + "error": "Unauthorized" + }, 401 + try: + database = Database( + database_file=current_app.config["DATABASE_FILE"], logging_level=current_app.config["LOGGING_LEVEL"]) + user_data_from_request = jwt.decode( + token, current_app.config["SECRET_KEY"], algorithms=["HS256"]) + request_user = database.get_user_by_name( + username=user_data_from_request["username"]) + if request_user is None: + return { + "message": "Invalid auth token", + "data": None, + "error": "Unauthorized" + }, 403 + except Exception as ex: + return { + "message": "Internal server error", + "data": None, + "error": str(ex) + }, 500 + + return f(request_user, *args, **kwargs) + + return decorated diff --git a/utils/models/__pycache__/models.cpython-310.pyc b/utils/models/__pycache__/models.cpython-310.pyc index 62ec91e74d786ddeeaf893e1bcdc19e3ffca1ba2..8a7fa428c4483084c0047b06d14a97ef3034a3ac 100644 GIT binary patch literal 2067 zcmaJ?&u`;I6rQmi+i~L5O}o3WT7C+Fg0#tj8$zg}sAz?#R%+oe5;AV)HF4@6>5Nmh zRXJs^`xhW2IPO2hVXmBdMVtUFyl1Do(NfmdJkK}t#-8`RZ=TCA3>aR2<%{v}E@QtD zSijl`cChJR(MTqF#&RxrZV4;5g`GRX$y=huY0k>r+!J2z3%|xT`nE;8?mJnKcSNV| zx3X>?ijXr1mrV4aEnVo%HhyG3SxYV==s+aBCtPg8=B)qo)-Mb_Thb>4T(-dmM+Qs2 zv=Mc{LewR+bj0=-Oop=en8_Y&E^ToO@rH~LM>W2UcvJQf_iKDdZXK|}_7%p)1})?6 zmf0dNjQ60ZU;@gx2bD^Ti3#>f1?i;t63$KQFgeO#V41FhEUD76(9?8oyrX1%qTqPI zO*mGNR1iZkNejS%NWwTv6grmGnQ1GQTg$LZuE(5G2i!N;S~2`N@T;cxId3*xrR}t=G4+s5Xk!8g2mBbO_ee=}=iXUg%8pdTIalzQasq4$e z4z*ou`du`aY{ouk-*$emF0C2A``?GkzQwNe*#rf;h(4FEZ+PWbV=ugPAF!qq5z<2{xWTeZ)BRNF%T9a@;7d4*~{NvgGK-P(e5>d8j8q-0yP>ybv;KB_fX^B~-TF4mb) z2H5Y(4l1UrXs@*r>NxeGBE_m(Xh=%#qDW5{peU^L4~{ciG)n$BuI>lRsT56K!gp$*W}-&1(X5x0htXlH?d6{e;?Z#+kM_&<2!g( z2lxMM4{`MkY*Ur6>nefVHZ0?_Egj^mWgI#kqP3tiayYQmCceak$)YOL0t;l0rEPx@ zyqXl_(Q>S54KY5UT8QC1(fa#R$(Ro6jbVR?-}{Kdrt?E0>v122rf7VB@S35Ln`C$} z^YgVVPy!UmOyS>kvbctBN9liEYYz(vKas;NltIVx1qk)tArYfogTW0jyz zTHRCWV`rF|fIM2s6-?(+%W8HA{JSJCr1Zx8ai02u_kf z$L5$`ZtYxs*STPrLv&+v)a4iwbd`3lGR4phZ&+tU_wa}(Iz