From 84f416f6b06d6f5c6d836d2ee106354d02ae9e49 Mon Sep 17 00:00:00 2001 From: Abdulrahman <abdulrahman2.ali@live.uwe.ac.uk> Date: Fri, 29 Mar 2024 23:56:22 +0300 Subject: [PATCH] Update AIEngineer model and admin functionality --- mlaas/__pycache__/settings.cpython-310.pyc | Bin 2637 -> 2697 bytes .../ai_engineer_auth.cpython-310.pyc | Bin 0 -> 1148 bytes mlaas/middleware/ai_engineer_auth.py | 28 +++++++++ mlaas/settings.py | 1 + .../__pycache__/admin.cpython-310.pyc | Bin 331 -> 974 bytes .../__pycache__/backends.cpython-310.pyc | Bin 0 -> 795 bytes .../__pycache__/forms.cpython-310.pyc | Bin 704 -> 823 bytes .../__pycache__/middleware.cpython-310.pyc | Bin 0 -> 1228 bytes .../__pycache__/models.cpython-310.pyc | Bin 2099 -> 2171 bytes .../__pycache__/urls.cpython-310.pyc | Bin 701 -> 725 bytes .../__pycache__/views.cpython-310.pyc | Bin 4854 -> 5902 bytes prediction_service/admin.py | 16 ++++- prediction_service/forms.py | 10 +-- .../0009_aiengineer_is_authorized.py | 18 ++++++ ...9_aiengineer_is_authorized.cpython-310.pyc | Bin 0 -> 593 bytes prediction_service/models.py | 2 +- .../templates/prediction_service/login.html | 51 +++++++++------ .../prediction_service/register.html | 15 ++--- prediction_service/urls.py | 4 +- prediction_service/views.py | 59 +++++++++++++++--- 20 files changed, 160 insertions(+), 44 deletions(-) create mode 100644 mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc create mode 100644 mlaas/middleware/ai_engineer_auth.py create mode 100644 prediction_service/__pycache__/backends.cpython-310.pyc create mode 100644 prediction_service/__pycache__/middleware.cpython-310.pyc create mode 100644 prediction_service/migrations/0009_aiengineer_is_authorized.py create mode 100644 prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc diff --git a/mlaas/__pycache__/settings.cpython-310.pyc b/mlaas/__pycache__/settings.cpython-310.pyc index f788d33ee151854c64446ae4eca1f0ed4bd8ade1..b40f363086c9c9309b27a33e6a79f41a8a3dc175 100644 GIT binary patch delta 94 zcmX>r(kaT9&&$ijz`($uDbJq9DYTK#n3<7lvJ>-JL#y1J#KdB~+{~1eoYeBfqEx-a t%=py2^vt}})S~#r(vl24M^9HM-?6kLWAaUA`OV5K_gNWvCo^+-0RY|R9LoRz delta 40 wcmeAaJuAYO&&$ijz`(!|XTz4(BDj&yn3<7tvJ>;!&E71ZSs8gI+jDsV0JpmdjQ{`u diff --git a/mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc b/mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1366c37d9f748f5ce6c1aaf8ec1d9ecd4d7f2b0 GIT binary patch literal 1148 zcmd1j<>g{vU|^^fW=|_(VPJR+;vi#Y1_lNP1_p*=Ck6(F6owSW9EM!RC`LvQn<<AW zmpO_V%x2DE$z_dV1+!Ul*mBvU*clnz8B$nN*jgA;*qWK5I8xYy88kUwf=t(Byv0$J znvz+Rnp~pEc#FL#wJf!$I8~GJ7E5SxYLO=6Ep8AUP?VpRnUk6f(t?bcV2+YuU|>jP zh+<4(h+;}%Okrwah+<A*PGM<bh+;`$4Q9|}yCvc1>6(|GnU|Vc<XBpg;hUL~l9O7V zSd^L!G6iNThz-KdAg_W#q=vDEA)X<HA(%mv(NB}{7EgL=NqkXiaY24wajGWMEtcZc zoU|f#1_p+e3`Lv_3=F?C^%DyU^mB6(6N~k8;kM`}X2z#N?T=3^Ey>U;sJz7yAD@|* zSrQ-50kRHcFBfB#A})vO!BnHTn1z9X0i+%5;syo=h8o5!h7!gU#%9KBrXs!?h6PMD zj0+iSnQEAV8A_OI7*m*<nTjlH7_(TiSc@#H#7o$+*t0l5{1oP1##-hY<}A(>mTaaX z-5TaBu43I1?iAK$#&CvUhH!>FE*6Fowk)1X3q}SIjAY1TEN4KqLzB&~iqF@_(J@%J zC^bE^xFogc7E38OHj8)|7#MDGBLzhjH$-JletKq}Chsklg2a-HB2Z!jhv_Z$jKt!^ zl9D2bPJzr~aM-2hm1HI-mZYW>v4RX_&rixqO)e?E#hjj6a*L%XKPUATFH~uMQD#+Y zN)ae*Z}GU~rxyF=m$+7B7MEzU6oG;bl;#RcQ;SPL2@w*jw|GFVjW2*CI&h>y2vB+e z#aVJ<PELG0Hz>|P36GDFi;0C%h>3|&fKdR%Zs22NVPg8n#lnI=HX-KtX|jS0%}dNp zjgP;@6(66QpHi9wV)Mku7nUaGKxB$Q_7zDoFhG(S#6_GSF34F$Yzzzxpj224VsJ2U zF!C^i#r!lmZwaJiCFZ5)>lJ6@7nLNJmJ~yRgBvPbT9i`^4)R-4P?6;Pypp2KBt39C z&CO3q%_#;I3Jg(_1)$uTT#}ie7hjxORF;{Xst1(^#RS+!B$vURcZ<UY;ww8wP^f`i K%)<zQLQDY54jqgD literal 0 HcmV?d00001 diff --git a/mlaas/middleware/ai_engineer_auth.py b/mlaas/middleware/ai_engineer_auth.py new file mode 100644 index 0000000..6921cf0 --- /dev/null +++ b/mlaas/middleware/ai_engineer_auth.py @@ -0,0 +1,28 @@ +# ai_engineer_auth.py +from django.shortcuts import redirect +from django.urls import reverse +from django.contrib.auth.models import User +from prediction_service.models import UserProfile + +class AIEngineerAuthMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + if request.path == reverse('MLAAS-register'): + # Skip authorization check for the registration page + response = self.get_response(request) + return response + + if hasattr(request, 'user') and request.user.is_authenticated: + try: + user_profile = UserProfile.objects.get(user=request.user) + if user_profile.role == 'ai_engineer' and not user_profile.is_authorized: + # Redirect to unauthorized page or perform other actions + return redirect('MLAAS-login') + except UserProfile.DoesNotExist: + # Handle case where UserProfile does not exist + pass + + response = self.get_response(request) + return response diff --git a/mlaas/settings.py b/mlaas/settings.py index 1d82798..a74d4fa 100644 --- a/mlaas/settings.py +++ b/mlaas/settings.py @@ -45,6 +45,7 @@ MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django_session_timeout.middleware.SessionTimeoutMiddleware',# middlewear to delete current session after specified time SESSION_EXPIRE_SECONDS 'django.middleware.common.CommonMiddleware', + 'mlaas.middleware.ai_engineer_auth.AIEngineerAuthMiddleware',# custom middlewear that checks if user is authorized to view page 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', diff --git a/prediction_service/__pycache__/admin.cpython-310.pyc b/prediction_service/__pycache__/admin.cpython-310.pyc index c1504645d10a35ba7f6aa3cedaa99ecc4c2bf5dd..50aa0f37e655a4e3cbe61002b4008c38c3a1f044 100644 GIT binary patch literal 974 zcmd1j<>g{vU|^WDoGtAz69dCz5C<8vGB7YWFfcF_H!v_Tq%fo~<}l<kMlmunq%fs0 z=P>0mM=^uhEICZMEKw|AHfs)3E^8DkBSR`<7TW^$ROW?@a5gIvn+3#9VM<}kVanx* z;sB{xz@EynkkOqXg*}C%g&~C_l`)I6nYo!UiYtXPm_d{4CCF`>jJH@5Q*tx&UNSN; zFlaK~VhPAEF41JX#T{ClS`<)}pO%@Es>yhZ-PgxAKP5Fslkpapqo-?LdS+f~YEd%C z2xQCz^P&+014Al96k`fQ6jKUg3R5~$6mtqwI%5<|3UdleI#U#D3Tp~m3quqe#CcKd z5J%nON0{yia@Q@E(&E&jTfCXY@rk7+8Tmz-RjDbr1QH7hit@`+<5Qt7xy4_Unw6Sd z0vAYTMsgR34Z_Y03=E$I7#J98n6el^&gun)K0`2rCbM72O2#5k{H<iX#a3F7l30?u zlKB=(acWN5E%u_+!qU{@l3N^wrKv@g#i=DL8Hz+17#Myj=qDBw=ob{Frer3UWaj6^ z7pE4LWhSTUgTqv>pt6XYfq?;}^fM@E1Q@Fn(EO)|?h~92FX9Eo5VN0K5g!8sLlHlS z5Cjn*<H61;5(9C07#J8NKn!sP28Jqmbo<c4$xoBx7Ds%1USe))eEco0`1suXl+qj! zn<qZLurx6TD#MeLSzHpIl384klUR9+8_Y|~%qdANy2YLd_IokduSFp1A+AAl7Y73a z1IW?EAQc=8987GC9E==HJj_KP89z<#D87`e#Ju!;z2yA7lA_F{B2bXsV#@`kyW%1i zke5JNsECb$f#DWQab`*CEsmnp^vvRt)S@DGkRTU0je^q+*idZlxW!=u@uD3l#TSb( UFfi~i@GycQE0|>BV3J@200r9SRsaA1 delta 116 zcmX@dews-;pO=@5fq{V`&W0_GgOP#ZF^GeVnHd-u92giFiX$d!N3gO5Gib6;++fP= zr^zwdk=cfGB|{NNe-YQ@4~(jcw>WHa^HWN5QtcQ)TKE_k7<d?X7{QR0hf#nL05iT4 ANB{r; diff --git a/prediction_service/__pycache__/backends.cpython-310.pyc b/prediction_service/__pycache__/backends.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f347b86d68c7846d63dc5aa6f3fd08b19c2af62e GIT binary patch literal 795 zcmd1j<>g{vU|`UdV^51=Vqka-;vi!d1_lNP1_p*=9R>!56owSW9EM!RC`Lwx6s8pB z9Hw06C}u_mcZL*}6xJ4o6xLM6X67iC6t-XnP4<@{b2J%m@%ZMaq~<s!CTFMSrMzTh zU|`T>yv60{>6(|GnU|Vclnhdbj6rsS_{DMz3=F9ZQH&`JQA{Z;?F?y*AX{5FqnO(n zSQw&Mf*CYfZ}B>p7MJAbLe2L}hUo^Gz|O$Hz{<eDzzy<&4+8^32}3hO7Gn)#8e<Jp z4RZ?P9HttUC5(NHwX8L)DGa5IMJhF{Sxi~XDNNZ+MJgpMS*%%XAdwX2UdCFs8n!I< zVwDtzV1^pjU<OSVKTW1v9HqsnMR|$2skb-^5{rw=^NUh$aVKWRr$T+F$#{zeq(qbB z7He^7L2A)0p2X6UjMTi6%;dz9)LYyj$%3N%w9K5;TP#KSIjKb;AKYTkPs&P7E-Ajn zoSs^8i#M}49;7Y5D6=XxMU(v&OL1yW+Aa2?)WXu#;*ugZ1_p*AkZ*6XWtS%wr56`* zf<!nN7#LPE-r|gpPtHj!E{>01$?!{AKe3=dzn~~JB{R7sGe0lBIJKxOGdWd12@*ra zdIgn5pa25}Trm#=1A`Q!2$KLK8zT!N3saR8N^t9e90l`>CX=6^ChIMZ_;^rw#K+&_ zijU9DPbtkwjgP;@6CYn#nwSHT0h@n|7wW9!)SR67_#!coi@}5lh$RjpKyCm9M=^-t zU=U+00*QcZkx9u)%uCPLOU}<LDauR&J46rWg(4;f28LT~xuAqs3=U7QJ|ru^_JFLo W#bE<+qa7$^7J~wkhk=Jtgb4umg2o~M literal 0 HcmV?d00001 diff --git a/prediction_service/__pycache__/forms.cpython-310.pyc b/prediction_service/__pycache__/forms.cpython-310.pyc index 65ce3999e709adc67bd43d6741df0fb5ab8029d8..799a389ced0edd5b3172d0368cacc42516d299b5 100644 GIT binary patch delta 441 zcmX@Wx}A+TpO=@5fq{X+WFlMI=83!kjLZ|`q@@Hxi&Kl7i&7IyGV}A?@{4jc8E>(G z#F8fpO4ge(FfgPtL@}l?L@}i@FJM{75XG9xoW+*Hn8K9Kl**jNp2FPA6vg4rkiwF} z+QN{++RPNinZg##pvis<Y;;g+dS-D+Y7y9Irduqf#i>O_EDQ_`noLpLiJ9@KdFh#X zsi{R(+>V|Ku27C9(=GPojQmXQ<kaF@Y~`6L>8T|Xp9L_oPBv#$XS>Bxl%JD2IgU|7 z24v7J*4+G*)SO#vX_=`xDa9)pii8;$7>a}^FJiP77G+>y@YCcf;sXisg9w4i9~ebb zKp}C9+c_gYGda}_r0*7YP-04EesF3|YH~>tFGwXwFVrj$7i_8sh{ejlzyQL<91IK$ z91I+cB8);zMIaGBP4-)CDOrhm>G?%WlQWs*8JQ=0FezAo+zD2I&AeM2Ho5sJr8%i~ Sj0_A6U_*Hrco=yYMVJ6I3uy`f delta 352 zcmdnac7T;PpO=@5fq{V`&W0`R@<iSMM%IaO()BE%#i>P_jJE_pv~y8vVo7Fxo?CuV zZZb$MGG=CAU~phyU?^5%U|>jPh+<4(h+;}*Ucj=DA&S+VA%!u8sf8hhshKH?ErmIl zL6ZeyW>9K+W^qYs5mqyqCVMd2F|tf<XH=iOg;7HWWXCPm-29Z(oLg*ZnW;G`#VZ+# z_!$@&iufo0V6@H_WME+M(_}9K`J{*&B+dgOm>3usZgIKhCT8ZifpitIgG51!p_)Nl zurUH47Ape-0~^RIAcBK|gHed72qfmG$$pD1B`Yy6J->))@_i-+M&`-;ndGHdV45&Y Ln=HvJ%g77>KsrQu diff --git a/prediction_service/__pycache__/middleware.cpython-310.pyc b/prediction_service/__pycache__/middleware.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3a3ac86bb3d10e26b2aedf08e11f03b7a7b2656 GIT binary patch literal 1228 zcmd1j<>g{vU|<Md&z3fynStRkh=Yuo85kHG7#J9e%@`OMQW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qX#8T-GR7Mh16=6xI~B7KRkIW~L~%6!u^SO^%l!6EzucaTKMdWEQ0+ zmuNEH;&sf+&#TPMFD(u&PAz)L$iTp$$#{#)(bF|AJu@#gwI~^+2^llNoT9?Oz>vxi z#hAhn#gxLB!qmbL#SC&n3quqO#PTRsh{d<W9ZO3x@{2O75=%1k^L#T?QgTwu6N^%l zL59H$2eCoe8RSn;aMUo?FvK&YFa$HKWb|9fc#9`JwIseMwYVTZuQ*kc=@v_IYED`a zCj$e+N`@kC1_p*-s``lq1^NXb|0RQLiZ4zrD$7hx)z5`nsaH^Wiz7ZhGcU6wKAs(9 z706C5#wrCIZq$P*MsX}CLO>YoSUv^@h8l(i3^j}k8Ectpn1UIKKqeP)fI^eG2;`Sr z>_w@CrK!awpwNf-0PJK4!Nb770CH7wVopwcJV<>p3j+fK7b6Q^cR`dVv%*4<fq{XI zfq?;JE!bT-Aa^llF=R0o8I&;9FlI5NFg7z48G%??%vmfcOxa9DCRM^EtXXVX>>$w; z=3d5H)*99<j$)+}&J>nr#&CvUhH!8surQRcW^q;OGctf+Bv`B*OoE~agf&_HZm|~> z<)>xlq~79A%#2TkCL&G7TP&r;sYO-XzCMnQ!MZv5>6v+&+(p75e+y(5$0wGSWTfVm zWF{w;q^8_r&qypzEGa1}5(LS!6y@in7J)o@i#<OnD>b>K_!e_|YRN5Ls76r2N=+#O z#p5j=m;BUXzx)!{ip=5?O*U}Y7lGpE7H3&zYI%HGX<l*^gqc{BUL3^@7R@dPaf*Z( z7$6A=DOPw2it>|Fi;Lqy3PA=Hi!d-SC^0fI3NW%Uaxt>~=VM}HWcttZyGjLD3PLu* zPm>K4(|L)xsqyi*xZ>k;^HWN5Ky04)_`=e}9EeO2FUTzdAVLO2fRZ=FRbUn<!4!ew z8ib2M5zfKD!N|eP!vYrd(`3ITkdl>{m!7XzoRMEtl3ZF+3<)49sBm(AUP)1Ak{&4J s^>Xu5Qge!nKneO58<YbIaIj%W*23++#bE<+w;ia&06Tz(5d?*p0NjKvxBvhE literal 0 HcmV?d00001 diff --git a/prediction_service/__pycache__/models.cpython-310.pyc b/prediction_service/__pycache__/models.cpython-310.pyc index 50c27cd026bc5a13998e1b7524438bade92f2ef0..86d32afbfa6cf15951ac4193cb4f909a2bd01b05 100644 GIT binary patch delta 391 zcmdli@LPa4pO=@5fq{Wx?{c;@|Bbx8OpKo=&t{q}D#gISAk4tP@R^N)fq{cTfKh<4 zNNVysW?5xP1_lOA)>~YTp00W6nR%(HMMdlk3=D278E>(tq^2d7=9El+$fP5~<CLGD zlbV?4mYJH962+TY9G_TPl96AOS(TbHS&><kUygx+L7ahsp-2`)$W5+el4X>cJcmhI zD1|AQL6f<N8zc@g+fQ@yTxL5#5MP>sfuWcM>?RS$$<8dTtVIe83=ESmvJ{9aF)%R5 zgXAG@=3$g#EK-^r#=1~NnSp`fWeUjQj77W*3=DonAa!7OYcdsafb3D2EX&rdrU7DV zf(TI%p~t|$aEmiIr!*bxi(4$kIi=}EGLz4-1&V`gi(=2s$<0qm&AG)~TvAkI0CI^U mvnZqXWFK~UM(xQt>?IPQkSqfE72+R|wjynaLXpWl9O?kdqEc-D delta 375 zcmew@uvvgNpO=@5fq{X6*MTj~awBgq6Jzn@*-W!VB^ekPgc%qZirE+#7&sUN7zG%M zBquLm6`35*%)#_oX7U^+>B$BxY$CU~96eq0(lhf?Q;Uk&85kJ+R&q@4W7e3Q%_1r+ z%fP@O&cML%nFVZ$2xE~f)C^8B83qOhP39tQ1_lO*z9KmW28PLs%%YPUSU6aV<UzcN zEUlck*i%x|5=(PRCQGvxh$=8JFo2|>4&z~zVk}aaynuC~nj!-O!^;$qsf<OuActr& z7OB8Y*JLW<0I^jjr?PbmsDqdqAVL&G=uTo6Wt5&Q#vUjRGCqnuHzzkgB{k<3b8$&g zkv_;Fip-*lS_}*f%Ahb20{e!C5d=Ay_!tEkg_wkxinJzgVK0#Yg<KKH;}EZb3@ifa NoUF(!GC71p9RS#tLeu~N diff --git a/prediction_service/__pycache__/urls.cpython-310.pyc b/prediction_service/__pycache__/urls.cpython-310.pyc index 02683f73fd283f2eac80e14d202a8d1914655123..3994335e1991fecedc1724a0dad612742ac43c45 100644 GIT binary patch delta 283 zcmdnXdX<$opO=@5fq{WxmjZj*)``5bj4LK;tJkM6rLg2M=dwkyF*2kwrm&{6X0c~+ zq_Cy1_cEq%q;U2!r!uB+r7~x6rf@@fJgIDO8QxUZEUqk$6h5$eey9q8ROT%16hSCY zD3v*jCq)>_6G>&x;!P0+@zU9&4Ea*Tf*CZ$UxHkw$#{#UAh9IlB_jg^gC^rG*0Rjh z@?uTKTim`rj*h|cIr-_Cc@sar7UjRiosyN9m!7XzT9i{<#KgeBP{cO*Bcmp35i0`& t!(=I@05&0zpwQ$3CSw^11_lNm1|CKpCLTsH7CsQk$j8LT$j8X>9RM<lK)L_` delta 259 zcmcc0x|fwVpO=@5fq{V`&W0`R@<d))#$^+=)$3CkQ&>`2v)HoOQ&>~jdKpvLQ#g8= zQyEh@Q<<|kQn;WzZmeo}QdzS&v)EI3!8-Y%YWY){v$#?Opgh4;<}B_MAt+Bcl{t$i zMFhl4XOH4dQ4kGg&=h+Ka+fCKEtZ1Bl8l#(3=9mKjJH_JGE>WoCo?g=7UjFeosyN9 zm!7XzT9i{<#KgeBP{cZ!iAi&^0aE~*Ac!kCxsAzKN{oSlfro*Ik%vi)nU6_~QH+s~ LiI0(wk>fi6x!5^n diff --git a/prediction_service/__pycache__/views.cpython-310.pyc b/prediction_service/__pycache__/views.cpython-310.pyc index 75ea0217cd183b744d09f743647419b2ebea4e96..3bf7b8c4c54e6585584a01ac3e09da23a139bd58 100644 GIT binary patch delta 2015 zcmeyS+NZ~t&&$ijz`(#TOOrj#Nqi!o43h)nM4kM4h7_h8=3JI27Dk2?mK4?;_FRrA z4ltWHhcj0oN+4G-N-$R_N{Epmg)fD_g&|5fg&{>CM<iD?N;Fq2N{o>q1=$RS6viBe zT*fHIT&5@{upFvdmK4DpPN;c8DZ*hb3{m1K3@IWx5>XOhS~5x!OiM*cgK3#u*(f=% zK_WTwQSvDaDWW+Fxr$MWP%)(_rBt>Qu@vzZhGxbn<rI-%22F{LUv4qhYck*B4lPbC z3Mk4?%gjl=#qOGy0^;A|a`be~OV7+pO)W}h1O*BdvoSC*fUq+I14Ho!1_p*2hAf5@ z#%!h{-x9_ehAgIL##+W2#s$m^8H#*r7#FZCWT<7TVa#G(z?Q<akg=8-%4S~3Sj$pU z&z{AR#aY8t!;-?%%T&u+!;-?9%~WJm!UYy*O=0V0WMs(WsbNWB&t@vJE8&KUbEI(g zGBGlg@GRi1VMyVsVV=#9!abLHAxMlbg{PS@m?4k3gt3{Sma&Ath9QMFg|CJ&ld+jO zm_d`@?-omde{jexj?$Fk)S|q^+|*kvMfo|YnoPG?N{dsAili7A7>cAB7#LPEf~i~F ziJ9@K(BN>>WP%9tW){aMmX>7X7iCtZrc{YICMV~Y=9MTU7o{eaq^2mO<rgXZVpRM! zxt7^fK;RZzZfZ$Jeo7HL$Z(0thnUr4L_tg*1_p*(Y!FRFVjvN55WxZxW-l&HPEIW@ zE@B1=F)=VOXtEXYf!K;50_4OZNe~O<;#)i*$Hx~yqH?kzi)6hrD3%l$7#O%1xfnSZ zIT(2uc^CzlIhX|)IT!^PMVL4knLe@!3NRLFfy`#Q#RKwCYF<fZa$-s9E!Ld;^vpa> z#v+i5P?7;F0|NsHgOkBL<YeGg!;r<efC(Jg^`I01;(%hCsf4+Pp@y-BDTSq%xt6(x zIfbE=vB;r@Ig2HW6&&s6C2U#jSxg`iP{h}=)Uaf66q}cDF5s$RNMQ#@E_VtCC~`}9 zY8Yymn?cddox%wgfvDm_R#jgDN*&zIOu-DAJbpzIppXIu*Da2M#Ny)e{Gt?1CP?_{ zf}~_YgbV`%LsfWWeyKuYQK~{-eu)AoNFZ^nP?E2Z2#yeil8jUZU!TOpV1?q!;*!){ zJ%xar)WqUch4RGA5^&TfrsURV=D~F*mSpDV=@o$@ql(Md$I&rZHzPkcwMy1AuPiYq zGerRud7!kYkYA(#bDmz6Y(Y_KN@g-hb9`}XQCVhksy;YY^fF3vb2Ryilt7LK`%DeQ z(gr0PZjf08MfvrhJPk?BpcpIyCAA_skTP)UVofb7$}fVXEgg_3IDxT35*R3)ion4F zPG#V*5dbLy6M|rCz}|=lJI4u>(m+OYfzuctBL@=?qlf?_8zT=R2O}2~2O|$Nh%PeN z?8)+xiP2=TA&>IpIQCXXtI2^pu9G!6EFmnm?I24WC$HnEV|1LX%c;j^4iQM?^kQ_J zyoS@5(Qz^(n}dKASeSu<;pGhwAuxF(rv`hGFIaRkBb&kGelAfqN03zXWJP{GHmJ-! zE(h*tkmw(fN;{C0PZWs%7eu@T5$8cNNpK<o!~z@i3ncpi#PtBN`a!G^5DS!OUcLlz zlP53aF;ab54ieo663E0PUV_c`oXp53!}Br?Bo8vZ$bRxdo?`ZwE5QPj=kQc==YW|Y zqbw&c<S7C3U;YR2<KX-vklvRGsQe-u1V0~S2!vk<VuI8c*-U0+Q<}V&pNFw%@+tn^ zJcgk7WXUf`%_~xwJW;@yQEl>3fmp`U$;yHntnCa83`vs%1Y_AiEKQZkn*|qmg3B&M zaRn+rZV9JkCFZ5)>m}#sl@w(r>49=i5hz6#fs>a3$P%Xf;-V@B28Jlsywco)%A)eg znL_e1m0*$Ff}9lNTg(BTK1Co071e><+dg@TkeVGRwgnh?n0Od@*uW$s6B8FB2Nw?u i52FYp2a|vV50e0+04TLFaY#UlI#6-P!N|nK#|Qu}so0JH delta 979 zcmeCv`=-j5&&$ijz`(!|XTz4pC^(T%hUo~yM4kLd-W0wThA4p)h7|rB!6-p6EfggL zriG(Kz_e(tSd=&;1DGulC6U6AB9J4QD-|UL6_bvVPGw6GOc82fXl9I(N#PG>&=lTW zz<7(XKA90@DHJm^Ffgz&FfceXFfbISFfcIGFk~^LFlI9qsh2R;Fk~?`GuATJFfL$T z$WWwK!?=KDAp;{r4PzGT0=5*Ug^aaKCF~10Y8X<OYnWy;q_E6oUdY7AP{NtQ+RPZt zkjGrY*vwGNSi)7qkiwS2Uc;El*lfTY%%I8PcZ(&!KRDzTM`>|tQC?zhYL$p%a&mrY zUWr0-QEFmIYKlTyev!g2M#ZYhYgkMLxNouLrj}&nrxdX>FfbH}PX5TEuFAr|z;KJb zxHLIAwYazl<dq^O1_lOA<|00jA_)*7Hd&EbSc9V|H9fPqB(+E$<WCU>1_mxBE=CR} z4kjKZ5k?M1reACv0?bA7n`JmYGBGMoZWL6WY{=cps5yBfr_1Eu+*S}4`^)VhGYuv; z^3*XJOybpJQ-km~a@zB}6lY*yc=;S6P|s`3XfSyrrvsZNMBpc{F`Es9xslUgauS~? zn*m6D^yH14;*%!`h{I+19JsweGJim-bz#yzo*=QmAmS~EI1iEygcJTC7TCaFAlVNf zt~rR+4`P90_oWPo`x3+rn#{;$r24WPB(M=A5P?a&Oah5nOy0;T!}Br?#0HsOq&Jz7 ztC;=eO0dA>e1S@~XbAJ2KqX`J<P5<&ZioQL?1agTTqOv8kv4)K2hs)MCxDn>!?h=G z<W!nGL70azaq?W@-8>4Q_+`m2NX;vfo}40L%qTl~hDa=9%H(e%8vJDp3=Ec_*bD*1 zCi7%NQQgT7qAZi+M3vY;a+<P}+e8<Lfg=1CQ+{z#CIbUQ6l-2-Zb4;H+T?sOdBqH{ zNNzz+it#Px08gJHkbOnDAm@M#C=viA9exg*-29Z%oK!ndwkg(_d{InXgoA}ch=Y-X Lkq3&InD`h00=DDQ diff --git a/prediction_service/admin.py b/prediction_service/admin.py index 640d4b8..97ce197 100644 --- a/prediction_service/admin.py +++ b/prediction_service/admin.py @@ -8,4 +8,18 @@ from .models import MLModel # Register your models here to the admin page admin.site.register(Post) admin.site.register(MLModel) -admin.site.register(UserProfile) \ No newline at end of file +admin.site.register(UserProfile) + +from .models import AIEngineer + +@admin.register(AIEngineer) +class AIEngineerAdmin(admin.ModelAdmin): + list_display = ['user', 'is_authorized'] + list_filter = ['is_authorized'] + actions = ['approve_engineer', 'reject_engineer'] + + def approve_engineer(self, request, queryset): + queryset.update(is_authorized=True) + + def reject_engineer(self, request, queryset): + queryset.update(is_authorized=False) \ No newline at end of file diff --git a/prediction_service/forms.py b/prediction_service/forms.py index 5385eef..c8a56a5 100644 --- a/prediction_service/forms.py +++ b/prediction_service/forms.py @@ -1,11 +1,11 @@ from django import forms +from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User -from django.contrib.auth.forms import UserCreationForm #django implemented registration - -class UserRegisterForm(UserCreationForm):# inherits from usercreationform and adds email to the form - email = forms.EmailField()# create the email field +class UserRegisterForm(UserCreationForm): + email = forms.EmailField() + role = forms.ChoiceField(choices=[('user', 'User'), ('ai_engineer', 'AI Engineer')], widget=forms.RadioSelect) class Meta: model = User - fields = ['username','email', 'password1', 'password2'] #place elements and email field in order \ No newline at end of file + fields = ['username', 'email', 'password1', 'password2', 'role'] diff --git a/prediction_service/migrations/0009_aiengineer_is_authorized.py b/prediction_service/migrations/0009_aiengineer_is_authorized.py new file mode 100644 index 0000000..2b0b747 --- /dev/null +++ b/prediction_service/migrations/0009_aiengineer_is_authorized.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2024-03-29 11:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prediction_service', '0008_post_slug'), + ] + + operations = [ + migrations.AddField( + model_name='aiengineer', + name='is_authorized', + field=models.BooleanField(default=False), + ), + ] diff --git a/prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc b/prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e847c26be1a72baa8ed5e9eba9cc5fa6cac72b88 GIT binary patch literal 593 zcmd1j<>g{vU|_hkoGonvBLl-@5C<8vFfcGUFfcF_t1&Pzq%fo~<}l<kMlt3xMKLil zxHF_Mr7*WJq%fy4W-&K2M=__c1T$!|z66<|$#jb=H#5B`u_QA;ulN>QZhlH?PH{3w z3K_G(EYM+KU`S<%VoYI(VoG65XN+P_WyxX%S&+(>#h${F!rIH2!q&^2&KSj!!XC_^ z$#IL*7iPXD(=DNbqSTbkWRPv~#i>PQnaQcQ_zVmTEaD6Di%a5*b4t^1aV2J^=A~!m zrKT3$;>|3MPb@9T$S=yQN=<RoWW2?mlA4xSnp2|5e2WY0+W5T0+|*kvV3IX0Gc_m0 zPm}W&M?6?OKK>S0e0*+xN@-4NeEcn*`1r!o#2k=X5HBUQAT=)~H7_|cwYZ3hfq~%` zhhs{L8_0|zW)PRhDL+3aH8Bq?bc-v$AQc)?D;bJJ7#JYLFK7M4f&zU^pXnn)R^PzD zz%m};v3L}J=@nEKf#MJp%*8?s3=A9$Ow26*Sy-7EnHaekS^jeT2h00uvfScK$x6&i l&(}*y0=pROPOv1xK@gTG$O9ZU5Wm|of|3Ww4gn@HW&q(!pb`K8 literal 0 HcmV?d00001 diff --git a/prediction_service/models.py b/prediction_service/models.py index 22fa64a..d3f147c 100644 --- a/prediction_service/models.py +++ b/prediction_service/models.py @@ -22,7 +22,7 @@ class EndUser(models.Model): class AIEngineer(models.Model): user = models.OneToOneField(UserProfile, on_delete=models.CASCADE) - # Add other fields as needed + is_authorized = models.BooleanField(default=False) class Administrator(models.Model): user = models.OneToOneField(UserProfile, on_delete=models.CASCADE) diff --git a/prediction_service/templates/prediction_service/login.html b/prediction_service/templates/prediction_service/login.html index 7263290..47be209 100644 --- a/prediction_service/templates/prediction_service/login.html +++ b/prediction_service/templates/prediction_service/login.html @@ -2,28 +2,39 @@ {% block content %} - <div class="container d-flex justify-content-center"> +<div class="container d-flex justify-content-center"> + <div class="row col-sm-4"> + <h1>MLAAS Login</h1> + <form method="post"> + {% csrf_token %} + <fieldset class="form-group"> + <legend class="border-bottom mb-4">Log In</legend> + {% if error_message %} + <p class="text-danger">{{ error_message }}</p> + {% endif %} + <!-- Add fields for username and password manually --> + <div class="form-group"> + <label for="id_username">Username:</label> + <input type="text" name="username" id="id_username" class="form-control"> + </div> + <div class="form-group"> + <label for="id_password">Password:</label> + <input type="password" name="password" id="id_password" class="form-control"> + </div> + </fieldset> - <div class="row col-sm-4"> - <h1>MLAAS Login</h1> - <form method="post"> - {% csrf_token %} - <fieldset class="form-group"> - <legend class="border-bottom mb-4">Log In</legend> - {{ form.as_p }} - </fieldset> - <div class="form-group"> - <button class="btn btn-outline-info" type="submit">login</button> - </div> - </form> - - <div class="border-top pt-3"> - <small class="text-muted"> - Need have an account? <a class="ml-2" href="{% url 'MLAAS-register' %}">Sign up now</a>. - </small> + <div class="form-group"> + <button class="btn btn-outline-info" type="submit">Login</button> </div> - + </form> + + <div class="border-top pt-3"> + <small class="text-muted"> + Need to create an account? <a class="ml-2" href="{% url 'MLAAS-register' %}">Sign up now</a>. + </small> </div> + </div> +</div> -{% endblock content %} \ No newline at end of file +{% endblock content %} diff --git a/prediction_service/templates/prediction_service/register.html b/prediction_service/templates/prediction_service/register.html index fab6ea9..ca1b2cc 100644 --- a/prediction_service/templates/prediction_service/register.html +++ b/prediction_service/templates/prediction_service/register.html @@ -8,14 +8,15 @@ <h1>MLAAS Register</h1> <form action="/register/" method="post"> {% csrf_token %} - <fieldset class="form-group"> - <legend class="border-bottom mb-4">Join Today!</legend> - {{ form.as_p }} - </fieldset> - <div class="form-group"> - <button class="btn btn-outline-info" type="submit">Sign Up</button> - </div> + <fieldset class="form-group"> + <legend class="border-bottom mb-4">Join Today!</legend> + {{ form.as_p }} + </fieldset> + <div class="form-group"> + <button class="btn btn-outline-info" type="submit">Sign Up</button> + </div> </form> + <div class="border-top pt-3"> <small class="text-muted"> diff --git a/prediction_service/urls.py b/prediction_service/urls.py index 154dbe9..e537584 100644 --- a/prediction_service/urls.py +++ b/prediction_service/urls.py @@ -2,12 +2,14 @@ from django.urls import path from . import views from django.contrib.auth import views as auth_views +from .views import MLAAS_login + urlpatterns = [ path('', auth_views.LoginView.as_view(template_name='prediction_service/login.html'), name='MLAAS-login'), path('register/', views.register, name='MLAAS-register'), - path('login/', auth_views.LoginView.as_view(template_name='prediction_service/login.html'), name='MLAAS-login'), # + path('login/', MLAAS_login, name='MLAAS-login'), # path('logout/', auth_views.LogoutView.as_view(template_name='prediction_service/logout.html'), name='MLAAS-logout'), # path('about/', views.about, name='MLAAS-about'), diff --git a/prediction_service/views.py b/prediction_service/views.py index 8883186..cfeffc6 100644 --- a/prediction_service/views.py +++ b/prediction_service/views.py @@ -28,24 +28,65 @@ def about(request): return render(request, 'prediction_service/about.html', {'title':'About'}) -def register(request): +from django.contrib import messages +from .forms import UserRegisterForm +from .models import UserProfile, EndUser, AIEngineer +def register(request): if request.method == "POST": - form = UserRegisterForm(request.POST) #fill whatever form we have with current form input - + form = UserRegisterForm(request.POST) if form.is_valid(): - - form.save() # save the user account to the db - - username = form.cleaned_data.get('username')# uses the data and clears it from form + user = form.save() + username = form.cleaned_data.get('username') + role = form.cleaned_data.get('role') + + # Create UserProfile + user_profile = UserProfile.objects.create(user=user, role=role) + + # Create EndUser if role is 'user' + if role == 'user': + EndUser.objects.create(user=user_profile) + elif role == 'ai_engineer': + AIEngineer.objects.create(user=user_profile, is_authorized=False) + messages.success(request, f'Account created for {username}!') return redirect('MLAAS-login') else: form = UserRegisterForm() - - # if metho is GET then return normal register page return render(request, 'prediction_service/register.html', {'form': form}) + +from django.contrib.auth import authenticate, login + +from django.contrib import messages +from django.shortcuts import render, redirect +from django.contrib.auth import authenticate, login +from .models import AIEngineer + +def MLAAS_login(request): + if request.method == "POST": + username = request.POST.get('username') + password = request.POST.get('password') + user = authenticate(request, username=username, password=password) + + if user is not None: + if user.userprofile.role == 'ai_engineer': + ai_engineer = AIEngineer.objects.get(user=user.userprofile) + if not ai_engineer.is_authorized: + messages.error(request, 'You are not authorized to access the MLaaS system. Please wait for admin authorization.') + return redirect('MLAAS-login') # Redirect to login page + + login(request, user) + return redirect('MLAAS-home') + + else: + messages.error(request, 'Invalid username or password.') + return redirect('MLAAS-login') # Redirect to login page if login fails + + return render(request, 'prediction_service/login.html') + + + import os import io import numpy as np -- GitLab