From 48ea170c96100558ccc3a8a2279a0fd8aa90cc6e Mon Sep 17 00:00:00 2001 From: Eilert Tunheim <emtunhei@stud.ntnu.no> Date: Sun, 8 May 2022 20:21:06 +0200 Subject: [PATCH] Fully implemented deleting user! --- .../com/application/DB/Account_handler.java | 57 ++++++++++++++---- .../GUI/PopUpWindows/LoginPopup.java | 29 +++++++-- .../com/application/DB/Account_handler.class | Bin 3564 -> 4213 bytes .../GUI/PopUpWindows/LoginPopup.class | Bin 10685 -> 11512 bytes 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/application/DB/Account_handler.java b/src/main/java/com/application/DB/Account_handler.java index ff63832..e5a7cf0 100644 --- a/src/main/java/com/application/DB/Account_handler.java +++ b/src/main/java/com/application/DB/Account_handler.java @@ -8,21 +8,13 @@ import com.google.cloud.bigquery.TableResult; import static com.application.DB.Constants.*; import static com.application.DB.Settings.*; import static com.application.GUI.PopUpWindows.LoginPopup.getPasswordTextField; +import static java.lang.System.err; public class Account_handler { - public static void getAccount(String username, String password) throws Exception { + public static void getAccountInformation(String username, String password) throws Exception { - // Sqlstatement - 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+ '"'; - - System.out.println(sqlStatement); - - // Retrieves the results from the queryjob - TableResult result = HelpingFunctions.createQueryJob(sqlStatement); + TableResult result = logIn(username,password); if(result.getTotalRows() != 0) { for (FieldValueList row : result.iterateAll()) { @@ -51,6 +43,33 @@ public class Account_handler { } } + public static TableResult logIn(String username, String password) throws Exception { + + // Sqlstatement + 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+ '"'; + + System.out.println(sqlStatement); + + // Retrieves the results from the queryjob + return HelpingFunctions.createQueryJob(sqlStatement); + } + + public static TableResult getAccount(String username) throws Exception { + + // Sqlstatement + final String sqlStatement = "SELECT Username " + + "FROM " + PROJECT_ID + "." + LOCATION_ID + "." + USERS_TABLE_NAME + " " + + "WHERE Username = " + '"' + username + '"'; + + System.out.println(sqlStatement); + + // Retrieves the results from the queryjob + return HelpingFunctions.createQueryJob(sqlStatement); + } + public static void addUser(String firstName, String lastName, String phoneNo, String username, String password, boolean isAdmin) throws Exception { // Sqlstatement final String sqlStatement = @@ -62,4 +81,20 @@ public class Account_handler { HelpingFunctions.createQueryJob(sqlStatement); } + public static boolean deleteUser(String username) throws Exception { + + if(getAccount(username).getTotalRows() != 0){ + // Sqlstatement + final String sqlStatement = "DELETE FROM "+ PROJECT_ID + "." + LOCATION_ID + "." + USERS_TABLE_NAME +" WHERE Username = "+'"'+username+'"'; + + System.out.println(sqlStatement); + + HelpingFunctions.createQueryJob(sqlStatement); + + return true; + } else { + return false; + } + } + } diff --git a/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java b/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java index d256ef9..c9739a3 100644 --- a/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java +++ b/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java @@ -11,8 +11,7 @@ import javafx.stage.Stage; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -import static com.application.DB.Account_handler.addUser; -import static com.application.DB.Account_handler.getAccount; +import static com.application.DB.Account_handler.*; import static com.application.DB.Constants.*; import static com.application.GUI.Panes.LogoBar.getLogin; @@ -39,7 +38,7 @@ public class LoginPopup { loginButton.setOnAction(event -> { try { - getAccount(userNameTextField.getText(), hashPassword(getPasswordTextField().getText())); + getAccountInformation(userNameTextField.getText(), hashPassword(getPasswordTextField().getText())); } catch (Exception e) { e.printStackTrace(); } @@ -76,6 +75,7 @@ public class LoginPopup { Button addUser = new Button("Add User"); Button deleteUser = new Button("Delete User"); Button logout = new Button("Logout"); + Button close = new Button("Close"); addUser.setOnAction(event -> { adminAddUser(); @@ -87,11 +87,12 @@ public class LoginPopup { logout(); window.close(); }); + close.setOnAction(event -> window.close()); VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); - layout.getChildren().addAll(usernameLabel, usernameTextfield, addUser, deleteUser, logout); + layout.getChildren().addAll(usernameLabel, usernameTextfield, addUser, deleteUser, logout, close); Scene scene = new Scene(layout, 500, 300); scene.getStylesheets().add(InputPopup.class.getResource("/com.application/CSS/styleSheet.css").toExternalForm()); @@ -174,10 +175,28 @@ public class LoginPopup { Label usernameLabel = new Label("Username: "); TextField usernameTextField = new TextField(); + Button close = new Button("Close"); + Button delete = new Button("Delete User"); + + close.setOnAction(event -> window.close()); + delete.setOnAction(event -> { + try { + boolean results = deleteUser(usernameTextField.getText()); + if(results){ + NotificationPopUp.displayNotificationWindow(usernameTextField.getText()+" was successfully deleted!"); + window.close(); + } else { + NotificationPopUp.displayNotificationWindow("Could not find username: " + usernameTextField.getText()); + usernameTextField.clear(); + } + } catch (Exception e) { + e.printStackTrace(); + } + }); VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); - layout.getChildren().addAll(); + layout.getChildren().addAll(usernameLabel, usernameTextField, delete, close); Scene scene = new Scene(layout, 500, 300); scene.getStylesheets().add(InputPopup.class.getResource("/com.application/CSS/styleSheet.css").toExternalForm()); diff --git a/target/classes/com/application/DB/Account_handler.class b/target/classes/com/application/DB/Account_handler.class index 6e0dd40dcbbfaca02fad27009793c8cbbaf28c39..c09f8ced6631474642158218a0c1f8833b6ff76f 100644 GIT binary patch delta 1926 zcmaDO{Z*m<)W2Q(7#J8#7|ydZL~=10F+_1O7&1h2F~l&$f`~Y7hIobqZiYmLBoL9z z&XB^vkjllt$&kjykj{_+(vr!=kj0SA#gN00%f*n#kk7$T0Fo;N5k(-8Vh)B95M9c_ zPzIvQIT$KHl9gPE40#My91PW53^fe3Tnu##^;`@M42|pzO<W8L3{e~m%^<o3M6_}+ zw1Mb$PKFMKPA-NnhHfr~9)?~HhCU94eh!8SAjydw43j_}n9RX2g`Ht4JHxbz7jmUU z(^E?vlaupH^GZDP((;RP6H7Al^B5V_H6|A@sZ1_lOq%?V(OG#qJHrfih7?8yF4v0W z)B=#2Vs?g^j0~(f`RSf{j10aI^|tKVGR1{C!6k_$sky0nC5#MQ2n!e)tS1X_=ueJh z=bP-nG@CaiH7B(sHMBUjh><~bvH*w3<m*hXy2cD9JPe);UhE9hc^GCf%;sU3!!Vbf zVIB{|e1-+=3^RBb7BVd2VOY$tgpomGvOT-hWP1*-$qN`+>KPe0K!)Wd=BDy6EM-{6 z&aj+^VFkky9)^_+tJoP<^DwMoSj*0^j)!4A!v=PSjXVsS7&b66a0F!J=cUHy<?}FX z2ARBtVJi>AHjoULTV_#lNj${B?I00OpG3I84v+w=V@hsj9uLD#hDDP%v1kcyU}xCJ z!?2&>06W7$9)?2<CX?lv``r#R9N}R&%y5*EK|sOL&qX01vADQAzbHk)R)L4%7{gX} zhT}X8Cm2q$Go0dKI1O^#86JkS48DvE9>K0YuFfF}AdgMXXSSXEmZeJiFvB@U1}04f z9tIzf8haO4AJ-691-Br7-^ssO6erJQ7M`5XYQ?BJ*`8f>@*`H=&FSnL85zN0%osLV zjMH;+5u5ntcupI}$^2}|lRMc0Cx2oypFEpOLD-PNhyeuH7#JCh8B7=$8B8ai;}WYk zV_;wai7_znGMF<kFz_%iGB7Z(GFUKJGB7Z3GFUNKGcYljGB7X}Ft9MNGB7Y4*3#a= z!0fBDje&)8%1nmUI@=gncQUXsGWhB4WMF4xn8`3zcP9e}Bf|j(PAe8k79p-}4BXoo zc(k@L@Xll?+rhx6wT*#aYX^gXB#ThJAXrjp7MKU&2=8DJkz^4PMV5hZgm*BANwNru zBg;TI!aEowBw2(ck!2tpsT~Z`%l~IAXW$c(*})*YgF$W^gZxGY1_ovZGX{ow1}_F7 z1_lN}1~vv^27U$+23-a*20I3E23H0N22TblhA;+chGYg=h5`mThFS&%hAsw0hUpB- z3`-bP7&bDfGi+zjWZ1)?#c+s02ONM}3@i+~3@r>c47Lm`px|P#W3UH>Ji}oI2L^iv zMg}&9y$p^FP7F*8&J6Vo4AKl7e;Fj%8C=*IT>mh5vNO0zO8#Py{Kde;#Kqvwz`(%5 zz{udizzNDckf>m&V_;%nW?*2j*v+62xt&2#NNF2`veq^RWdWsa3@SpZFqSrqv5i5^ zcN2rU&Nc=OogECC8yFZEm_XiVsOJM4WXPbyV8&p~U<vku0$9uf?r;mJ!*v*V7`z$m z8JJL<<-_0$bygw+69W?i1A{8eSs*8YFxXk!7}R_=F{o>AW6;osy8)d3Aa1Z{kYsRX zP+)KayFm<M64VWnP@5T1Z1!XDhuZv|fr){gfq|hFW;4j=aGQm6VBr7~20I2ORL`IS zmxPHisOZAfBZMSbP{c%8w=w7n>1|_B-o~J2#kPq-U6O4ZgN7vA4hGF|Q0jsNuMjv1 zcr%nS_%qZo1TwTR1c80$0dXxuKs_{Vv@!&O(*^@WD?<=Ch(Rn+$^pf5D>wo`si~DA zm?4CLm7$D*9~>2IC;<}65C#p9HU<`O0Gev;V9<x=R4rKG7$8zhF@p+Pyo9r?VO|5v z9t=_pYzzzxVGKMB5e%vfQ4Bf^F${(baSX-`31E+aqDhs359}6D!C?xGFlVp{jK)aL LV`K;iC%Xs$ARKcT delta 1467 zcmeyW@J71+)W2Q(7#J8#7>=+r1aL9vF$A(R1aUDiGX!!l1cT@h5E0735C)>dIT<1t zBDol%7^1ltVi;n%7~&Y>K|}&KLn1>GH$yT*3W!K$XGr5<Natb@V#wfP$YjU@nVikV zki(G6#gNC4&&5!{P{_eh#1+Vp$xsYZQ34Vw<zOfS(d8Tr6(G8jgP{r}Sq<XUa4^(z zG1M{Cb1^h9G;%RCF*I{9v~V!Af*jVy!O+gm(812oIq^X*KUaEciDPndera9_BZIoe zWLsvH$=!@eygbE)Il(1~C8@coc_ouyGrCH3u`_hDGxV@Cq%ksZxmF~n7L;V>=M}Rv z^iKZCG<WiDW=Cdy27}4mto^Zl4E;O|eGC&A83Ys@{ah3R5{rw=^NUgxY!!GICNfN7 zXPC^xFoj_%JHs>{hUpA5*coQ>FwA0@&Cbxx!!U<oE)T;zhWYFa3wRh7GAv?e=;2{l z%&>%qVJX8hMh1<^h8!xBeOUzSmouzjXIRO@u!><B55sDPHS7#)c^K9)tY>G~z{9W+ zWa=g!hRqB!7#TPMGV=3M<MZ-)7`A{6+R8AAhhZB?hRZFpsJJ9PFEKZjhhaNNgwrPx zF0cb6!0MQio0-SMuoI+n7sGBw2I=sk{JiwZcUfcwXRtHu<6+p(aDbiRAP>VK27}46 zY*ie642KyRm^2k8KV!2J6v#>}OVrOv%uCk~E-A{)OP?&q9y<9NSMua$PVvc>+<}u9 zF^e*WP43{fWVD|AfJ=08C6ngn67~&@lWjQNH_zg<VVr!BTcKW;L5~3hm>C!u^cf5o z7#R#17#Q>!7#SED7#LW!wlgqoWME)mVlZN0U|<6a@-P@PFfj0d*{lpE45kbW44e#R z4CV|>AkB=s7+4tC7#J9S>}Ft&+|Ixv#JY`vO=}win}E_b26iD17)yH_16w^<Y#Rfo z?<NK=oox)<Iy)G6{B*Z5@N!O>$*@j$8w1}?27X2cD;7zXoeTnu3^N&~fmni!3<ns5 ztXL&kg@m^;h-_mJ)!N1&Hj|-j2ZOlQHU<f;9So9^tU^*?Iq6vp0&tGZ4hC6CRv|fv zOg%&j!jsv-ATP-(qyUkE$UrzUI~WutS%s94Wgr~o9SkbV|EDcy;1g2a!JxK-L46y8 z1}Mas!66pJAi}`FAjqJ@AjV+KAjx3CAkE;&Aj6QvAjeS5AkR==#h}1Y$DqW}&7jOM zgF%&HDT5lrCI$_L{S2B6XBe~@ZZhaFJY&#jc*9`G@R7lY;X8u~IQUH%SQ(NSS{N)C zEE!lqfz4pWU=4~$h93+z4Au;c3_1*F7;G7=8JHL>7!EMlG1xOOGdM6XFvu}*{A2K8 zXK-X^aAL1#aQ?&K&CcK=Dfx>*@)rXW6BmOk0|NsK10#bQ11Ez!g9jv58NM?xF|ac* zFtoyARTCvv;qeQKRdA#V!G&~SF^&+@g$mWPBg7<Gpn?!FQPyn?+Cm_`+ZZ^l*fue6 zNwRHY;Fe_D!N3y^3Smf^6k=duU|_IdC}Xf;sAI5WXkoAi2apHEwG5unU}<IW0tX8N vLo0(fI9Na|b5N);gS-U}HIPxQ3_c9L46F=g4E*5mV?zoMMg~7{X7C39PAw<Z diff --git a/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class b/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class index d4a94a6fe190f467c0b42a87ea149c36ce524ac6..698cb86ef53e3d533faa5e46e0a6a7d16ec3f077 100644 GIT binary patch delta 5636 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 TEMqv!6wWe(vpnG}FGfZH#vGsg delta 4795 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 Ug|pP)EGsaJotfb?qcy`<01H3k`Tzg` -- GitLab