James Moger
2011-10-21 b75734f0600c333d70a3659af82be54caf3cfd3e
commit | author | age
da0269 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.client;
17
18 import java.awt.BorderLayout;
19 import java.awt.Dimension;
20 import java.awt.FlowLayout;
21 import java.awt.Font;
22 import java.awt.GridLayout;
23 import java.awt.Insets;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
f14f76 26 import java.awt.event.KeyEvent;
da0269 27 import java.text.MessageFormat;
JM 28 import java.util.ArrayList;
29 import java.util.Arrays;
bcc616 30 import java.util.HashSet;
da0269 31 import java.util.List;
b75734 32 import java.util.Map;
bcc616 33 import java.util.Set;
da0269 34
JM 35 import javax.swing.ImageIcon;
36 import javax.swing.JButton;
37 import javax.swing.JCheckBox;
38 import javax.swing.JComponent;
39 import javax.swing.JDialog;
40 import javax.swing.JLabel;
41 import javax.swing.JOptionPane;
42 import javax.swing.JPanel;
43 import javax.swing.JPasswordField;
f14f76 44 import javax.swing.JRootPane;
da0269 45 import javax.swing.JTextField;
f14f76 46 import javax.swing.KeyStroke;
da0269 47
JM 48 import com.gitblit.Constants.AccessRestrictionType;
49 import com.gitblit.Keys;
50 import com.gitblit.models.RepositoryModel;
b75734 51 import com.gitblit.models.SettingModel;
da0269 52 import com.gitblit.models.UserModel;
JM 53 import com.gitblit.utils.StringUtils;
54
55 public class EditUserDialog extends JDialog {
56
57     private static final long serialVersionUID = 1L;
58
59     private final UserModel user;
60
b75734 61     private final Map<String, SettingModel> settings;
da0269 62
bcc616 63     private boolean isCreate;
JM 64     
da0269 65     private boolean canceled = true;
JM 66
67     private JTextField usernameField;
68
69     private JPasswordField passwordField;
70
71     private JPasswordField confirmPasswordField;
72
73     private JCheckBox canAdminCheckbox;
74
75     private JCheckBox notFederatedCheckbox;
76
77     private JPalette<String> repositoryPalette;
78
bcc616 79     private Set<String> usernames;
JM 80
b75734 81     public EditUserDialog(Map<String, SettingModel> settings) {
da0269 82         this(new UserModel(""), settings);
bcc616 83         this.isCreate = true;
JM 84         setTitle(Translation.get("gb.newUser"));        
da0269 85     }
JM 86
b75734 87     public EditUserDialog(UserModel anUser, Map<String, SettingModel> settings) {
da0269 88         super();
JM 89         this.user = new UserModel("");
90         this.settings = settings;
bcc616 91         this.usernames = new HashSet<String>();
JM 92         this.isCreate = false;
da0269 93         initialize(anUser);
JM 94         setModal(true);
b7f591 95         setTitle(Translation.get("gb.edit") + ": " + anUser.username);
da0269 96         setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
f14f76 97     }
JM 98     
99     @Override
100     protected JRootPane createRootPane() {
101         KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
102         JRootPane rootPane = new JRootPane();
103         rootPane.registerKeyboardAction(new ActionListener() {
104             public void actionPerformed(ActionEvent actionEvent) {
105                 setVisible(false);
106             }
107         }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
108         return rootPane;
da0269 109     }
JM 110
111     private void initialize(UserModel anUser) {
112         usernameField = new JTextField(anUser.username == null ? "" : anUser.username, 25);
113         passwordField = new JPasswordField(anUser.password == null ? "" : anUser.password, 25);
114         confirmPasswordField = new JPasswordField(anUser.password == null ? "" : anUser.password,
115                 25);
b7f591 116         canAdminCheckbox = new JCheckBox(Translation.get("gb.canAdminDescription"), anUser.canAdmin);
da0269 117         notFederatedCheckbox = new JCheckBox(
b7f591 118                 Translation.get("gb.excludeFromFederationDescription"),
da0269 119                 anUser.excludeFromFederation);
JM 120
121         JPanel fieldsPanel = new JPanel(new GridLayout(0, 1));
b7f591 122         fieldsPanel.add(newFieldPanel(Translation.get("gb.username"), usernameField));
JM 123         fieldsPanel.add(newFieldPanel(Translation.get("gb.password"), passwordField));
124         fieldsPanel.add(newFieldPanel(Translation.get("gb.confirmPassword"), confirmPasswordField));
125         fieldsPanel.add(newFieldPanel(Translation.get("gb.canAdmin"), canAdminCheckbox));
126         fieldsPanel.add(newFieldPanel(Translation.get("gb.excludeFromFederation"),
127                 notFederatedCheckbox));
da0269 128
JM 129         repositoryPalette = new JPalette<String>();
130         JPanel panel = new JPanel(new BorderLayout());
131         panel.add(fieldsPanel, BorderLayout.NORTH);
b7f591 132         panel.add(newFieldPanel(Translation.get("gb.restrictedRepositories"), repositoryPalette),
JM 133                 BorderLayout.CENTER);
da0269 134
b7f591 135         JButton createButton = new JButton(Translation.get("gb.save"));
da0269 136         createButton.addActionListener(new ActionListener() {
JM 137             public void actionPerformed(ActionEvent event) {
138                 if (validateFields()) {
139                     canceled = false;
140                     setVisible(false);
141                 }
142             }
143         });
144
b7f591 145         JButton cancelButton = new JButton(Translation.get("gb.cancel"));
da0269 146         cancelButton.addActionListener(new ActionListener() {
JM 147             public void actionPerformed(ActionEvent event) {
148                 canceled = true;
149                 setVisible(false);
150             }
151         });
152
153         JPanel controls = new JPanel();
154         controls.add(cancelButton);
155         controls.add(createButton);
156
157         final Insets _insets = new Insets(5, 5, 5, 5);
158         JPanel centerPanel = new JPanel(new BorderLayout(5, 5)) {
159
160             private static final long serialVersionUID = 1L;
161
162             @Override
163             public Insets getInsets() {
164                 return _insets;
165             }
166         };
167         centerPanel.add(panel, BorderLayout.CENTER);
168         centerPanel.add(controls, BorderLayout.SOUTH);
169
170         getContentPane().setLayout(new BorderLayout(5, 5));
171         getContentPane().add(centerPanel, BorderLayout.CENTER);
172         pack();
173     }
174
175     private JPanel newFieldPanel(String label, JComponent comp) {
176         JLabel fieldLabel = new JLabel(label);
177         fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD));
178         fieldLabel.setPreferredSize(new Dimension(150, 20));
179         JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
180         panel.add(fieldLabel);
181         panel.add(comp);
182         return panel;
183     }
184
185     private boolean validateFields() {
186         String uname = usernameField.getText();
187         if (StringUtils.isEmpty(uname)) {
bcc616 188             error("Please enter a username!");
da0269 189             return false;
JM 190         }
191
bcc616 192         // verify username uniqueness on create
JM 193         if (isCreate) {
194             if (usernames.contains(uname.toLowerCase())) {
195                 error(MessageFormat.format("Username ''{0}'' is unavailable.", uname));
196                 return false;
197             }
198         }
da0269 199
b75734 200         int minLength = settings.get(Keys.realm.minPasswordLength).getInteger(5);
da0269 201         if (minLength < 4) {
JM 202             minLength = 4;
203         }
204         char[] pw = passwordField.getPassword();
205         if (pw == null || pw.length < minLength) {
bcc616 206             error(MessageFormat.format(
da0269 207                     "Password is too short. Minimum length is {0} characters.", minLength));
JM 208             return false;
209         }
210         char[] cpw = confirmPasswordField.getPassword();
211         if (cpw == null || cpw.length != pw.length) {
bcc616 212             error("Please confirm the password!");
da0269 213             return false;
JM 214         }
215         if (!Arrays.equals(pw, cpw)) {
bcc616 216             error("Passwords do not match!");
da0269 217             return false;
JM 218         }
219         user.username = uname;
b75734 220         String type = settings.get(Keys.realm.passwordStorage).getString("md5");
da0269 221         if (type.equalsIgnoreCase("md5")) {
JM 222             // store MD5 digest of password
223             user.password = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(pw));
224         } else {
225             user.password = new String(pw);
226         }
227         user.canAdmin = canAdminCheckbox.isSelected();
228         user.excludeFromFederation = notFederatedCheckbox.isSelected();
229
230         user.repositories.clear();
231         user.repositories.addAll(repositoryPalette.getSelections());
232         return true;
233     }
234
bcc616 235     private void error(String message) {
b7f591 236         JOptionPane.showMessageDialog(EditUserDialog.this, message, Translation.get("gb.error"),
da0269 237                 JOptionPane.ERROR_MESSAGE);
JM 238     }
239
bcc616 240     public void setUsers(List<UserModel> users) {
JM 241         usernames.clear();
242         for (UserModel user : users) {
243             usernames.add(user.username.toLowerCase());
244         }
245     }
246
da0269 247     public void setRepositories(List<RepositoryModel> repositories, List<String> selected) {
JM 248         List<String> restricted = new ArrayList<String>();
249         for (RepositoryModel repo : repositories) {
250             if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
251                 restricted.add(repo.name);
252             }
253         }
254         StringUtils.sortRepositorynames(restricted);
255         if (selected != null) {
256             StringUtils.sortRepositorynames(selected);
257         }
258         repositoryPalette.setObjects(restricted, selected);
259     }
260
261     public UserModel getUser() {
262         if (canceled) {
263             return null;
264         }
265         return user;
266     }
267 }