View Javadoc
1   /*
2    * Copyright (c) Patrick Magauran 2018.
3    *   Licensed under the AGPLv3. All conditions of said license apply.
4    *       This file is part of ABOS.
5    *
6    *       ABOS is free software: you can redistribute it and/or modify
7    *       it under the terms of the GNU Affero General Public License as published by
8    *       the Free Software Foundation, either version 3 of the License, or
9    *       (at your option) any later version.
10   *
11   *       ABOS is distributed in the hope that it will be useful,
12   *       but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   *       GNU Affero General Public License for more details.
15   *
16   *       You should have received a copy of the GNU Affero General Public License
17   *       along with ABOS.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package Controllers;
21  
22  import Utilities.*;
23  import javafx.application.Platform;
24  import javafx.event.ActionEvent;
25  import javafx.fxml.FXML;
26  import javafx.geometry.Insets;
27  import javafx.scene.control.*;
28  import javafx.scene.control.cell.CheckBoxTreeCell;
29  import javafx.scene.layout.BorderPane;
30  import javafx.scene.layout.GridPane;
31  import javafx.scene.layout.HBox;
32  import javafx.scene.layout.VBox;
33  import javafx.stage.Stage;
34  import javafx.stage.Window;
35  
36  import java.sql.Connection;
37  import java.sql.PreparedStatement;
38  import java.sql.ResultSet;
39  import java.sql.SQLException;
40  import java.util.*;
41  import java.util.regex.Pattern;
42  
43  //import javax.swing.*;
44  //import javax.swing.border.EmptyBorder;
45  //import javax.swing.table.DefaultTableModel;
46  //import java.awt.*;
47  //import java.awt.*;
48  @SuppressWarnings("WeakerAccess")
49  
50  public class AddUserController {
51  
52      @FXML
53      private TextField userNameField;
54      @FXML
55      private TextField fullNameField;
56      @FXML
57      private TextField passwordField;
58      private Window parentWindow;
59      @FXML
60      private Accordion yearsPanel;
61      private boolean newUser = true;
62      @FXML
63      private Button deleteUserButton;
64      @FXML
65      private CheckBox adminCheckbox;
66      private Map<String, ArrayList<String>> checkedUsers = new HashMap();
67      private Map<String, ArrayList<String>> checkedFullName = new HashMap();
68  
69      private Map<String, Integer> groups = new HashMap<>();
70  
71      public AddUserController() {}
72  
73      public static boolean stringContainsItemFromList(String inputStr, String[] items) {
74          return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
75      }
76  
77      @FXML
78      private void cancel(ActionEvent event) {
79          close();
80      }
81  
82      private void close() {
83          Stage stage = (Stage) userNameField.getScene().getWindow();
84          // do what you have to do
85          stage.close();
86      }
87  
88      /**
89       * Create the dialog.
90       */
91  
92      @FXML
93      private void submit(ActionEvent event) {
94          Pattern p = Pattern.compile("[^a-zA-Z0-9]");
95          boolean hasSpecialChar = p.matcher(userNameField.getText()).find();
96          if (hasSpecialChar) {
97              Alert alert = new Alert(Alert.AlertType.WARNING);
98              alert.setTitle("");
99              alert.setHeaderText("You have entered an invalid character in the username");
100             alert.setContentText("Only Alphanumeric characters are aloud.");
101             alert.show();
102         } else {
103             Set<String> years = new HashSet<>();
104             if (newUser) {
105                 User.createUser(userNameField.getText(), passwordField.getText(), fullNameField.getText(), adminCheckbox.isSelected());
106             } else {
107                 User.updateUser(userNameField.getText(), passwordField.getText(), fullNameField.getText(), adminCheckbox.isSelected());
108 
109             }
110             ArrayList<ArrayList<String>> yearUsers = new ArrayList<>();
111             checkedUsers.forEach((year, users) -> {
112                 ArrayList<String> usersManage = new ArrayList<>();
113 
114                 users.forEach((user) -> {
115                     if (Objects.equals(user, "user@self")) {
116                         user = userNameField.getText();
117                     }
118                     if (!user.isEmpty()) {
119                         usersManage.add(user);
120 
121                     }
122                 });
123 
124                 if (!usersManage.isEmpty()) {
125                     years.add(year);
126                     User yearUser = new User(userNameField.getText(), fullNameField.getText(), usersManage, years, adminCheckbox.isSelected(), groups.getOrDefault(year, 0));
127                     if (newUser) {
128                         yearUser.addToYear(year);
129                     } else {
130                         yearUser.updateYear(year);
131                     }
132                 }
133             });
134 
135 
136             close();
137         }
138     }
139 
140     @FXML
141     private void deleteUser(ActionEvent event) {
142 
143         final String user = userNameField.getText();
144         if (!Objects.equals(user, DbInt.getUserName())) {
145 
146 
147             Optional<Group> returnGroup = Optional.empty();
148             Dialog<String> dialog = new Dialog<>();
149             dialog.setTitle("DELETE USER?");
150             dialog.setHeaderText("This will delete ALL customers and data associated with this user.");
151 // Set the button types.
152             ButtonType addGrp = new ButtonType("Delete", ButtonBar.ButtonData.OK_DONE);
153             dialog.getDialogPane().getButtonTypes().addAll(addGrp, ButtonType.CANCEL);
154 
155 // Create the username and password labels and fields.
156             GridPane grid = new GridPane();
157             grid.setHgap(10);
158             grid.setVgap(10);
159             grid.setPadding(new Insets(20, 150, 10, 10));
160 
161             TextField verifyUNameTF = new TextField();
162 
163             grid.add(new Label("Please re-type the username for verification:"), 0, 0);
164             grid.add(verifyUNameTF, 1, 0);
165 
166 
167 // Enable/Disable login button depending on whether a username was entered.
168             javafx.scene.Node deleteUserButton = dialog.getDialogPane().lookupButton(addGrp);
169             deleteUserButton.setDisable(true);
170             deleteUserButton.setStyle("fx-background-color: Red; fx-color: White");
171 // Do some validation (using the Java 8 lambda syntax).
172             verifyUNameTF.textProperty().addListener((observable, oldValue, newValue) -> {
173                 if (Objects.equals(newValue, user)) {
174                     deleteUserButton.setDisable(false);
175                 } else {
176                     deleteUserButton.setDisable(true);
177                 }
178             });
179 
180             dialog.getDialogPane().setContent(grid);
181 
182 // Request focus on the username field by default.
183             Platform.runLater(() -> verifyUNameTF.requestFocus());
184 
185 // Convert the result to a username-password-pair when the login button is clicked.
186             dialog.setResultConverter(dialogButton -> {
187                 if (dialogButton == addGrp) {
188                     return verifyUNameTF.getText();
189                 }
190                 return null;
191             });
192 
193             Optional<String> result = dialog.showAndWait();
194             result.ifPresent(res -> {
195                 if (Objects.equals(res, user)) {
196 
197                     DbInt.getUserYears().forEach(year -> {
198                         try (Connection con = DbInt.getConnection(year);
199                              PreparedStatement prep = con.prepareStatement("DELETE FROM users WHERE userName=?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
200                             prep.setString(1, user);
201                             prep.execute();
202                         } catch (SQLException e) {
203                             LogToFile.log(e, Severity.SEVERE, CommonErrors.returnSqlMessage(e));
204                         }
205                         try (Connection con = DbInt.getConnection(year);
206                              PreparedStatement prep = con.prepareStatement("UPDATE users SET uManage = REPLACE (uManage, ?, '')", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
207                             prep.setString(1, user);
208                             prep.execute();
209                         } catch (SQLException e) {
210                             LogToFile.log(e, Severity.SEVERE, CommonErrors.returnSqlMessage(e));
211                         }
212 
213                     });
214                     try (Connection con = DbInt.getConnection("Commons");
215                          PreparedStatement prep = con.prepareStatement("DELETE FROM Users WHERE userName=?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
216                         prep.setString(1, user);
217                         prep.execute();
218                     } catch (SQLException e) {
219                         LogToFile.log(e, Severity.SEVERE, CommonErrors.returnSqlMessage(e));
220                     }
221                     try (Connection con = DbInt.getConnection();
222                          PreparedStatement prep = con.prepareStatement("DELETE USER IF EXISTS `" + user + "`@`%`", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
223 
224                         prep.setString(1, user);
225                         prep.execute();
226                     } catch (SQLException e) {
227                         LogToFile.log(e, Severity.SEVERE, CommonErrors.returnSqlMessage(e));
228                     }
229 
230                 }
231             });
232         } else {
233             Alert alert = new Alert(Alert.AlertType.WARNING);
234             alert.setHeaderText("You cannot delete yourself.");
235             alert.showAndWait();
236         }
237 
238         close();
239 
240     }
241 
242     public void initAddUser(Window parWindow) {
243         parentWindow = parWindow;
244         DbInt.getUserYears().forEach(year -> {
245             TitledPane yPane;
246             yPane = new TitledPane();
247 
248             ComboBox<TreeItemPair<String, Integer>> groupBox = new ComboBox<>();
249             TreeView<TreeItemPair<String, String>> yearTView;
250             CheckBoxTreeItem<TreeItemPair<String, String>> yearItem = new CheckBoxTreeItem<TreeItemPair<String, String>>(new TreeItemPair<>(year, ""));
251             CheckBoxTreeItem<TreeItemPair<String, String>> selfItem = createUserTreeItem(new TreeItemPair<>("Themselves", "user@self"), year, yPane);
252             yearItem.getChildren().add(selfItem);
253             Group.getGroups(year).forEach(group -> {
254                 CheckBoxTreeItem<TreeItemPair<String, String>> groupItem = new CheckBoxTreeItem<TreeItemPair<String, String>>(new TreeItemPair<>(group.getName(), ""));
255                 group.getUsers().forEach(user -> {
256                     CheckBoxTreeItem<TreeItemPair<String, String>> userItem = createUserTreeItem(new TreeItemPair<>(user.getFullName(), user.getUserName()), year, yPane);
257                     groupItem.getChildren().add(userItem);
258                 });
259                 yearItem.getChildren().add(groupItem);
260                 try {
261                     groupBox.getItems().add(new TreeItemPair<String, Integer>(group.getName(), group.getID()));
262                 } catch (Group.GroupNotFoundException ignored) {}
263             });
264             yearTView = new TreeView(yearItem);
265             yearItem.setExpanded(true);
266             yearTView.setCellFactory(CheckBoxTreeCell.forTreeView());
267             groupBox.getSelectionModel().selectedItemProperty().addListener(observable -> {
268 
269                 groups.put(year, groupBox.getSelectionModel().getSelectedItem().getValue());
270             });
271             BorderPane contents = new BorderPane(new VBox(10, new Label("Users to manage"), yearTView), new HBox(10, new Label("Group to be a part of"), groupBox), null, null, null);
272             yPane.setText(year);
273             yPane.setContent(contents);
274             yearsPanel.getPanes().add(yPane);
275             groupBox.getSelectionModel().selectFirst();
276         });
277 
278 
279     }
280 
281     private void addUser() {
282 
283     }
284 
285     /**
286      * Create the dialog.
287      */
288     public void initAddUser(String userName, Window parWindow) {
289         ArrayList<User> users = new ArrayList<User>();
290         adminCheckbox.setDisable(true);
291 
292         newUser = false;
293         parentWindow = parWindow;
294         userNameField.setText(userName);
295         userNameField.setEditable(false);
296         deleteUserButton.setDisable(false);
297         DbInt.getUserYears().forEach(year -> {
298             TitledPane yPane;
299             yPane = new TitledPane();
300 
301             ComboBox<TreeItemPair<String, Integer>> groupBox = new ComboBox<>();
302             TreeView<TreeItemPair<String, String>> yearTView;
303             CheckBoxTreeItem<TreeItemPair<String, String>> yearItem = new CheckBoxTreeItem<TreeItemPair<String, String>>(new TreeItemPair<>(year, ""));
304             User currentUser = new User(userName, year, true);
305             users.add(currentUser);
306 
307             Group.getGroups(year).forEach(group -> {
308                 CheckBoxTreeItem<TreeItemPair<String, String>> groupItem = new CheckBoxTreeItem<TreeItemPair<String, String>>(new TreeItemPair<>(group.getName(), ""));
309                 group.getUsers().forEach(user -> {
310                     CheckBoxTreeItem<TreeItemPair<String, String>> userItem = createUserTreeItem(new TreeItemPair<>(user.getFullName(), user.getUserName()), year, yPane);
311                     if (currentUser.getuManage().contains(user.getUserName())) {
312                         userItem.setSelected(true);
313 /*                        checkedUsers.computeIfPresent(year, (k, v) -> {
314                             v.add(user.getUserName());
315                             return v;
316                         });
317                         checkedUsers.computeIfAbsent(year, k -> {
318                             ArrayList<String> v = new ArrayList();
319                             v.add(user.getUserName());
320                             return v;
321                         });
322                         checkedFullName.compute(year, (k, v) -> {
323                             ArrayList<String> vArray = new ArrayList();
324                             vArray.addAll(v);
325                             vArray.add(user.getFullName());
326                             return vArray;
327                         });*/
328 /*                        checkedFullName.computeIfAbsent(year, k -> {
329                             ArrayList<String> v = new ArrayList();
330                             v.add(user.getFullName());
331                             return v;
332                         });*/
333                     }
334                     groupItem.getChildren().add(userItem);
335                 });
336                 yearItem.getChildren().add(groupItem);
337                 try {
338                     groupBox.getItems().add(new TreeItemPair<String, Integer>(group.getName(), group.getID()));
339                     if (currentUser.getGroupId() == group.getID()) {
340                         groupBox.getSelectionModel().selectLast();
341                     } else if (currentUser.getGroupId() == 0) {
342                         groupBox.getSelectionModel().selectFirst();
343 
344                     }
345 
346                 } catch (Group.GroupNotFoundException ignored) {
347                 }
348             });
349             yearTView = new TreeView(yearItem);
350             yearItem.setExpanded(true);
351             yearTView.setCellFactory(CheckBoxTreeCell.forTreeView());
352             yearTView.refresh();
353             groupBox.getSelectionModel().selectedItemProperty().addListener(observable -> {
354 
355                 groups.put(year, groupBox.getSelectionModel().getSelectedItem().getValue());
356             });
357             BorderPane contents = new BorderPane(new VBox(10, new Label("Users to manage"), yearTView), new HBox(10, new Label("Group to be a part of"), groupBox), null, null, null);
358             yPane.setText(year);
359             yPane.setContent(contents);
360 
361             yearsPanel.getPanes().add(yPane);
362             if (checkedUsers.getOrDefault(year, new ArrayList<>()).isEmpty()) {
363                 yPane.setText(year + " - Disabled");
364 
365             } else {
366                 yPane.setText(year + " - " + arrayToCSV(checkedFullName.getOrDefault(year, new ArrayList<>())));
367 
368             }
369             groups.put(year, groupBox.getSelectionModel().getSelectedItem().getValue());
370 
371         });
372         User latestUser = users.get(users.size() - 1);
373         fullNameField.setText(latestUser.getFullName());
374         adminCheckbox.setSelected(latestUser.isAdmin());
375 
376     }
377 
378     private <T> CheckBoxTreeItem<TreeItemPair<String, String>> createUserTreeItem(TreeItemPair<String, String> value, String year, TitledPane titledPane) {
379 
380         CheckBoxTreeItem<TreeItemPair<String, String>> item = new CheckBoxTreeItem<TreeItemPair<String, String>>(value);
381         if (!value.getValue().isEmpty()) {
382             item.selectedProperty().addListener((obs, wasChecked, isNowChecked) -> {
383                 if (isNowChecked) {
384                     checkedUsers.computeIfPresent(year, (k, v) -> {
385                         v.add(value.getValue());
386                         return v;
387                     });
388                     checkedUsers.computeIfAbsent(year, k -> {
389                         ArrayList<String> v = new ArrayList();
390                         v.add(value.getValue());
391                         return v;
392                     });
393                     checkedFullName.computeIfPresent(year, (k, v) -> {
394                         v.add(value.getKey());
395                         return v;
396                     });
397                     checkedFullName.computeIfAbsent(year, k -> {
398                         ArrayList<String> v = new ArrayList();
399                         v.add(value.getKey());
400                         return v;
401                     });
402 
403                 } else {
404                     checkedUsers.compute(year, (k, v) -> {
405                         v.remove(value.getValue());
406                         return v;
407                     });
408                     checkedFullName.compute(year, (k, v) -> {
409                         v.remove(value.getKey());
410                         return v;
411                     });
412                 }
413                 if (checkedUsers.getOrDefault(year, new ArrayList<>()).isEmpty()) {
414                     titledPane.setText(year + " - Disabled");
415 
416                 } else {
417                     titledPane.setText(year + " - " + arrayToCSV(checkedFullName.getOrDefault(year, new ArrayList<>())));
418 
419                 }
420 
421             });
422         }
423 
424         return item;
425     }
426 
427     private String arrayToCSV(Collection<String> array) {
428         final String[] ret = {""};
429         array.forEach(value -> {
430             if (!ret[0].isEmpty()) {
431                 ret[0] = ret[0] + ", " + value;
432             } else {
433                 ret[0] = value;
434             }
435         });
436         return ret[0];
437     }
438 
439 }