James Moger
2012-09-10 fabe060d3a435f116128851f828e35c2af5fde67
commit | author | age
f13c4c 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  */
dfb889 16 package com.gitblit.wicket.pages;
JM 17
a098da 18 import java.text.MessageFormat;
dfb889 19 import java.util.ArrayList;
fe24a0 20 import java.util.Collections;
dfb889 21 import java.util.Iterator;
JM 22 import java.util.List;
23
24 import org.apache.wicket.PageParameters;
d3ca1c 25 import org.apache.wicket.behavior.SimpleAttributeModifier;
dfb889 26 import org.apache.wicket.extensions.markup.html.form.palette.Palette;
331fbc 27 import org.apache.wicket.markup.html.form.Button;
dfb889 28 import org.apache.wicket.markup.html.form.CheckBox;
JM 29 import org.apache.wicket.markup.html.form.Form;
30 import org.apache.wicket.markup.html.form.PasswordTextField;
31 import org.apache.wicket.markup.html.form.TextField;
32 import org.apache.wicket.model.CompoundPropertyModel;
33 import org.apache.wicket.model.Model;
34 import org.apache.wicket.model.util.CollectionModel;
35 import org.apache.wicket.model.util.ListModel;
36
f98825 37 import com.gitblit.Constants.AccessRestrictionType;
dfb889 38 import com.gitblit.GitBlit;
JM 39 import com.gitblit.GitBlitException;
f98825 40 import com.gitblit.Keys;
1f9dae 41 import com.gitblit.models.RepositoryModel;
fe24a0 42 import com.gitblit.models.TeamModel;
1f9dae 43 import com.gitblit.models.UserModel;
f98825 44 import com.gitblit.utils.StringUtils;
1f9dae 45 import com.gitblit.wicket.RequiresAdminRole;
6fa6ab 46 import com.gitblit.wicket.StringChoiceRenderer;
dfb889 47 import com.gitblit.wicket.WicketUtils;
JM 48
1f9dae 49 @RequiresAdminRole
d376ab 50 public class EditUserPage extends RootSubPage {
dfb889 51
JM 52     private final boolean isCreate;
53
54     public EditUserPage() {
55         // create constructor
56         super();
6cca86 57         if (!GitBlit.self().supportsCredentialChanges()) {
JM 58             error(MessageFormat.format(getString("gb.userServiceDoesNotPermitAddUser"),
59                     GitBlit.getString(Keys.realm.userService, "users.conf")), true);
60         }
dfb889 61         isCreate = true;
511554 62         setupPage(new UserModel(""));
dfb889 63     }
JM 64
65     public EditUserPage(PageParameters params) {
66         // edit constructor
67         super(params);
68         isCreate = false;
69         String name = WicketUtils.getUsername(params);
f98825 70         UserModel model = GitBlit.self().getUserModel(name);
dfb889 71         setupPage(model);
JM 72     }
73
511554 74     protected void setupPage(final UserModel userModel) {
dfb889 75         if (isCreate) {
a7571b 76             super.setupPage(getString("gb.newUser"), "");
dfb889 77         } else {
a7571b 78             super.setupPage(getString("gb.edit"), userModel.username);
dfb889 79         }
d5623a 80
2a7306 81         final Model<String> confirmPassword = new Model<String>(
JM 82                 StringUtils.isEmpty(userModel.password) ? "" : userModel.password);
511554 83         CompoundPropertyModel<UserModel> model = new CompoundPropertyModel<UserModel>(userModel);
dfb889 84
f98825 85         List<String> repos = new ArrayList<String>();
JM 86         for (String repo : GitBlit.self().getRepositoryList()) {
87             RepositoryModel repositoryModel = GitBlit.self().getRepositoryModel(repo);
88             if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
89                 repos.add(repo);
90             }
91         }
fe24a0 92         List<String> userTeams = new ArrayList<String>();
JM 93         for (TeamModel team : userModel.teams) {
94             userTeams.add(team.name);
95         }
96         Collections.sort(userTeams);
97         
2a7306 98         final String oldName = userModel.username;
JM 99         final Palette<String> repositories = new Palette<String>("repositories",
831469 100                 new ListModel<String>(new ArrayList<String>(userModel.repositories)),
6fa6ab 101                 new CollectionModel<String>(repos), new StringChoiceRenderer(), 10, false);
fe24a0 102         final Palette<String> teams = new Palette<String>("teams", new ListModel<String>(
JM 103                 new ArrayList<String>(userTeams)), new CollectionModel<String>(GitBlit.self()
6fa6ab 104                 .getAllTeamnames()), new StringChoiceRenderer(), 10, false);
511554 105         Form<UserModel> form = new Form<UserModel>("editForm", model) {
dfb889 106
JM 107             private static final long serialVersionUID = 1L;
108
a098da 109             /*
JM 110              * (non-Javadoc)
111              * 
112              * @see org.apache.wicket.markup.html.form.Form#onSubmit()
113              */
dfb889 114             @Override
JM 115             protected void onSubmit() {
ae0b13 116                 if (StringUtils.isEmpty(userModel.username)) {
6caa93 117                     error(getString("gb.pleaseSetUsername"));
a098da 118                     return;
JM 119                 }
ae0b13 120                 // force username to lower-case
JM 121                 userModel.username = userModel.username.toLowerCase();
122                 String username = userModel.username;
a098da 123                 if (isCreate) {
JM 124                     UserModel model = GitBlit.self().getUserModel(username);
125                     if (model != null) {
6caa93 126                         error(MessageFormat.format(getString("gb.usernameUnavailable"), username));
a098da 127                         return;
JM 128                     }
129                 }
fe24a0 130                 boolean rename = !StringUtils.isEmpty(oldName)
JM 131                         && !oldName.equalsIgnoreCase(username);
f3b625 132                 if (GitBlit.self().supportsCredentialChanges()) {
JC 133                     if (!userModel.password.equals(confirmPassword.getObject())) {
134                         error(getString("gb.passwordsDoNotMatch"));
a098da 135                         return;
JM 136                     }
f3b625 137                     String password = userModel.password;
JC 138                     if (!password.toUpperCase().startsWith(StringUtils.MD5_TYPE)
139                             && !password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
140                         // This is a plain text password.
141                         // Check length.
142                         int minLength = GitBlit.getInteger(Keys.realm.minPasswordLength, 5);
143                         if (minLength < 4) {
144                             minLength = 4;
145                         }
146                         if (password.trim().length() < minLength) {
147                             error(MessageFormat.format(getString("gb.passwordTooShort"),
148                                     minLength));
149                             return;
150                         }
151     
152                         // Optionally store the password MD5 digest.
153                         String type = GitBlit.getString(Keys.realm.passwordStorage, "md5");
154                         if (type.equalsIgnoreCase("md5")) {
155                             // store MD5 digest of password
156                             userModel.password = StringUtils.MD5_TYPE
157                                     + StringUtils.getMD5(userModel.password);
158                         } else if (type.equalsIgnoreCase("combined-md5")) {
159                             // store MD5 digest of username+password
160                             userModel.password = StringUtils.COMBINED_MD5_TYPE
161                                     + StringUtils.getMD5(username + userModel.password);
162                         }
163                     } else if (rename
164                             && password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
165                         error(getString("gb.combinedMd5Rename"));
166                         return;
f98825 167                     }
JM 168                 }
169
dfb889 170                 Iterator<String> selectedRepositories = repositories.getSelectedChoices();
JM 171                 List<String> repos = new ArrayList<String>();
172                 while (selectedRepositories.hasNext()) {
28d6b2 173                     repos.add(selectedRepositories.next().toLowerCase());
dfb889 174                 }
28d6b2 175                 userModel.repositories.clear();
db653a 176                 userModel.repositories.addAll(repos);
fe24a0 177
JM 178                 Iterator<String> selectedTeams = teams.getSelectedChoices();
179                 userModel.teams.clear();
180                 while (selectedTeams.hasNext()) {
181                     TeamModel team = GitBlit.self().getTeamModel(selectedTeams.next());
182                     if (team == null) {
183                         continue;
184                     }
185                     userModel.teams.add(team);
186                 }
187
ae0b13 188                 try {                    
892570 189                     GitBlit.self().updateUserModel(oldName, userModel, isCreate);
dfb889 190                 } catch (GitBlitException e) {
JM 191                     error(e.getMessage());
192                     return;
193                 }
a098da 194                 setRedirect(false);
f98825 195                 if (isCreate) {
JM 196                     // create another user
6caa93 197                     info(MessageFormat.format(getString("gb.userCreated"),
2a7306 198                             userModel.username));
f98825 199                     setResponsePage(EditUserPage.class);
JM 200                 } else {
d376ab 201                     // back to users page
JM 202                     setResponsePage(UsersPage.class);
f98825 203                 }
dfb889 204             }
JM 205         };
d3ca1c 206         
JM 207         // do not let the browser pre-populate these fields
208         form.add(new SimpleAttributeModifier("autocomplete", "off"));
6cca86 209         
JM 210         // not all user services support manipulating username and password
211         boolean editCredentials = GitBlit.self().supportsCredentialChanges();
0aa8cf 212         
JM 213         // not all user services support manipulating display name
214         boolean editDisplayName = GitBlit.self().supportsDisplayNameChanges();
215
216         // not all user services support manipulating email address
217         boolean editEmailAddress = GitBlit.self().supportsEmailAddressChanges();
6cca86 218
JM 219         // not all user services support manipulating team memberships
220         boolean editTeams = GitBlit.self().supportsTeamMembershipChanges();
dfb889 221
JM 222         // field names reflective match UserModel fields
6cca86 223         form.add(new TextField<String>("username").setEnabled(editCredentials));
f98825 224         PasswordTextField passwordField = new PasswordTextField("password");
JM 225         passwordField.setResetPassword(false);
6cca86 226         form.add(passwordField.setEnabled(editCredentials));
2a7306 227         PasswordTextField confirmPasswordField = new PasswordTextField("confirmPassword",
JM 228                 confirmPassword);
f98825 229         confirmPasswordField.setResetPassword(false);
6cca86 230         form.add(confirmPasswordField.setEnabled(editCredentials));
0aa8cf 231         form.add(new TextField<String>("displayName").setEnabled(editDisplayName));
JM 232         form.add(new TextField<String>("emailAddress").setEnabled(editEmailAddress));
dfb889 233         form.add(new CheckBox("canAdmin"));
831469 234         form.add(new CheckBox("excludeFromFederation"));
dfb889 235         form.add(repositories);
6cca86 236         form.add(teams.setEnabled(editTeams));
88598b 237
719798 238         form.add(new Button("save"));
JM 239         Button cancel = new Button("cancel") {
331fbc 240             private static final long serialVersionUID = 1L;
JM 241
242             @Override
243             public void onSubmit() {
8c5d72 244                 setResponsePage(UsersPage.class);
88598b 245             }
JM 246         };
247         cancel.setDefaultFormProcessing(false);
248         form.add(cancel);
249
dfb889 250         add(form);
JM 251     }
252 }