You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EditUserPage.java 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  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.wicket.pages;
  17. import java.text.MessageFormat;
  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import org.apache.wicket.PageParameters;
  23. import org.apache.wicket.behavior.SimpleAttributeModifier;
  24. import org.apache.wicket.extensions.markup.html.form.palette.Palette;
  25. import org.apache.wicket.markup.html.form.Button;
  26. import org.apache.wicket.markup.html.form.CheckBox;
  27. import org.apache.wicket.markup.html.form.Form;
  28. import org.apache.wicket.markup.html.form.PasswordTextField;
  29. import org.apache.wicket.markup.html.form.TextField;
  30. import org.apache.wicket.model.CompoundPropertyModel;
  31. import org.apache.wicket.model.Model;
  32. import org.apache.wicket.model.util.CollectionModel;
  33. import org.apache.wicket.model.util.ListModel;
  34. import com.gitblit.Constants.RegistrantType;
  35. import com.gitblit.GitBlitException;
  36. import com.gitblit.Keys;
  37. import com.gitblit.models.RegistrantAccessPermission;
  38. import com.gitblit.models.TeamModel;
  39. import com.gitblit.models.UserModel;
  40. import com.gitblit.utils.StringUtils;
  41. import com.gitblit.wicket.RequiresAdminRole;
  42. import com.gitblit.wicket.StringChoiceRenderer;
  43. import com.gitblit.wicket.WicketUtils;
  44. import com.gitblit.wicket.panels.RegistrantPermissionsPanel;
  45. @RequiresAdminRole
  46. public class EditUserPage extends RootSubPage {
  47. private final boolean isCreate;
  48. public EditUserPage() {
  49. // create constructor
  50. super();
  51. isCreate = true;
  52. setupPage(new UserModel(""));
  53. setStatelessHint(false);
  54. setOutputMarkupId(true);
  55. }
  56. public EditUserPage(PageParameters params) {
  57. // edit constructor
  58. super(params);
  59. isCreate = false;
  60. String name = WicketUtils.getUsername(params);
  61. UserModel model = app().users().getUserModel(name);
  62. setupPage(model);
  63. setStatelessHint(false);
  64. setOutputMarkupId(true);
  65. }
  66. @Override
  67. protected boolean requiresPageMap() {
  68. return true;
  69. }
  70. @Override
  71. protected Class<? extends BasePage> getRootNavPageClass() {
  72. return UsersPage.class;
  73. }
  74. protected void setupPage(final UserModel userModel) {
  75. if (isCreate) {
  76. super.setupPage(getString("gb.newUser"), "");
  77. } else {
  78. super.setupPage(getString("gb.edit"), userModel.username);
  79. }
  80. final Model<String> confirmPassword = new Model<String>(
  81. StringUtils.isEmpty(userModel.password) ? "" : userModel.password);
  82. CompoundPropertyModel<UserModel> model = new CompoundPropertyModel<UserModel>(userModel);
  83. // build list of projects including all repositories wildcards
  84. List<String> repos = getAccessRestrictedRepositoryList(true, userModel);
  85. List<String> userTeams = new ArrayList<String>();
  86. for (TeamModel team : userModel.teams) {
  87. userTeams.add(team.name);
  88. }
  89. Collections.sort(userTeams);
  90. final String oldName = userModel.username;
  91. final List<RegistrantAccessPermission> permissions = app().repositories().getUserAccessPermissions(userModel);
  92. final Palette<String> teams = new Palette<String>("teams", new ListModel<String>(
  93. new ArrayList<String>(userTeams)), new CollectionModel<String>(app().users()
  94. .getAllTeamNames()), new StringChoiceRenderer(), 10, false);
  95. Form<UserModel> form = new Form<UserModel>("editForm", model) {
  96. private static final long serialVersionUID = 1L;
  97. /*
  98. * (non-Javadoc)
  99. *
  100. * @see org.apache.wicket.markup.html.form.Form#onSubmit()
  101. */
  102. @Override
  103. protected void onSubmit() {
  104. if (StringUtils.isEmpty(userModel.username)) {
  105. error(getString("gb.pleaseSetUsername"));
  106. return;
  107. }
  108. // force username to lower-case
  109. userModel.username = userModel.username.toLowerCase();
  110. String username = userModel.username;
  111. if (isCreate) {
  112. UserModel model = app().users().getUserModel(username);
  113. if (model != null) {
  114. error(MessageFormat.format(getString("gb.usernameUnavailable"), username));
  115. return;
  116. }
  117. }
  118. boolean rename = !StringUtils.isEmpty(oldName)
  119. && !oldName.equalsIgnoreCase(username);
  120. if (app().authentication().supportsCredentialChanges(userModel)) {
  121. if (!userModel.password.equals(confirmPassword.getObject())) {
  122. error(getString("gb.passwordsDoNotMatch"));
  123. return;
  124. }
  125. String password = userModel.password;
  126. if (!password.toUpperCase().startsWith(StringUtils.MD5_TYPE)
  127. && !password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
  128. // This is a plain text password.
  129. // Check length.
  130. int minLength = app().settings().getInteger(Keys.realm.minPasswordLength, 5);
  131. if (minLength < 4) {
  132. minLength = 4;
  133. }
  134. if (password.trim().length() < minLength) {
  135. error(MessageFormat.format(getString("gb.passwordTooShort"),
  136. minLength));
  137. return;
  138. }
  139. // change the cookie
  140. userModel.cookie = StringUtils.getSHA1(userModel.username + password);
  141. // Optionally store the password MD5 digest.
  142. String type = app().settings().getString(Keys.realm.passwordStorage, "md5");
  143. if (type.equalsIgnoreCase("md5")) {
  144. // store MD5 digest of password
  145. userModel.password = StringUtils.MD5_TYPE
  146. + StringUtils.getMD5(userModel.password);
  147. } else if (type.equalsIgnoreCase("combined-md5")) {
  148. // store MD5 digest of username+password
  149. userModel.password = StringUtils.COMBINED_MD5_TYPE
  150. + StringUtils.getMD5(username + userModel.password);
  151. }
  152. } else if (rename
  153. && password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
  154. error(getString("gb.combinedMd5Rename"));
  155. return;
  156. }
  157. }
  158. // update user permissions
  159. for (RegistrantAccessPermission repositoryPermission : permissions) {
  160. userModel.setRepositoryPermission(repositoryPermission.registrant, repositoryPermission.permission);
  161. }
  162. Iterator<String> selectedTeams = teams.getSelectedChoices();
  163. userModel.teams.clear();
  164. while (selectedTeams.hasNext()) {
  165. TeamModel team = app().users().getTeamModel(selectedTeams.next());
  166. if (team == null) {
  167. continue;
  168. }
  169. userModel.teams.add(team);
  170. }
  171. try {
  172. if (isCreate) {
  173. app().gitblit().addUser(userModel);
  174. } else {
  175. app().gitblit().reviseUser(oldName, userModel);
  176. }
  177. } catch (GitBlitException e) {
  178. error(e.getMessage());
  179. return;
  180. }
  181. setRedirect(false);
  182. if (isCreate) {
  183. // create another user
  184. info(MessageFormat.format(getString("gb.userCreated"),
  185. userModel.username));
  186. setResponsePage(EditUserPage.class);
  187. } else {
  188. // back to users page
  189. setResponsePage(UsersPage.class);
  190. }
  191. }
  192. };
  193. // do not let the browser pre-populate these fields
  194. form.add(new SimpleAttributeModifier("autocomplete", "off"));
  195. // not all user services support manipulating username and password
  196. boolean editCredentials = app().authentication().supportsCredentialChanges(userModel);
  197. // not all user services support manipulating display name
  198. boolean editDisplayName = app().authentication().supportsDisplayNameChanges(userModel);
  199. // not all user services support manipulating email address
  200. boolean editEmailAddress = app().authentication().supportsEmailAddressChanges(userModel);
  201. // not all user services support manipulating team memberships
  202. boolean editTeams = app().authentication().supportsTeamMembershipChanges(userModel);
  203. // field names reflective match UserModel fields
  204. form.add(new TextField<String>("username").setEnabled(editCredentials));
  205. PasswordTextField passwordField = new PasswordTextField("password");
  206. passwordField.setResetPassword(false);
  207. form.add(passwordField.setEnabled(editCredentials));
  208. PasswordTextField confirmPasswordField = new PasswordTextField("confirmPassword",
  209. confirmPassword);
  210. confirmPasswordField.setResetPassword(false);
  211. form.add(confirmPasswordField.setEnabled(editCredentials));
  212. form.add(new TextField<String>("displayName").setEnabled(editDisplayName));
  213. form.add(new TextField<String>("emailAddress").setEnabled(editEmailAddress));
  214. form.add(new CheckBox("canAdmin"));
  215. form.add(new CheckBox("canFork").setEnabled(app().settings().getBoolean(Keys.web.allowForking, true)));
  216. form.add(new CheckBox("canCreate"));
  217. form.add(new CheckBox("excludeFromFederation"));
  218. form.add(new RegistrantPermissionsPanel("repositories", RegistrantType.REPOSITORY, repos, permissions, getAccessPermissions()));
  219. form.add(teams.setEnabled(editTeams));
  220. form.add(new TextField<String>("organizationalUnit").setEnabled(editDisplayName));
  221. form.add(new TextField<String>("organization").setEnabled(editDisplayName));
  222. form.add(new TextField<String>("locality").setEnabled(editDisplayName));
  223. form.add(new TextField<String>("stateProvince").setEnabled(editDisplayName));
  224. form.add(new TextField<String>("countryCode").setEnabled(editDisplayName));
  225. form.add(new Button("save"));
  226. Button cancel = new Button("cancel") {
  227. private static final long serialVersionUID = 1L;
  228. @Override
  229. public void onSubmit() {
  230. setResponsePage(UsersPage.class);
  231. }
  232. };
  233. cancel.setDefaultFormProcessing(false);
  234. form.add(cancel);
  235. add(form);
  236. }
  237. }