From 564ed8baaa3275ae372960ded18648da844f498a Mon Sep 17 00:00:00 2001 From: Eilert Tunheim <emtunhei@stud.ntnu.no> Date: Sun, 8 May 2022 18:44:08 +0200 Subject: [PATCH] Added login for admin and logout functionality, missing add- and delete user --- .../com/application/DB/Account_handler.java | 21 ++-- .../java/com/application/DB/Constants.java | 18 +++ .../GUI/PopUpWindows/LoginPopup.java | 105 +++++++++++++++++- .../com/application/DB/Account_handler.class | Bin 2783 -> 2964 bytes .../com/application/DB/Constants.class | Bin 1759 -> 2090 bytes .../GUI/PopUpWindows/LoginPopup.class | Bin 5697 -> 7674 bytes 6 files changed, 132 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/application/DB/Account_handler.java b/src/main/java/com/application/DB/Account_handler.java index 10dd3e7..2c05fa0 100644 --- a/src/main/java/com/application/DB/Account_handler.java +++ b/src/main/java/com/application/DB/Account_handler.java @@ -14,7 +14,7 @@ public class Account_handler { public static void getAccount(String username, String password) throws Exception { // Sqlstatement - final String sqlStatement = "SELECT Username, Admin, Phone_no " + + final String sqlStatement = "SELECT Username, Admin, Phone_no, First_name, Last_name " + "FROM " + PROJECT_ID + "." + LOCATION_ID + "." + USERS_TABLE_NAME + " " + "WHERE Username = " + '"' + username + '"' + " " + "AND Password = " + '"' + password+ '"'; @@ -30,14 +30,19 @@ public class Account_handler { if (row.get("Username").getValue().equals(username)) { LogoBar.getLogin().setText(username); setUserName(username); - } - - if (!row.get("Phone_no").isNull()) { - setPhoneNo(row.get("Phone_no").getStringValue()); - } - if (row.get("Admin").getBooleanValue()) { - setIsAdmin(true); + if (!row.get("Phone_no").isNull()) { + setPhoneNo(row.get("Phone_no").getStringValue()); + } + if (!row.get("First_name").isNull()) { + setFirstName(row.get("First_name").getStringValue()); + } + if (!row.get("Last_name").isNull()) { + setLastName(row.get("Last_name").getStringValue()); + } + if (!row.get("Admin").isNull()) { + setIsAdmin(row.get("Admin").getBooleanValue()); + } } } } else { diff --git a/src/main/java/com/application/DB/Constants.java b/src/main/java/com/application/DB/Constants.java index a026f51..75ae0f2 100644 --- a/src/main/java/com/application/DB/Constants.java +++ b/src/main/java/com/application/DB/Constants.java @@ -36,6 +36,8 @@ public class Constants { // Account constants private static boolean isAdmin = false; + private static String firstName; + private static String lastName; private static String userName; private static String phoneNo; @@ -62,4 +64,20 @@ public class Constants { public static void setIsAdmin(boolean isAdmin) { Constants.isAdmin = isAdmin; } + + public static String getFirstName() { + return firstName; + } + + public static void setFirstName(String firstName) { + Constants.firstName = firstName; + } + + public static String getLastName() { + return lastName; + } + + public static void setLastName(String lastName) { + Constants.lastName = lastName; + } } diff --git a/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java b/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java index 4db9e17..2e28bb1 100644 --- a/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java +++ b/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java @@ -18,6 +18,8 @@ import java.security.SecureRandom; import java.util.Arrays; import static com.application.DB.Account_handler.getAccount; +import static com.application.DB.Constants.*; +import static com.application.GUI.Panes.LogoBar.getLogin; public class LoginPopup { @@ -33,6 +35,7 @@ public class LoginPopup { Label passwordLabel = new Label("Password:"); TextField userNameTextField = new TextField(); + getPasswordTextField().clear(); Button closeButton = new Button("Close"); Button loginButton = new Button("Login"); @@ -56,7 +59,7 @@ public class LoginPopup { getAccount(userNameTextField.getText(),hashedPasswordString.toString()); - if(!LogoBar.getLogin().getText().equals("Login")){ + if(!getLogin().getText().equals("Login")){ window.close(); } @@ -85,7 +88,55 @@ public class LoginPopup { Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); - window.setTitle("Login window"); + window.setTitle("Admin window"); + + Label usernameLabel = new Label("Username: "); + TextField usernameTextfield = new TextField(); + usernameTextfield.setText(getUserName()); + usernameTextfield.setEditable(false); + + Button addUser = new Button("Add User"); + Button deleteUser = new Button("Delete User"); + Button logout = new Button("Logout"); + + addUser.setOnAction(event -> { + window.close(); + adminAddUser(); + }); + deleteUser.setOnAction(event -> { + window.close(); + adminDeleteUser(); + }); + logout.setOnAction(event -> { + window.close(); + logout(); + }); + + + VBox layout = new VBox(10); + layout.setAlignment(Pos.CENTER); + layout.getChildren().addAll(usernameLabel, usernameTextfield, addUser, deleteUser, logout); + + Scene scene = new Scene(layout, 500, 300); + scene.getStylesheets().add(InputPopup.class.getResource("/com.application/CSS/styleSheet.css").toExternalForm()); + window.setScene(scene); + window.showAndWait(); + } + + public static void adminAddUser(){ + + Stage window = new Stage(); + window.initModality(Modality.APPLICATION_MODAL); + window.setTitle("Admin window"); + + Label firstNameLabel = new Label("First Name: "); + Label lastNameLabel = new Label("Last Name: "); + Label phoneNoLabel = new Label("Phone No: "); + Label username = new Label("Username: "); + Label passwordFirst = new Label("Password"); + + + VBox layout = new VBox(10); @@ -98,11 +149,20 @@ public class LoginPopup { window.showAndWait(); } - public static void userPopup(){ + public static void adminDeleteUser(){ Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); - window.setTitle("Login window"); + window.setTitle("Admin window"); + + Label firstNameLabel = new Label("First Name: "); + Label lastNameLabel = new Label("Last Name: "); + Label phoneNoLabel = new Label("Phone No: "); + Label username = new Label("Username: "); + Label passwordFirst = new Label("Password"); + + + VBox layout = new VBox(10); @@ -115,6 +175,43 @@ public class LoginPopup { window.showAndWait(); } + public static void logout(){ + getLogin().setText("Login"); + setFirstName(""); + setLastName(""); + setIsAdmin(false); + setPhoneNo(""); + setUserName(""); + } + + public static void userPopup(){ + + Stage window = new Stage(); + window.initModality(Modality.APPLICATION_MODAL); + window.setTitle("User window"); + + + Label nameLabel = new Label("Name: "); + Label phoneNoLabel = new Label("Phone no: "); + + TextField nameTextfield = new TextField(); + TextField phoneNoTextField = new TextField(); + + nameTextfield.setText(getFirstName() + " " + getLastName()); + phoneNoTextField.setText(getPhoneNo()); + + Button logout = new Button("Logout"); + + VBox layout = new VBox(10); + layout.setAlignment(Pos.CENTER); + layout.getChildren().addAll(nameLabel, nameTextfield, phoneNoLabel, phoneNoTextField, logout); + + Scene scene = new Scene(layout, 500, 300); + scene.getStylesheets().add(InputPopup.class.getResource("/com.application/CSS/styleSheet.css").toExternalForm()); + window.setScene(scene); + window.showAndWait(); + } + public static PasswordField getPasswordTextField() { return PASSWORD_TEXT_FIELD; } diff --git a/target/classes/com/application/DB/Account_handler.class b/target/classes/com/application/DB/Account_handler.class index 254fefbc8b16860ea8ebc924d879720d5c4da3fc..8d513275eda4d202e46c120ea5da851ea1fba4e1 100644 GIT binary patch delta 973 zcmcaFIz_zx)W2Q(7#J8#7`Cu8xN<RQF}SfaxN|WuGq`aucz|e65aGqa;0>aEI2n8y z{J0qW83MQ%0vUq17=jr>Ktw1vLl{FiH$wzNB#4M&XNcxth~Z)oVu<Bph+~KcnVi7I zkjRk4#gNR9!o`rvkjBA~&gIMy$B+S1kqHvY;$X-I(K#Fpxga`^gCQRzSpeb`axfHe zF%&bDa50oJlyNbXGgPoMRI)QvZQK;XC{@kQP{Ynp%gzwZ$iU@Vk(^pkl9``Z%+63Z zS%Jw#L7PE`kwH8wu`E$PCowNwKe(hQGcVn#G&3h9wTO|SU~&tSg1C-?TV_#lNqk;n zZmN!gPa>2#c?pwsY&}B*4?{geBO`-=f}@{{LO^11ae01Gih`{I4?`0}Gdn{I4?`<M z8#_Zg4?_n-Cp$wI4?{OY4?9B*4?{0Q9}h!6!vuDQi98IG7$&nb)bcP)VVKIpFpXh4 zBZJ1|jch8D6PN|-XE4lUXPCvqFq>gI55pXWx$F${co^n0EMR9?$iuJ*Wa?rbh9wN0 zj0_wB8Toms@p<_?3`;=<En{frVOS25;X-(VhhYUsgcI%+9)^`50anM9+{`>4hE*V) zs~OfXGDwFP<>#eOKFcg2ww8xs9muBjJPaEcHnKBp;$hg#ptJcm^Iv9Zp5oLJu<?G0 zxv7i{+{LLSAhSWd&EMEX8HF_&v=~5uiGh(pn?Z+xkwJH|9H*GE9s>gd8v`Q)0|O6( zK9~ftSs4r%3>g?0I2nu>j2W01bQu^JcQLRqurV+&{Ft21=^(aFcN+uWP6mEP1}hdx zmYoa&j0`gwrcK_<DZ^Mc`4*>Mvh*wl0ZCRNxor$0+ZbeaFvv@?3Mqg&P#FkEW(R|! zB&(1TvJ8Zyyn{hy`Tw-#417YWI~de<FsN^1(Adbpz`)D^a&!=b$Yeb(<$5KCZU$wB z84RinOBvJ{HZf>0>}SwqIK!aLaFaoY;TeNI!y5)ehK~$J4Br_{z+N<AU}Z>RXkjp6 zFlAr`d5FP`!5kDe3_lnw7|a<M8FU!VFjz8}GcYk&FdSg8Vz6dlX0TykV31?r_{ZSG y&S1;VV8_m2|A)bwU4g+tQt}sr<Szy$CN2g?1_lNe21W)a21W*F1_lNu1{VNc8_f9t delta 824 zcmbOteqXfy)W2Q(7#J8#7*??}IC3$lF*va^ICC*DGdOWDxPWL^5aGtb;0~faI2k+{ zyto*=8GN`Hd>Q<>82lLmKtv!nLl8qSH$w<RD2NDSX9(wDh~Q!nVu<8oh+>EanH<B# z5X%t9#SqVsz{QZrki@}|%w^0F#gGD0kqQz@<6uY!aWX)hOb&)DE{1G|94>}jhCD8Y ze1-ychC+6RqK$__7^RBY8A{k0O4%9085y`-E0R+SN;32FirE>;CL1uhD5x`NFfxc| zC6*=X=OpH(>j#$<W#*+jm1gFoq!uwUL{6T<q%iq3lXX-%Lj?~*IYT8QgMfmgpNm33 zVsUYKeo=~otpX226+<;ULk$l@EkhkULp={e14AP_LlX}}GeZkILkSN<D?=L(LpwtU zJ3}WALl;9gJ3}cCLk~kQ4?`bA|KtQ_i;xKn6WJLi@i0tg=;vXW!Z4McVHyv^bcPx1 z3^REcW`T^G&BHK<p^=e+BOoI`FEu_dpNC;C$b@+e)jSOIK{Bk4DY=<>JPZp!!V4J| zP3C7&kX+2eumq%iDG$RkhUM%GD|i@Ig8ZyBnTt_ra~8`D=FRaO!i+Jh3~CG@z{J4F zpw6Jdz{sG<z`&r-z{tSJz`($&wVi=!BLf2i6N4550|OgakcUB=fq{Vs%w}cKVbEn@ zVBloXW6)<{0%>N<VPIikV_;y|J^37`gK?qmHU_?(4E&4?RxFY%I~fER8D=s>f>?r# z3<ns5tXL&kg@m^;h-_mJ)!N1&Hj{yGvLlzCn*2-#c9tCs3d{d5Ue3TLq_~4YX$OPy zHU<@tbC|)-abggde2GiBUYVhrL4{!kgF3@f1`URl3|b898FU!7Fz7PuV$cUW)`WqT zA&J4A!GOV#ffeL51|tSzkhd9jGng<KGcYpfF!VE+G8i*3F<3A(Gng@$GcYq)FfcI4 zGO+(+@L^}LWM{BqXR!XmV93s3Bl(L#;1>fE6BmOm0|Ns;3j-sA9RnkSJvg8o00Kpp A@&Et; diff --git a/target/classes/com/application/DB/Constants.class b/target/classes/com/application/DB/Constants.class index 14dbc461da2178a2135d25751ff437e29ad98f62..f9229ec0ebccb95510e2f7694f75caeb87e56e94 100644 GIT binary patch literal 2090 zcmX^0Z`VEs1_l#`3@!#~247AFDF#0f;SVALKtv#j2;yJ}2GJoL451)83`B&3hzJl7 z2_m9EL^Ozq0THnvA`V2vgNOtWkq9D^KtwW#NC6S4><nq_4C#yvyxy*n@ot_zuJL}3 zzOIZ6LOxlEWr_MZiFxVz!6ikRdFj@S3|zq>jzJ;uA)X)=oWUXf0Z=xNb7)YIt6xaG zi(`l@BLgQ$MZAxzTL>cqw`Xv?o2Q>=u!pM)BLia;BLlaOzoUz*3rMXaBLh!JkgIEa zaDc0`r)w}H1DA`Zud83Mr@vn?BLiEoV|cJ@2qOcpufJz-NNA92yt}`n4<mzsU#PE> zYf!wuTfDP}tFw17BLkx+BZH)`V?=ytuxn7fr(Zy5NW8O$W00eBh-*+VBZI7qtD9q} zPe{CHaD1?<kE?Ttt4q9(XP7J09dg*@gIwK%T!TTbVPsInuOL3y!_mb*oRL8ho4SA? z*Dz22&|s)#?3u-mDY=<>j0~J<nMK7Veu=rMj0_w(iEw6VacU7nl)WG$KQGlUpOJyh zCNnRy#Ey}HSwl07k%7fIKP8osf!`-HFV(L!Hz~C!Brz!`6%=>*$%#2(iA9+pK2(sU zBqOt!kwMNUIX_oFv7jI)GdZy&Ge1w?#Yx{eKd-nXF|VZ9nvsD!J+&khZn=ntCbopY zU5u<qR0C5D$bnqxsU-n0$8!}UaX2%JJz*ihtf3jj$N-Xt3$bWKf%NmFr<S-Of`_LV zg$r`14?Ms?E<*4)Y?5=JVZ{}kUs{x$>Xr!#89umA^+3s+hryJ=jEBLPL6(QX1Vk7x zDDyBFf>=fjvWyHG#c8@JMU|O(>ALv^C7HRIRp21gwMaBdHB2&3OG`F1(aS2%&*Nc` z0jX!;VUPo9mIo0EAVLvDD1l5>0THSot{R9?2N4<|LX$y@hd~=e=zx^yf(Shjq0gYq z$RL9+x)>P*K;D4lQval^)Z`KdMFuGbX$A%cF$PYMqZk+%I6;mA)A9_mU|Io6D?(`{ z24%3g3Y1obimO3sbttU?r8OC}!0NT3v<_6CE|k`T()wVUi@^X&8-n$7F&IH<V<>F` zrg<0`LGi)B$Y9REz@X2-$iT?Jz`&}toq=&90|NsSg9QTv0~=V7nZc5QfdQm}fq|95 zioqJ}92*8(sAd_kDh39YO$<yM7#J8Bk@V^^a5C62*h5ts!>!rOz=W`di-C!Ofx(c0 zg~15LDu|0Y862=##f)y1DFY{iBUY=J(XFy%U}3OAu?i9>oD5D3&QP}^`HE!?ny+jb zI2l|RT%juAzLMI^z=Cd-BLfSA6N*)k_~B%5!{#eibYHnLa5A`K^%X0+Rh|qi3|=T! zL6QI`g9kRN*wC%=W#DA+#A+2Ax>bP;EDS*?RzXr32ZI-b88ledLz6|Y5c_5Z4k6CX z3|t_B8$|Gc2wvvR41CO+8TdgQ0T3YwB7{JMFw15J5dp5v45BQX8N^sNGl(;9W{_an z%pl1O4P;0v^I{MJr&Cr2P6jRpE(U%EZUzws9tKGUeg;_vK?X$z5e78|Q3h=WF$Mz$ paRyTcDF#ahSq3`>1qLSuMFuwpB?d1BWd=V6H3mioZ*a=@0RY|4P)Gm( delta 905 zcmZ1_aG$sS)W2Q(7#J8#7~;4XBpF;e86+6oK!iJp@ZezZ1kqj`4BjBx2SoUS2tN?v z4<Z6UL?DO=0ujL=A_PQ)f`~8>5e_0EKtv>nhyoGO><lsN46z$Ks~9&+F|jgEj%3yp zGGs8~VbEug=3y`Z5qb=Yljkw(hDk9<GcqvnFvx%eWkG}-h>!;n3Ji)o3`!tE8N^iq z5vm|U4MeCjXz(y-f(R{;5^WHn10r-86elaPnAS@$NHQ=mh%j(6NHIt=Ffed}ECJK9 zP`(_LmWR>`42ocRB`B>76<2}Ms!&=DN~<$yfYob4X)UNeZ4h10z{#KkVlZ$r=z?i3 z20bXP4>o`c6ch{$3>*xM42BFw42%rM3=9nV42%qn3=9mcTH6^IH!?6VFfo`gFfg!z z1(_L489>1WR={A!U=Ft5g2581Sq7|%fq`WcgACIK1_lO3B+c3koD5bB)*z*m8(77( zLB?`1FoEr4VK6{38sb7u1{;XclMk|r)`QeToMFts$zTgHiGhK^81CZD49o}@LyR_O zU}3O8G1>s^c}@m9278cG7#J9kT+Olu&C%8joD2>Ojtq<p^`Ov!+a<M`fd$<zdj=K; z2Nb&?0nWkT1P|Wz&=3k1V%^NZCd9s(fdfQvf(R}U!OgsxfroiB122ff2O{`Egn*C+ y`(_3~mdy-80$iIJgjqH-h_GyC5M|!XAjYzpL7W-t9!3U}$(Psz*`2{L=K=uHTu;{k diff --git a/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class b/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class index c0bfec4e092c91274be6d9220d72a0f18defb406..3f8a75275aab99173bb5eb93f608c03a1989df38 100644 GIT binary patch delta 4419 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 delta 2526 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 LFaye(%`gK1d_VCm -- GitLab