From c2e7406b0055433fa935ec222d3828c25d44cf4c Mon Sep 17 00:00:00 2001
From: "cc02503@surrey.ac.uk" <cc02503@surrey.ac.uk>
Date: Thu, 21 Mar 2024 14:37:36 +0000
Subject: [PATCH] Firt commit for User Microservice

---
 User_MicroService_Group3/app.yaml             |   2 +
 User_MicroService_Group3/app/__init__.py      |  10 ++
 User_MicroService_Group3/app/config.py        |   0
 .../app/controllers/__init__.py               |   3 +
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 356 bytes
 .../changePasswordController.cpython-311.pyc  | Bin 0 -> 3885 bytes
 .../deleteProfileController.cpython-311.pyc   | Bin 0 -> 1360 bytes
 .../__pycache__/login.cpython-311.pyc         | Bin 0 -> 1151 bytes
 .../loginController.cpython-311.pyc           | Bin 0 -> 3422 bytes
 .../logoutController.cpython-311.pyc          | Bin 0 -> 1096 bytes
 .../signupController.cpython-311.pyc          | Bin 0 -> 2617 bytes
 .../updateProfileController.cpython-311.pyc   | Bin 0 -> 1994 bytes
 .../controllers/changePasswordController.py   | 117 ++++++++++++++++++
 .../controllers/deleteProfileController.py    |  33 +++++
 .../app/controllers/loginController.py        |  91 ++++++++++++++
 .../app/controllers/logoutController.py       |  21 ++++
 .../app/controllers/signupController.py       |  70 +++++++++++
 .../controllers/updateProfileController.py    |  49 ++++++++
 User_MicroService_Group3/app/index.py         |  42 +++++++
 .../app/models/__init__.py                    |  15 +++
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 571 bytes
 .../changePassword.cpython-311.pyc            | Bin 0 -> 5555 bytes
 .../database_connection.cpython-311.pyc       | Bin 0 -> 793 bytes
 .../__pycache__/deleteProfile.cpython-311.pyc | Bin 0 -> 2913 bytes
 .../models/__pycache__/login.cpython-311.pyc  | Bin 0 -> 4431 bytes
 .../models/__pycache__/models.cpython-311.pyc | Bin 0 -> 4492 bytes
 .../models/__pycache__/signup.cpython-311.pyc | Bin 0 -> 3576 bytes
 .../__pycache__/updateProfile.cpython-311.pyc | Bin 0 -> 4493 bytes
 .../app/models/changePassword.py              | 107 ++++++++++++++++
 .../app/models/database_connection.py         |  14 +++
 .../app/models/deleteProfile.py               |  59 +++++++++
 User_MicroService_Group3/app/models/login.py  |  80 ++++++++++++
 User_MicroService_Group3/app/models/signup.py |  69 +++++++++++
 .../app/models/updateProfile.py               |  86 +++++++++++++
 User_MicroService_Group3/app/run.py           |   0
 .../app/templates/index.html                  |   6 +
 User_MicroService_Group3/requirements.txt     |   3 +
 37 files changed, 877 insertions(+)
 create mode 100644 User_MicroService_Group3/app.yaml
 create mode 100644 User_MicroService_Group3/app/__init__.py
 create mode 100644 User_MicroService_Group3/app/config.py
 create mode 100644 User_MicroService_Group3/app/controllers/__init__.py
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/__init__.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/changePasswordController.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/deleteProfileController.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/login.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/loginController.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/logoutController.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/signupController.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/__pycache__/updateProfileController.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/controllers/changePasswordController.py
 create mode 100644 User_MicroService_Group3/app/controllers/deleteProfileController.py
 create mode 100644 User_MicroService_Group3/app/controllers/loginController.py
 create mode 100644 User_MicroService_Group3/app/controllers/logoutController.py
 create mode 100644 User_MicroService_Group3/app/controllers/signupController.py
 create mode 100644 User_MicroService_Group3/app/controllers/updateProfileController.py
 create mode 100644 User_MicroService_Group3/app/index.py
 create mode 100644 User_MicroService_Group3/app/models/__init__.py
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/__init__.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/changePassword.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/database_connection.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/deleteProfile.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/login.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/models.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/signup.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/__pycache__/updateProfile.cpython-311.pyc
 create mode 100644 User_MicroService_Group3/app/models/changePassword.py
 create mode 100644 User_MicroService_Group3/app/models/database_connection.py
 create mode 100644 User_MicroService_Group3/app/models/deleteProfile.py
 create mode 100644 User_MicroService_Group3/app/models/login.py
 create mode 100644 User_MicroService_Group3/app/models/signup.py
 create mode 100644 User_MicroService_Group3/app/models/updateProfile.py
 create mode 100644 User_MicroService_Group3/app/run.py
 create mode 100644 User_MicroService_Group3/app/templates/index.html
 create mode 100644 User_MicroService_Group3/requirements.txt

