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