diff --git a/User_MicroService_Group3/app.yaml b/User_MicroService_Group3/app.yaml
new file mode 100644
index 00000000..ab488dfb
--- /dev/null
+++ b/User_MicroService_Group3/app.yaml
@@ -0,0 +1,2 @@
+runtime: python312
+entrypoint: gunicorn -b :$PORT index:app
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/__init__.py b/User_MicroService_Group3/app/__init__.py
new file mode 100644
index 00000000..e5da06c3
--- /dev/null
+++ b/User_MicroService_Group3/app/__init__.py
@@ -0,0 +1,10 @@
+from flask import Flask
+
+from app.models import login
+
+app = Flask(__name__)
+
+from app import routes
+
+if __name__ == '__main__':
+    app.run(debug=True)
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/config.py b/User_MicroService_Group3/app/config.py
new file mode 100644
index 00000000..e69de29b
diff --git a/User_MicroService_Group3/app/controllers/__init__.py b/User_MicroService_Group3/app/controllers/__init__.py
new file mode 100644
index 00000000..83fe4b03
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/__init__.py
@@ -0,0 +1,3 @@
+from flask import Flask
+from flask import Blueprint
+
diff --git a/User_MicroService_Group3/app/controllers/__pycache__/__init__.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5a4bfd8103bb4380305718ed59e96e027557a8a4
GIT binary patch
literal 356
zcmZvWy-EW?5XX1#5;Q_;3qiKMMhhDe5i}uo8i*kf7LN07l3TL3d(7Sj?nU$wByW>4
zq_q+oAzdoxKnuZPK7KRvADFjp_lS`V2cK|B^}T6+E%<@mDZwktSjIIg_>}X81L9yB
z5QifcwLThg#JBB%PTYc^bEiF&s7&<`h1>S58DmHyY*AXVU30L1>0QaO19UPe>NJ;+
z2KuO$Ap17;1(?doA#JTmv>Y2+pi@;X>`aV2BGj^HJvtB*iwk+1EfbSMCVF|IHJCX#
zp^TWovv`6uH&)xZ0w?d$`tm|1Whql@Dzqe~58_xERmJgHS?>?83!8ZjH`t*!IfXl?
W^c8Z>H|%)**Ej5B{h#9j-FyQ`G-u)f

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/changePasswordController.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/changePasswordController.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f2bccc2cdba24cef3aa5a38361740cb00752099f
GIT binary patch
literal 3885
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

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/deleteProfileController.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/deleteProfileController.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8e06212bf94edd278c153db45bf9c8cb26a0fc10
GIT binary patch
literal 1360
zcmah|&1)M+6rb5o$+De~RU_94?SgI09%=_#0xcyZwM$%R5`&Vuh=uJ&Gm_Wd4|Qf`
zsvtuSIp~l>>BTDa;FH_p9(rs3j8zcS?8y*%=uO2W2cPn06)RCLeeAw@^FDs_=J$4g
zotm0JAh(~M(lr^O=VEgv%4_4~F&KM@AcB1q;0g|;iWJBdIZ!GJ7JkWB1FfQABq554
zO!Wf^p+k6wQpwTWe*SFt_DU3@*6|<Ocs|h|qXS4g9Hmw!NUn^m{J+9uDQW%-zeyX+
z3*%JZ;!)_;TB*+H_f5*d!zt%p6k0gd2=!@9)2ZRQ&Z3&<(}%`#lT)@l=1i6KyXAXO
zqX#tJj0mreP6tD90sNqom!S4gjA3~#TO*s`1F#QA`(4yV?7R4kN66n27?}`hJL89a
z9jj+Ph>vo|@4t)Ncz=ZZCLbXpzjLP4mfDCYzeu}sTzHe&em75vr{0PxZ8ScEG9oI`
zJPfN&a$>decT!#O=6HmOX{IU-T+g>8CXm>qZ~=LoyLFl>Vbk{^gRzJ`ym%kV%rJ^g
zKdRR$F}={znI;P4I*plNAk~Jvr#bLAVyH|Pu!0dw9il75jos|DG(YSltVO9JOfE1?
zA*X+>d}fOSx$Oq6>ZW}+q^r!^q4sK2Z3Z-qxxEh2D0F@Meh2}^y|`sYHM87gjJE8R
zsL41rHzKxe-y}P3ScR5XHeKJRVV!d5-rS%M%zL!D8Afm;kMit5=eAd6QJJzGuS%U;
zENV7Bw%ta<u0~<ZA}EKR#y+~0QDCXjVmWbNp#(GhXHbvO3k{vS^klnh^`__h)ANsR
z9qZErbV<GXPvPQ|>)mgj73Pw{9Ap(Q_l>!pvCuabI;%&;nZ322*18+L;zGZ;(D`zp
zq08pcmAQc`zYq1GI$yn*K*d=AHs<@rd}lSo=zg+a>KRtwu#!m&ir)KRUrUU|WO5NU
z7iN;#rR3all3PB3=FlChkg7G`<=aer*V(ADSq?{A3?jHJUmCk{Hq<odIH4O*$4SqR
zMV$wYR0ZB*n(^>EVlx7`1nM;RIp8&YdYyd;Tk$jS4yb{QF+M`qlK*>-&|)(F92-}D
z{Iu)*_HEC&);9p*{4u`pH!eNHrDW!#r`n%CB)HVWH~RR-K$^u@2ME-EGLmlMF<0i#
GI(-EQ3|j;M

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/login.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/login.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ee02eac64b23cc7222f821324eb85aa9d76b8dc0
GIT binary patch
literal 1151
zcma)5%}X0W6rb6TY)nj3N}GC6S*aEmTcuS>DN<+?QK6`yMF<PB?oPhkk2td{M3Rz&
zhf)d+w9rcro-D=w0sSL-h{b~p2tw&Wda-!()R~R(qagJ0_RVkJd-J|#_H!Z;1B?bH
zexpGFfS-KRCg~I$ml*g6EMP$!I4}zxAuBjyR)kz9*pee>WrjsdvLlX?RUi-mQcBTw
zAWOC)dH7Y?Vi~sC*CH#r0k#<2ZYw~x!|Ip^TI`T(G?8{Zw*yqhMc1cFiFj@?SD^|<
zs{tau25BsZe6z3=5QGmQKLKgf_VPt{X}P=}83`ek=4R&?m_>1rU+^qqo@HY|JpGQp
zGr&58HQ-;cmw42WYOo47&nj<g`DzJU%xnAHQ}C5@d-Y$dSOrzF)SfI@31i}$mRJ=m
z>61{C{P=~_(&gCmz>@#ZPm9b@`N6}{vBy+Kj#0GNlP~yW)cL?fgyaHS6Zl97G4co}
zSjzR}1ou;muIXWnOkay&ndzy-Cr`yZ@^OUkW9fkSo`djo2J=2NnJQt5=?s-D!#Bck
zRN~h{6Bv=Q=MuEUErbVDIi0*uKha+@5271R#VqKvF3RBI8qzbK892!Gi9W}yo@?0p
zOP3iiDf$)F%drkvc@;hF1(+ap(ZehHGi%LoO=PL*f??ap%_GA4P#4j%x`51r>+z?6
zh(3wEpggJ@<+5&iu8%$D%qj>U%5b?t<q+Z9tV-T0S!JRQjv^qLs!#66Z@e9^XZAX;
zzngk9)mYr=?Ah(?sZach-)f+pc=v9+yPi2vt~L5UjQmjgno8f^ow090vulF!>%@LC
z)u`<x2X>PK&FH|v)uv;X6wGKbD(7s2tYH2|!$G&MBjI=!vdM63X<Z4x{8ytgYtKhv
z`CkC;;^$IKoJ7Z&b6}&VxR-7DOC_(EI1(X*d*FWaYTg6=&C7fMQq9YJ0F(8ujowCd
h^U>yD6Atabp<Ot1BqZS7Bf!KT5eWA#X+m{a-(RDLCEWl3

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/loginController.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/loginController.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0ae33a0fab843db2a609b147bf8a5d6eaea25f24
GIT binary patch
literal 3422
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

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/logoutController.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/logoutController.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fef5e24b0dc447c671daa0656ba2d91c90e66b0a
GIT binary patch
literal 1096
zcmb7C%WD%s7@tY9k38B+Us4sj(iWOSAK(i_3ff{7wJoF%2n$QPGfB4H-H9{1#T1nw
zf*yM4tvU8ok$Uhik*)Ml_EeA_yhVyodU9sd1bg&j_nY5*Gv7DA?>F<gqay{l>EF-r
z83f>`n6xZ$0ZwZi>;ME1w1ETj(23<^PCOrX68VH9<t0bX%Mio>hA4)Wy%+%d{BK%b
z#p-UdHT!o&ag->*uhQlHNd5r!__qD_)_e*nIgnL<iAYuslaFm5SE%KBp|Zw^YZa@Z
zLh&mfGcQbtNT@K(n8krgF|sH&y->DEiTK{8GSLKKVqreFn1!L@V6RLNGusDpAX<;}
z|8$$X9pG_kTDI242<~yb-=4n(ZvY+hTC(wkHBlon6kCrZp#zs{wf7>3z-1vI5CT~+
z2ats1i%}6{R-FqKpJ8fPh>GhIJup@%;mz(Bq@?jSHRhWpj}?78lrW`)h6&fV?al5b
zo~OCQ)3^*Jj5N#5N>mX=;w9`+Ng%l?Nf@t?N*2-%9%G_Q?fl#H16@>LdcmohWqsbo
zGt}C^`V29B2fH5A7x*f13%0)G@&(E)ud0!vmh&maRehTHlwoa!&~^P0+9<dt=P+F^
z*fw@cm~lGV3SQL~u~~Krr)Xgo9ca9?OiFT?ZdfKZW-0M2xAj7$qMO9^DB<axQ}br0
z+mZ1~m5QeqIazdJa90C=WYE>WwO-F2bPgYO4%cRnmCgo8Ns}k(?yaf%@{jaTkRCe8
z^lUw^CwK20WJV7&qd{i$sPATQ>u%6{FUZ_)$e`~=y%_Y21euZJD_4VS<3ZO%piZ3f
zBfwlX9ZE&Jz}BgF0#w{{q%9RRBE6}~QK%Y*TX3*pgvlm*W3>`Wygd&`tiJ%-Co+1u
zJ69h%1o<|eqSyIU+z5NeT_X-5JOWRG|M@uoj{Z;2w#)U`&Hif1W0?9l_<nGEV0U@<
eX>ITTjvd0WMywM~HUM|O;~+MEDH4Svet!WT`XG-0

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/signupController.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/signupController.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d6315f975befa50cae416644dbce66638592358c
GIT binary patch
literal 2617
zcma)7&2JM&6rZ)%>s_xMJ0#90*iN9u20_(OXiE4{Nz?`;0#cwL*Q&MgPU210yYB27
z2y!Z`Lakd>Dnv-}frHgUN}E>Y*kk_$8|}dwsZykh12<QQ9yoPojUC%jTE^?Q@4flW
z%zMxCe*V$t^8hkt&-??^JOF=DqdC~u%8MU}vH@fuGb+e1aVF!4J2K9=GsDJNhWZ_<
zE5pS(TX(ANxSRN#Dj(<Vw-6T`05UQQJ(~^yw#c_J;vy8w-lo<5mR&Np#Qfs!#LN6W
zut{KBEoj^)3->_0M|RGGnCCh5$5<>}P;)Sg6wSo$Wkc7L#Z~M^@berrOw3YGjKRDH
zZzppGM01!klqD^fz3YCbp<wpvmHBG~<IX@ct;<HLbs$k_!JOp#;wnjG1DI`d%S_Xd
znH4+D`wZG=w!8o=x03HnWDVp&neMu4$c|02eyg>|8nY+T*@blMiDbKw&OMQ?E+o4r
zlIudc_C&h7ken&(q@C~H$DMb}{BR4f#uHm;vjt*%+H6mrDZ5(mHl?%TvbbW`8=cED
zc}L!vXY;N+m*?|B-XnV-32UP1+gZHqZt8ilD|)Zl+nfVn*R0R%Yn%0TuAK+6Pwr6|
z`|YRiSYQs(Vqh1{NQ#O*iwZK#q$Xt`7F4OJ@~WPaOhwl)w*)mABFtwc!?>*@8MA50
zNMqKJR1<p?6CxXEU=R}!Z8k*HLOoRYsR&R(Q$YKupy8r^BIxZm3~3484cf6pQj(_W
zW@G_IU?yv>VphwkYRrRZu`$<Z70fR|Gf7(vJBfw|NO&{?m~6(Ew8L{5CQ`D9qf1?K
zE|WD7tuUgT6YIgOESb`OM~eecOX)I{TRV5hFVOBz(w%S*jmYlyhRx-&#19Qxg-FME
z^<?^V;yPJqB&5u0DxJ8Z!5O67f{7VDmCHcQG!j?ItgcCF;<`pAkfE5X5q&W-pF;?)
zCZ_cqGGOF}j#d&M%C{sf1?9+eT2fW0EkPrqXptLmA#x3-(weU7OA0jX1Cy7P6w>D*
zx}~IG@?)guvL_N!Hk(N4nu&C>oW#^1sOgsHcy<*L-Uhay7sq&yFhv2p<N)u#_eE*o
zsXJVChlv>&wEW?!f6Vfa71>&#e}iA=OM}(Gm=zc+x@y7UjhpK?OKLTE)CwLgdTRYc
z8?)=PrBAE<F{?jT6l#5g8<XpkrAyVm!&cwnB46tbZVastm7>+&gI4dsBDV|i=jgjn
zqSetUYjmo@57qqPGH3Y@lhb#!;9F(Y3Z5u>w#C5rQ{PT~bN0Klr3+8RP(=*Yc`y>L
zg`%|sZ`bx8s*Oab9NJHxP_*9X8SbeAB8nGZj)2hkqxfT?dSJpjFj1T%=?;WSN;Md@
zg3;nf&-zA6ryiVtc)sEtuX7+6szlze^i5X0liS{4iK~d=3LAbwiU(3Hnk5FkoHo&0
zL?J}qHrGz{oh`k_$c{CK*+xLiEn1f;%{Kp4$(}o-lbR?YZ4%s83%llgGg6~O_D1B#
zKBE7auDR#5`<3!n4C!DaElr#}6?5)TfZb6s4!aGQLeMm@XzD9aOD?RE-ob9#$*Qt|
z#q7e0yf~3eXQUM78f}T4X?Q2bHi)IgDfWg2O^Y@iI!F{W+7urU#gK?7fM?=9OAM7z
zRUEg(@xsh@?_lB5Yv-NEL%)T84p(ERt=Q?`XZ|=+6)#)j<-!cPFXT#+YyH6U&{G?T
zyuRers=HY)R|gH@;?N;-O3aU4i-b~F5dDE{=CP@)K}x<1;TF|6-e|Z6IUS+6C=rBX
zX{vnECgx-k3k_IuA&Xt4aS7?#O-WPx3D~FExxV7hkZp4+Jcmw_DSDxdUx}zY8HTBW
z6P5paYGAz5`P4v9!Tz)<V!{59%U!&9KV7<0^+qjkv><FVp0C4ShVKuTKPk@^!d2#&
e#T=_Ujxv!tAmVQ)a2#)WK4W|gDcNper}Hm<#!-v_

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/__pycache__/updateProfileController.cpython-311.pyc b/User_MicroService_Group3/app/controllers/__pycache__/updateProfileController.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d12100ee3869119656505afbb8d537567f89b91e
GIT binary patch
literal 1994
zcma)6&1)M+6rYu}AChc2wxn2cEO%X7Nrarpq|kyJ0<GQHE;I=^se=#*MLUw#-Vb$l
z72+U64n63QLI?$m5E`A_kMxjR+y6ov7P<@+48@1uR7@!N)R|QzM=FL6yKmmi`^}s8
zIp2?t1^^kWza7J$SOET{i{9|PWsbfj%pQ<{#3(>zvW)7<dQ@-LtNOA&mCdpYm3b6S
z<+HrYdkHUO1qOHkWF#N-?|T4vN&fE024J8S?5*CNC063f%+LHFUJ||r`vmr~56zB9
z{tb`{{6%+CEcSn@)L<3Knu+->L)YZe4(1X3ss;@c`{)kl4QLp$uB8|ptW~9g3G+1r
zBC;GSL9<wKS9w`0>6q)vAC6=wBGX-A->sV)w+WnAp;^%-qu95GFg*Fa<Ug7xUhV;t
zIT3F4d5PI4{LB7&7t{gz$0Tv@jXD@YFecUfc9{Mi2S9yD*Wft@m~LLX_${t?PV#KK
zSwO#<@5Fzrf5%{ycRh7at8Z;j2c0GF;C;K^Q<1(Qr0-NDJA`CUMRG$(?o=c{gyid>
z?ydXkY@Ms~lJK0{70mGy&$jvzt_wpa{buw8_aA9sAU6S$$AOC90Fqw{$c#G&>6{w5
zfq7b9d09d<7np@=K~`{}BqPJjYXuczzf$P2f}$4-CaGV{m7yk)!sSqi97AK2oS}sJ
zfhH&k6GHSMq$BLpYKro3;tsh=)O1r+^l}+WqO7HYh~^!8%g{vBZ_K(KglOL*T9laU
zmO2&)Bu~2t(MrOsR8y-45(rO}P%E&%>k922AL*^a>1K726oW%lWw-C#Gqhw48Vm7c
z9RISsl%vKQxq`Y=tmJNLa0SWtVQxh))>NpOM(!4o>RLg`-O-2u8M3(}>Lqcbh7jDz
zE$cO8Kygz?+qqAq`vt8?++VH~6a{K!Xpl&VoA91^8x|{?PNE}2!@V&7g<M4X21NJe
zBFwKMy;l7oSEyEVMO`zIPL30sx^KfRq?cp`F82kOt2;RK_LZr2g-9fh(SRFq(o&DW
z8xD+}eZ1XFS)qA5H2-MzfDd&*l3hHE%(Ygn$bubNX!!pSM!zXPk*$zuheS)5wT0QX
zFnbuBczmt-<?G;FJ2*!aMb6pbIV+sB!^y^q6N&AuJzZ;VT9Kq3Nj5%n;)xfrXR+3T
z70=l5OyhGWHvK|)CbZ63u}gOBQe)kjJh%7Y>4R3lnoQf1>BgE9jqlxkdbe4zq8IGw
zg~s(x03_y}_>41i(Mg<lrsth0u`|lYiOGaC*55?H%=^!?KlrW06+3aIaf4WOcD5C_
zqG>ytZd^YMPc=VmePo5xb~xQ0Nq0C9oo<%e;beOxd2nX3J$1P~mT3!_BN8ESBQ=WI
z5-I*|L?6|YigfF*TecBZm!M)?9>{=Oligw#@@^01^LTtP5&3&n%#v)Hq#=m%9|4-B
zcf3c)v2c}Wtts#tx=5Dv=`+3~q~m26#sOE`|L=3aLVNIYz+!vwJBTEntT!vI2UcX!
wju7ei0W<MC6MN0XnlrD?zlyb)n8hsF%u>gbVir4qkiWga^YOrryY1TlFXPVRGynhq

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/controllers/changePasswordController.py b/User_MicroService_Group3/app/controllers/changePasswordController.py
new file mode 100644
index 00000000..516ca01a
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/changePasswordController.py
@@ -0,0 +1,117 @@
+from flask import Blueprint, jsonify, request, session
+from models.changePassword import check_old_password, set_new_password
+import hashlib
+import secrets
+import hmac
+
+change_password_bp = Blueprint("change_password",__name__)
+
+@change_password_bp.route("/user/change_password", methods=["POST"])
+def change_password():
+
+    user_id = session.get("user_id")
+
+    if user_id:
+
+        if request.method == 'POST':
+
+            #User data from front end
+            data = request.get_json()
+            email = data.get("email")
+            old_password = data.get("old_password")
+            new_password = data.get("new_password")
+
+            new_encoded_password = generate_password_hash(new_password)
+            new_password_hash = new_encoded_password["hash"]
+            new_password_salt = new_encoded_password["salt"]
+            new_password_iterations = new_encoded_password["iterations"]
+
+            
+            old_auth = {
+                "user_id" : user_id,
+                "email" : email,
+                "password": old_password
+            }
+
+            #user_old_auth = check_old_password(old_auth) #Collect user data from database
+            
+
+
+                
+            old_auth_info, value = check_old_password(old_auth) #function returns certain columns collected from database
+
+            if value == 1: #if user exists in database
+
+                old_password_hash = old_auth_info.get("PasswordHash")
+                old_password_salt = old_auth_info.get("PasswordSalt")
+                old_password_iterations = old_auth_info.get("Iterations")
+
+
+                #password authentication
+                old_password_info = generate_password_hash(old_password)
+                is_correct = verify_password(old_password_info, old_password, old_password_salt, old_password_iterations, old_password_hash)
+
+                if is_correct == True:
+
+                    new_auth = {
+                        "user_id" : user_id,
+                        "email" : email,
+                        "password": new_password,
+                        "hash": new_password_hash,
+                        "salt": new_password_salt,
+                        "iterations": new_password_iterations
+                    }
+
+                    new_auth_info = set_new_password(new_auth)
+
+
+
+                    response_data = {"message":"Password is correct"}
+                    return jsonify(new_auth_info, user_id)
+                
+                else:
+                    response_data = {"error":"Old password is incorrect", "email": email}
+                    return jsonify(response_data)
+                
+            else:
+                return {"error" : "Email does not exist"}
+            
+        
+        return {"error" : "null"}
+    
+    else:
+        return {"error" : "User not logged in"}
+
+        
+
+    
+
+
+def generate_password_hash(password):
+    # Generate a 16-byte salt
+    salt = secrets.token_bytes(16)
+    # Define the number of iterations
+    iterations = 100000
+    # Generate the hash using PBKDF2-HMAC-SHA-256
+    hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, iterations)
+    
+    # Return the salt, iterations, and hash, encoded in a way that can be stored in the database
+    return {
+        'salt': salt.hex(),
+        'iterations': iterations,
+        'hash': hash.hex()
+    }
+
+
+def verify_password(stored_password_info, submitted_password, salt, iterations, user_hash):
+    # Convert the stored salt back to bytes
+    salt = bytes.fromhex(salt)
+    # Use the same number of iterations as when the password was hashed
+    iterations = iterations
+    # Hash the submitted password with the stored salt and iterations
+    hash = hashlib.pbkdf2_hmac('sha256', submitted_password.encode(), salt, iterations)
+    
+    # Compare the newly generated hash with the stored hash
+    # Convert the generated hash to hex for comparison
+    
+    return hmac.compare_digest(hash.hex(), user_hash)
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/controllers/deleteProfileController.py b/User_MicroService_Group3/app/controllers/deleteProfileController.py
new file mode 100644
index 00000000..c74dfe1f
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/deleteProfileController.py
@@ -0,0 +1,33 @@
+from flask import Blueprint, jsonify, request, session
+from models.deleteProfile import delete
+
+deleteProfile_bp = Blueprint("deleteProfile",__name__)
+
+@deleteProfile_bp.route("/user/deleteProfile", methods=["POST"])
+def deleteProfile():
+
+    user_id = session.get("user_id")
+
+    if user_id:
+
+        if request.method == 'POST':
+
+            #User data from front end
+            data = request.get_json()
+            email = data.get("email")
+
+            user_info = {
+                "email" : email,
+                "user_id" : user_id
+            }
+
+            user = delete(user_info) #Collect user data from database
+            
+
+            return jsonify(user, user_id)
+        
+        else:
+            return {"message" : "null"}
+    
+    else:
+        return {"error" : "User not logged in"}
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/controllers/loginController.py b/User_MicroService_Group3/app/controllers/loginController.py
new file mode 100644
index 00000000..31313b3f
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/loginController.py
@@ -0,0 +1,91 @@
+from flask import Blueprint, jsonify, request, session
+from models.login import fetch_user
+from models.login import fetch_password
+import hashlib
+import secrets
+import hmac
+
+login_bp = Blueprint("login",__name__)
+
+@login_bp.route("/login", methods=["POST"])
+def login():
+
+    if request.method == 'POST':
+
+        #User data from front end
+        data = request.get_json()
+        email = data.get("email")
+        password = data.get("password")
+
+        
+
+        user = fetch_user(email) #Collect user data from database
+        
+        #User authentication
+        if user is not None: #If database found matching email the user entered
+
+            user_email = user.get("Email") #User email from database
+
+
+            if user_email == email: #Checks if email returned from database is the same as what user entered
+                
+                auth = fetch_password(user_email) #function returns certain columns collected from database
+
+                user_hash = auth.get("PasswordHash")
+                user_salt = auth.get("PasswordSalt")
+                user_iterations = auth.get("Iterations")
+
+
+                #password authentication
+                password_info = generate_password_hash(password)
+                is_correct = verify_password(password_info, password, user_salt, user_iterations, user_hash)
+
+                if is_correct == True:
+                    session["user_id"] = user.get("UserID")
+                    response_data = {"message":"Login Sucessful", "email": email, "session" : session["user_id"]}
+                    return jsonify(response_data)
+                
+                else:
+                    response_data = {"message":"Email or password incorrect", "email": email}
+                    return jsonify(response_data)
+
+                
+            else:
+                return ("Email does not exist")
+            
+        else:
+            response_data = {"message":"Email does not exist", "email": email}
+            return jsonify(response_data)
+    
+    return {"message" : "null"}
+    
+
+
+def generate_password_hash(password):
+    # Generate a 16-byte salt
+    salt = secrets.token_bytes(16)
+    # Define the number of iterations
+    iterations = 100000
+    # Generate the hash using PBKDF2-HMAC-SHA-256
+    hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, iterations)
+    
+    # Return the salt, iterations, and hash, encoded in a way that can be stored in the database
+    return {
+        'salt': salt.hex(),
+        'iterations': iterations,
+        'hash': hash.hex()
+    }
+
+
+def verify_password(stored_password_info, submitted_password, salt, iterations, user_hash):
+    # Convert the stored salt back to bytes
+    salt = bytes.fromhex(salt)
+    # Use the same number of iterations as when the password was hashed
+    iterations = iterations
+    # Hash the submitted password with the stored salt and iterations
+    hash = hashlib.pbkdf2_hmac('sha256', submitted_password.encode(), salt, iterations)
+    
+    # Compare the newly generated hash with the stored hash
+    # Convert the generated hash to hex for comparison
+    
+    return hmac.compare_digest(hash.hex(), user_hash)
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/controllers/logoutController.py b/User_MicroService_Group3/app/controllers/logoutController.py
new file mode 100644
index 00000000..c7ff97bc
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/logoutController.py
@@ -0,0 +1,21 @@
+from flask import Blueprint, jsonify, request, json, session, redirect
+
+
+logout_bp = Blueprint("logout",__name__)
+
+@logout_bp.route("/logout", methods=["POST"])
+def logout():
+
+    user_id = session.get("user_id")
+
+    if user_id:
+
+        if request.method == 'POST':
+
+            session.pop("user_id", None)
+            return ({"message" : "Log out successful"})
+        
+        else:
+            return {"error" : "null"}
+    else:
+        return {"error" : "User not logged in"}
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/controllers/signupController.py b/User_MicroService_Group3/app/controllers/signupController.py
new file mode 100644
index 00000000..3876e7a8
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/signupController.py
@@ -0,0 +1,70 @@
+from flask import Blueprint, jsonify, request, json
+from models.signup import new_user
+import hashlib
+import secrets
+import hmac
+
+signup_bp = Blueprint("signup",__name__)
+
+@signup_bp.route("/signup", methods=["POST"])
+def signup():
+
+    if request.method == 'POST':
+
+        #User data from front end
+        data = request.get_json()
+        email = data.get("email")
+        first_name = data.get("first_name")
+        last_name = data.get("last_name")
+        location = data.get("location")
+        gender = data.get("gender")
+        password = data.get("password")
+        encoded_password = generate_password_hash(password)
+        hash = encoded_password["hash"]
+        salt = encoded_password["salt"]
+        iterations = encoded_password["iterations"]
+
+        if email.strip() != "":
+            
+            # Create a dictionary from user data
+            user_data = {
+                "email": email,
+                "first_name": first_name,
+                "last_name": last_name,
+                "location": location,
+                "gender": gender,
+                "password": password,
+                "hash": hash,
+                "salt": salt,
+                "iterations": iterations
+            }
+
+            # Convert to JSON
+            json_user_data = json.dumps(user_data)
+
+
+            update = new_user(user_data) #Send user info to database
+
+            return jsonify(update)
+        
+        else:
+            return {"message" : "email cannot be empty"}
+    
+    return {"message" : "null"}
+    
+
+#This function encrypts the user's password
+def generate_password_hash(password):
+    # Generate a 16-byte salt
+    salt = secrets.token_bytes(16)
+    # Define the number of iterations
+    iterations = 100000
+    # Generate the hash using PBKDF2-HMAC-SHA-256
+    hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, iterations)
+    
+    # Return the salt, iterations, and hash, encoded in a way that can be stored in the database
+    return {
+        'salt': salt.hex(),
+        'iterations': iterations,
+        'hash': hash.hex()
+    }
diff --git a/User_MicroService_Group3/app/controllers/updateProfileController.py b/User_MicroService_Group3/app/controllers/updateProfileController.py
new file mode 100644
index 00000000..faedd619
--- /dev/null
+++ b/User_MicroService_Group3/app/controllers/updateProfileController.py
@@ -0,0 +1,49 @@
+from flask import Blueprint, jsonify, request, json, session
+from models.updateProfile import update_user
+from models.updateProfile import fetch_user_info
+
+update_profile_bp = Blueprint("update",__name__)
+
+@update_profile_bp.route("/user/update", methods=["POST"])
+def update_profile():
+
+    user_id = session.get("user_id")
+
+    if user_id:
+
+        user_info = fetch_user_info(user_id)
+        print(jsonify(user_info))
+
+        if request.method == 'POST':
+
+            #User data from front end
+            data = request.get_json()
+            email = data.get("email")
+            first_name = data.get("first_name")
+            last_name = data.get("last_name")
+            location = data.get("location")
+            gender = data.get("gender")
+
+                
+            # Create a dictionary from user data
+            user_data = {
+                "user_id" : user_id,
+                "email": email,
+                "first_name": first_name,
+                "last_name": last_name,
+                "location": location,
+                "gender": gender,
+            }
+
+            # Convert to JSON
+            json_user_data = json.dumps(user_data)
+
+
+            update = update_user(user_data) #Send user info to database
+
+            return jsonify(update, user_id)
+        
+        else:
+            return {"error" : "null"}
+    else:
+        return {"error" : "User not logged in"}
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/index.py b/User_MicroService_Group3/app/index.py
new file mode 100644
index 00000000..32fd79e7
--- /dev/null
+++ b/User_MicroService_Group3/app/index.py
@@ -0,0 +1,42 @@
+from flask import Flask, redirect, url_for, request, render_template, make_response, session, abort
+from flask_cors import CORS
+from flask import jsonify
+from controllers.loginController import login_bp
+from controllers.signupController import signup_bp
+from controllers.updateProfileController import update_profile_bp
+from controllers.changePasswordController import change_password_bp
+from controllers.deleteProfileController import deleteProfile_bp
+from controllers.logoutController import logout_bp
+
+
+
+app = Flask(__name__)
+CORS(app)
+
+app.secret_key = 'Group3'
+
+@app.route('/')
+def index():
+    return render_template("index.html")
+
+
+@app.route("/hello/<int:score>")
+def hello_user(score):
+    return render_template("hello.html", marks=score)
+
+
+app.register_blueprint(login_bp)
+
+app.register_blueprint(signup_bp)
+
+app.register_blueprint(update_profile_bp)
+
+app.register_blueprint(change_password_bp)
+
+app.register_blueprint(deleteProfile_bp)
+
+app.register_blueprint(logout_bp)
+
+
+if __name__ == '__main__':
+    app.run(debug=True, port=5000)
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/__init__.py b/User_MicroService_Group3/app/models/__init__.py
new file mode 100644
index 00000000..d55ce4a0
--- /dev/null
+++ b/User_MicroService_Group3/app/models/__init__.py
@@ -0,0 +1,15 @@
+from flask import Flask
+from flask_cors import CORS
+
+
+#from app.models import models
+
+app = Flask(__name__)
+CORS(app)
+
+#db = sqlAlchemy
+
+#from app import routes
+
+if __name__ == '__main__':
+    app.run(debug=True)
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/__pycache__/__init__.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..dfb0366dfbe4ee46a4cd5603bac50bd5dcb0efcf
GIT binary patch
literal 571
zcmZWlF>ezw6n>6<O%o+z429(emMko62qB?Fgoz^3s#0Xhx}IN?Q+#%0=PIQOS5!eq
zm{^%W2!2dJ4AG4+A(lwpI$=XQL_EFc_xXF@v!DI3-EM-n7yaM(!{?u2b8YkrT)gt&
z9Y~NwK~6@51YA?KoQ^1g8X!UTfdG8=@y|w)XDLRTECFPaPHRD9Z({U*>q@?nB>VDT
zpWGTkh;IE?&~`}`JywaEdcb<S&xh5v5P6bmA@)K|;$bm<+O1d7QBc|NlB)R^i_}<W
zSs;9mPI45YqRDJlQCsLwa1qYGeA~Ov_Z?ctlYEg*_^!sj&5n`xO<Lrr=Z-(~RihKd
z_q8urm(3TkIf{pcwYcCtQ&@-bfw5EmNFFCTMH%-diBhP?=;BPr2Y49oVLH)9nQ?}W
z53DI>_qd;h=SHG(T!>6(b0O}|7MI%(JXt7wXm9ul!%w@pU)GcmvVzWX(^qhNx#{aB
z)LSK<KRGpLrlc!iB`b%gjk8ACShs++&QHG4oh98_vHI)5%fXvF<=`vpd}p2IwXZ3#
KTV7$?{^CFEX_?Ld

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/changePassword.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/changePassword.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3e2f696425d98b4acece898d09560e3b644ec81a
GIT binary patch
literal 5555
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

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/database_connection.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/database_connection.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ee658c793e4a505d7b70e54b3c82b148e4f6561e
GIT binary patch
literal 793
zcmZWnJ#Q015Zya}J93N>h_8a{z{1ebVI1kO1BpUHuww$zN!I#yv5%a0kKMZ<8(VTg
zNsq)w3qt$>egdVDD6FfH5Cs*M+@)gHaY7Jtx;O9b?Cidg_CqF<Mi8$Tf77QLLO+x^
z41G?fr+~ad1QE?eJBa8n(2hp58p=n0sVy7!eB&&o03+~E9|Ay^Hh_+SMj`{9L<bQP
z>!UY_#QPdxqOSuc`w_s@yVM}+gNMU-a>V=5_rO0LX}CGP5hlxR2Y2u;4zqPhMPnT^
z+@c-I{9dNKvTClIYi6R;wc8=;U8q!7A1qf(&ujPZ8Z|2Rs2CJ$%T=}3OBXBVmU+vp
zEth(+Vtuuu(&jd#v&AhDNS~5MnKMRh-{Gv(rLvgU!?@Swq-lo<`=FGMg>kR}Cx=Ob
zecZ&7hRFby814Y`u$0fZAYpFa0B1F%FC5mAF__s<vH!Mw!&1{o3oGl^Jw_|S*`rp4
z+ku)*TANVi47*mHK|x5z?;8BEQ455iU8~FkA*r#=#ja(NJ<M!MjB*>hE@dq$4Tl-q
zv}tTnyUn=ETMm`h9l-<dx`jQ@>Tp6`X&nyG`0MqW*A3Hi*&t1k1<%U2^Z<tFd*;mW
z_Bd+{SH{_k3Ub4hNfe!1(?7>2NaX|ka{0I#J;MLUws%|}@KN;i&xPE}rP28-Ul$7B
z77C+iVG4Jmye<-uW==jLaYFG$fc@l67$b1$k~j%cJsWumU=q<ZZHzL***8h1w5t>J
IKg<sL1L^+WwEzGB

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/deleteProfile.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/deleteProfile.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..11cd5e31a86ac49992cc243db920bc089e02298a
GIT binary patch
literal 2913
zcmcguTWcFf6rPo|(nywN%a;UOcDzZP5+%N%hCnWEg0U4RG_lh-A;cAk_3kL%c(tp}
zu3}5bA(TF-A&|5fQW^?=N?r2O{)Lju>&gf$77B*ahrS6yz~rfCWZAOi1d2;Knw>qj
zIp;fPF4~_P8+`~`a&?{j=tk&I#%wl6m3Y$!#1kYVnNv}co8mY|J5<M%1Kv*6nRHFL
zK<4@eP4Tj05{3D{+0-y+d+r#zrX(`sK>H+J(}-lo<!Onlx@IpP9w$6+&be3^FEY1j
zpMl~zJR5C+%W+HFw3~8->g*gj0Nb&pUT^~M*v7kL=K`N|EN!N^Wyy#fpL0C}&GRiS
zhrpI$+|}yhx^r&o&ADaQwpbo5BJ;9a;c^bz27VyR-EF5Ih{w@($n{^@PNGR9dlv8q
z^T9b!eLgZ?@P5$VyW1YHuyxwi>T%0n+4pfXJ&a6$4aObMCf$puxZpE`n><2tL(caU
z{p5HCJLdV;u3@!Z^46?s)UI53*{^Vt;}&f91>Zg2M_s>4ggMS^tKoT1MvebDqrm^2
z(Hxq0-a>QSVK_q{XaCQk%^2aPahoSeQBiGA+8{Kp$l1tb^m26Mx^M&dOQS-9>PbPK
z)(03LH^pg{2sbZAuSKf{p9$wFJNGsprBtWc0J9S`-4qgfT9dO!N5S3osBq!h#FdJl
z;j}q(NlWPUUb4sQEk6)ZfRMH)Nen~0O|o6Xk_3TF!AMII$P#H)%?L74iAm&a=covf
zMS}>0p%WCXsyZWN13Puu-WwX3Pr-#t<f^qUNofk)_F2vKR^bN9ZXMeVwuVk^51A)Y
z+9Wnk5L24bHDdFUsv86>^kh;oZFef8!<|lXrEDpxXr_&+uBy|bG;4dK^Abs!imrtl
zY?lo9xBdx0M%mvFb+dt;WILe9acPD~v+=Legl24<X3IqNIor*sOQUxCMlIqZ)LntP
zR}F(zam9XPE=P<8@F~>VyXBEHF}4gwOiX5^nb?FzMyYa_#71=~og|uR#IAx?*F-gT
zLjwgh6f+~}31Ko#Daph}bf^mK7@f|>hUL4WCP6(%W<*sb+HGR6(%vM~!gV6eXu7K3
zR)|pv7{8)ORG%dDt|F267}e9M6EQKBiY0XbZp1dwU!{6NQOQ6mW4kvbv<os|g*ASI
zU3njsT@k+LulAnrVvDi7uM`Ze1`n+S4;6yF#b9sVz1H0J_~v3`o-eiRdz@Ju%zMgi
z)Om%=2TC~bDDWWg_}<c70S^}OpoIrZtsPI!e}BHv+FNYx&EvI()-rN>2TSeUKZuK8
z<}c(gthI%#?tZIvpge^9EoH=cLnVL9qstF2e>?tgJU?D)XlKHnl7HW-ziY+cRq!7u
z`VUx@UUq_}d=?#?;4Iu-1z_#(TTT@4$s#^!;ge;Iy2nA=v86q_{7C^via287NZF6P
zt*f|W1$Pv1sE9)r4y`qJSY2nVrnBYFJtA6v8-ke+hagwJuQvRF8?C^=as&qGwHo1;
zRUBHup#ttM;%=5m^M0%InALRL!aI7od9Q%h*Vo?$ksnIw<Oga)1<|Qrzpw(QpcnAz
zB0g>5)1~(#>a&{qExe<{+V5@A0ML3l2w*CNfA3z53D~+{5BH4*(eGWu9(cV7HjN!~
zz7WFEA?Hgk2lPvyYpfr=9BKsml{Y+g#QEw|CVzE;$zLDgfqs3=$>{#Ui(SsJ+vXFh
zXv|XfMMj%ousb)7(Ez(%*!38%ervKDhTUeBWAqDp10<p$7~bI_n37h>IeHLS_H|%<
k4g>62j$1<=*3Mo+jrS|R5{g(mdl{eLddg_`Kn3vk4=g0DJ^%m!

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/login.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/login.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..54f0eb17fc5e099f4eaf6dcc17f1775c07a610e1
GIT binary patch
literal 4431
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
PZSp=hgzeqLJ;Of$v-#2z

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/models.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/models.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0c5497a917a5f33bfe0edde28b561ef47b6a7caf
GIT binary patch
literal 4492
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

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/signup.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/signup.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..94a888ae05aa3787387431d65168edf553a0a2cf
GIT binary patch
literal 3576
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
JFQ6f?_a7koS7`tM

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/__pycache__/updateProfile.cpython-311.pyc b/User_MicroService_Group3/app/models/__pycache__/updateProfile.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..43ec1e62b7e96678f2be3c7811088ea64c8e1774
GIT binary patch
literal 4493
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
Z5&hVzuO)X6*Hc1OGR_@i?cKz2{vX%f`gZ^T

literal 0
HcmV?d00001

diff --git a/User_MicroService_Group3/app/models/changePassword.py b/User_MicroService_Group3/app/models/changePassword.py
new file mode 100644
index 00000000..18d40df2
--- /dev/null
+++ b/User_MicroService_Group3/app/models/changePassword.py
@@ -0,0 +1,107 @@
+from flask import jsonify
+import pyodbc
+from models.database_connection import connect_db
+
+
+
+def check_old_password(data):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        email = data["email"]
+        user_id = data["user_id"]
+
+        
+
+        # Check if the email already exists
+        email_check_query = "SELECT COUNT(*) FROM dbo.User_table WHERE UserID = ?"
+        cursor.execute(email_check_query, user_id)
+        count = cursor.fetchone()[0]
+
+        if count == 0:
+            return ({"Error" : "Email does not exist"}, 0)
+        
+        else:
+
+            query = "SELECT t1.Email, t1.UserID, t2.Iterations, t2.PasswordHash, t2.PasswordSalt FROM dbo.User_table as t1 INNER JOIN dbo.AuthInfo as t2 ON t1.UserID = t2.UserID where t1.UserID= ?"
+            
+            cursor.execute(query, user_id)
+
+            row = cursor.fetchone()
+
+            columns = [column[0] for column in cursor.description]
+            user_data = dict(zip(columns, row))
+
+            #connection.close()
+
+            return (user_data, 1)
+    
+    except pyodbc.Error as e: #more error handling
+        print(f"Database error in check_old_password: {e}")
+        connection.rollback()
+        return {"Error" : "Database error"}
+    
+    except Exception as e: #more error handling
+        print(f"Unexpected error occured in check_old_password: {e}")
+        connection.rollback()
+        return {"Error" : "Unexpected error"}
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
+
+
+def set_new_password(data):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        email = data["email"]
+        user_id = data["user_id"]
+        
+
+        # 
+        select_userID_query = "SELECT UserID from dbo.User_table where UserID = ?"
+        cursor.execute(select_userID_query, user_id)
+        UserID = cursor.fetchone()[0]
+
+
+        # 
+        update_authinfo_query = '''UPDATE dbo.AuthInfo
+    SET PasswordHash = ?, PasswordSalt = ?, Iterations = ?, TempPlainText = ?
+    WHERE UserID = ?'''
+        
+
+        cursor.execute(update_authinfo_query, (data["hash"], data["salt"], data["iterations"], data["password"], UserID))
+
+        connection.commit()
+
+
+        #connection.close()
+
+        return {"Message" : "Password updated successfully"}
+    
+
+    
+    except pyodbc.Error as e: #more error handling
+        print(f"Database error in set_new_password: {e}")
+        connection.rollback()
+        return {"Error" : "Database error"}
+    
+    except Exception as e: #more error handling
+        print(f"Unexpected error occured in set_new_password: {e}")
+        connection.rollback()
+        return {"Error" : "Unexpected error"}
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/database_connection.py b/User_MicroService_Group3/app/models/database_connection.py
new file mode 100644
index 00000000..8bad5678
--- /dev/null
+++ b/User_MicroService_Group3/app/models/database_connection.py
@@ -0,0 +1,14 @@
+import pyodbc
+
+
+#Connect to database
+def connect_db():
+    
+    server = 'Chiamaka'
+    database = 'User_Management'
+    username = 'CHIAMAKA\amych'
+    password = ''
+
+    connection_string = f'DRIVER={{SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password};Trusted_Connection=yes;'
+    
+    return pyodbc.connect(connection_string)
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/deleteProfile.py b/User_MicroService_Group3/app/models/deleteProfile.py
new file mode 100644
index 00000000..7972b969
--- /dev/null
+++ b/User_MicroService_Group3/app/models/deleteProfile.py
@@ -0,0 +1,59 @@
+#from app import db
+from flask import jsonify
+import pyodbc
+from models.database_connection import connect_db
+
+
+
+def delete(data):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        email = data["email"]
+        user_id = data["user_id"]
+
+        # select user id from database
+        id_check_query = "SELECT UserID from dbo.User_table WHERE UserID= ?"
+        cursor.execute(id_check_query, user_id)
+        user_row = cursor.fetchone()
+
+        if user_row:
+            userID = user_row[0] 
+        else:
+            return {"Error": "User not found"}
+        
+        #delete from authinfo table first because of foreign key constraint
+        delete_authinfo_query = '''DELETE FROM dbo.AuthInfo WHERE UserID= ?'''
+        cursor.execute(delete_authinfo_query, userID)
+
+
+        #delete user info from user table 
+        delete_user_query = '''DELETE FROM dbo.User_table WHERE UserID = ?'''
+        cursor.execute(delete_user_query, userID)
+
+
+    
+
+        #commit changes to database if no errors
+        connection.commit()
+
+        return {"message" : "Account successfully deleted"}
+    
+    except pyodbc.Error as e: #more error handling
+        print(f"Database error in delete: {e}")
+        connection.rollback()
+        return {"Error" : "Database error"}
+    
+    except Exception as e: #more error handling
+        print(f"Unexpected error occured in delete: {e}")
+        connection.rollback()
+        return {"Error" : "Unexpected error"}
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/login.py b/User_MicroService_Group3/app/models/login.py
new file mode 100644
index 00000000..6e344a76
--- /dev/null
+++ b/User_MicroService_Group3/app/models/login.py
@@ -0,0 +1,80 @@
+#from app import db
+import pyodbc
+from flask import jsonify
+from models.database_connection import connect_db
+
+#Function to get user info
+def fetch_user(email):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        query = "SELECT * FROM dbo.User_table where Email = ?"
+        cursor.execute(query, email)
+
+        row = cursor.fetchone() #fetch data
+
+        columns = [column[0] for column in cursor.description]
+        user_data = dict(zip(columns, row))
+
+        #connection.close()
+
+        return user_data
+    
+    except pyodbc.Error as e: #error handling
+        print(f"Database error in fetch_user: {e}")
+        return None
+    
+    except Exception as e: #error handling
+        print(f"Unexpected error occured in fetch_user: {e}")
+        return None
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
+    
+
+
+
+
+def fetch_password(email):
+
+    try:
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        query = "SELECT t1.Email, t1.UserID, t2.Iterations, t2.PasswordHash, t2.PasswordSalt FROM dbo.User_table as t1 INNER JOIN dbo.AuthInfo as t2 ON t1.UserID = t2.UserID where Email= ?"
+        
+        cursor.execute(query, email)
+
+        row = cursor.fetchone()
+
+        if row is None:
+            return {"message" : "Email does not exist"}
+
+        else:
+            columns = [column[0] for column in cursor.description]
+            user_data = dict(zip(columns, row))
+
+            #connection.close()
+
+            return user_data
+    
+    except pyodbc.Error as e:
+        print(f"Database error in fetch_user: {e}")
+        return None
+    
+    except Exception as e:
+        print(f"Unexpected error occured in fetch_user: {e}")
+        return None
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/signup.py b/User_MicroService_Group3/app/models/signup.py
new file mode 100644
index 00000000..71474133
--- /dev/null
+++ b/User_MicroService_Group3/app/models/signup.py
@@ -0,0 +1,69 @@
+#from app import db
+from flask import jsonify
+import pyodbc
+from models.database_connection import connect_db
+
+
+
+def new_user(data):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        email = data["email"]
+
+        # Check if the email already exists
+        email_check_query = "SELECT COUNT(*) FROM dbo.User_table WHERE Email = ?"
+        cursor.execute(email_check_query, email)
+        count = cursor.fetchone()[0]
+
+        if count > 0:
+            return {"Error": "Email already exists"}
+
+        
+        #insert data into user table
+        insert_user_query = '''INSERT INTO dbo.User_table (Username, Email, First_Name, Last_Name, Tenure_Months, Location, Gender)
+VALUES (?, ?, ?, ?, ?, ?, ?);'''
+        cursor.execute(insert_user_query, (data["first_name"], data["email"], data["first_name"], data["last_name"], " ", data["location"], data["gender"]))
+
+
+        UserID_query = "SELECT UserID FROM dbo.User_table WHERE Email= ?"
+        cursor.execute(UserID_query, email)
+        UserID = cursor.fetchone()[0]
+
+
+        #Insert password into authentication table
+        insert_authinfo_query = '''INSERT INTO dbo.AuthInfo (PasswordHash, PasswordSalt, Iterations, TempPlainText, UserID)
+VALUES (?, ?, ?, ?, ?);'''
+        cursor.execute(insert_authinfo_query, (data["hash"], data["salt"], data["iterations"], data["password"], UserID))
+
+
+    
+        
+
+
+        
+
+
+        #commit changes to database if no errors
+        connection.commit()
+
+        return {"message" : "New user info added successfully"}
+    
+    except pyodbc.Error as e: #more error handling
+        print(f"Database error in new_user: {e}")
+        connection.rollback()
+        return {"Error" : "Database error"}
+    
+    except Exception as e: #more error handling
+        print(f"Unexpected error occured in new_user: {e}")
+        connection.rollback()
+        return {"Error" : "Unexpected error"}
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/models/updateProfile.py b/User_MicroService_Group3/app/models/updateProfile.py
new file mode 100644
index 00000000..0c70bedb
--- /dev/null
+++ b/User_MicroService_Group3/app/models/updateProfile.py
@@ -0,0 +1,86 @@
+#from app import db
+from flask import jsonify
+import pyodbc
+from models.database_connection import connect_db
+
+
+def fetch_user_info(id):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+
+        query = "SELECT * FROM dbo.User_table where UserID = ?"
+        cursor.execute(query, id)
+
+        row = cursor.fetchone() #fetch data
+
+        columns = [column[0] for column in cursor.description]
+        user_data = dict(zip(columns, row))
+
+        #connection.close()
+
+        return user_data
+    
+    except pyodbc.Error as e: #error handling
+        print(f"Database error in fetch_user_info: {e}")
+        return None
+    
+    except Exception as e: #error handling
+        print(f"Unexpected error occured in fetch_user_info: {e}")
+        return None
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
+
+
+
+def update_user(data):
+
+    try: #error handling
+
+        connection = connect_db()
+        cursor = connection.cursor()
+        
+        user_id = data["user_id"]
+
+        #insert data into user table
+        update_user_query = '''UPDATE dbo.User_table
+    SET
+        Username= ?,
+        First_Name= ?,
+        Last_Name= ?,
+        Location= ?,
+        Gender= ?
+    WHERE
+        UserID= ?'''
+
+        cursor.execute(update_user_query, (data["first_name"], data["first_name"], data["last_name"], data["location"], data["gender"], user_id))
+
+
+        #commit changes to database if no errors
+        connection.commit()
+
+        return {"message" : "Profile updated successfully"}
+        
+
+
+    except pyodbc.Error as e: #more error handling
+        print(f"Database error in update_user: {e}")
+        connection.rollback()
+        return {"Error" : "Database error"}
+    
+    except Exception as e: #more error handling
+        print(f"Unexpected error occured in update_user: {e}")
+        connection.rollback()
+        return {"Error" : "Unexpected error"}
+    
+    finally:
+        if cursor:
+            cursor.close()
+        if connection:
+            connection.close()
\ No newline at end of file
diff --git a/User_MicroService_Group3/app/run.py b/User_MicroService_Group3/app/run.py
new file mode 100644
index 00000000..e69de29b
diff --git a/User_MicroService_Group3/app/templates/index.html b/User_MicroService_Group3/app/templates/index.html
new file mode 100644
index 00000000..6207c520
--- /dev/null
+++ b/User_MicroService_Group3/app/templates/index.html
@@ -0,0 +1,6 @@
+<html>
+    <head></head>
+    <body>
+        <p>HELLO</p>
+    </body>
+</html>
\ No newline at end of file
diff --git a/User_MicroService_Group3/requirements.txt b/User_MicroService_Group3/requirements.txt
new file mode 100644
index 00000000..6da6fc6e
--- /dev/null
+++ b/User_MicroService_Group3/requirements.txt
@@ -0,0 +1,3 @@
+Flask==3.0.0
+gunicorn==21.2.0
+boto3==1.29.0
\ No newline at end of file
-- 
GitLab