]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewUser.java
Re-add org.argeo.cms.util.useradmin
[lgpl/argeo-commons.git] / org.argeo.security.ui.admin / src / org / argeo / security / ui / admin / internal / commands / NewUser.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
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 org.argeo.security.ui.admin.internal.commands;
17
18 import java.util.Dictionary;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.naming.InvalidNameException;
23 import javax.naming.ldap.LdapName;
24 import javax.naming.ldap.Rdn;
25
26 import org.argeo.ArgeoException;
27 import org.argeo.eclipse.ui.EclipseUiUtils;
28 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
29 import org.argeo.jcr.ArgeoNames;
30 import org.argeo.osgi.useradmin.LdifName;
31 import org.argeo.osgi.useradmin.UserAdminConf;
32 import org.argeo.security.ui.admin.SecurityAdminPlugin;
33 import org.argeo.security.ui.admin.internal.UserAdminUtils;
34 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
35 import org.eclipse.core.commands.AbstractHandler;
36 import org.eclipse.core.commands.ExecutionEvent;
37 import org.eclipse.core.commands.ExecutionException;
38 import org.eclipse.jface.wizard.Wizard;
39 import org.eclipse.jface.wizard.WizardDialog;
40 import org.eclipse.jface.wizard.WizardPage;
41 import org.eclipse.swt.SWT;
42 import org.eclipse.swt.events.ModifyEvent;
43 import org.eclipse.swt.events.ModifyListener;
44 import org.eclipse.swt.layout.GridData;
45 import org.eclipse.swt.layout.GridLayout;
46 import org.eclipse.swt.widgets.Combo;
47 import org.eclipse.swt.widgets.Composite;
48 import org.eclipse.swt.widgets.Label;
49 import org.eclipse.swt.widgets.Text;
50 import org.eclipse.ui.handlers.HandlerUtil;
51 import org.osgi.service.useradmin.Role;
52 import org.osgi.service.useradmin.User;
53 import org.osgi.service.useradmin.UserAdminEvent;
54
55 /** Open a wizard that enables creation of a new user. */
56 public class NewUser extends AbstractHandler {
57 /**
58 * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}.
59 * Thanks to <a href=
60 * "http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/"
61 * >this tip</a>.
62 */
63 public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
64 // private final static Log log = LogFactory.getLog(NewUser.class);
65 public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".newUser";
66
67 /* DEPENDENCY INJECTION */
68 private UserAdminWrapper userAdminWrapper;
69
70 public Object execute(ExecutionEvent event) throws ExecutionException {
71 NewUserWizard newUserWizard = new NewUserWizard();
72 newUserWizard.setWindowTitle("User creation");
73 WizardDialog dialog = new WizardDialog(
74 HandlerUtil.getActiveShell(event), newUserWizard);
75 dialog.open();
76 return null;
77 }
78
79 private class NewUserWizard extends Wizard {
80
81 // pages
82 private MainUserInfoWizardPage mainUserInfo;
83
84 // End user fields
85 private Text dNameTxt, usernameTxt, firstNameTxt, lastNameTxt,
86 primaryMailTxt, pwd1Txt, pwd2Txt;
87 private Combo baseDnCmb;
88
89 public NewUserWizard() {
90
91 }
92
93 @Override
94 public void addPages() {
95 mainUserInfo = new MainUserInfoWizardPage();
96 addPage(mainUserInfo);
97 String message = "Default wizard that also eases user creation tests:\n "
98 + "Mail and last name are automatically "
99 + "generated form the uid. Password are defauted to 'demo'.";
100 mainUserInfo.setMessage(message, WizardPage.WARNING);
101 }
102
103 @SuppressWarnings({ "rawtypes", "unchecked" })
104 @Override
105 public boolean performFinish() {
106 if (!canFinish())
107 return false;
108 String username = mainUserInfo.getUsername();
109 try {
110 userAdminWrapper.beginTransactionIfNeeded();
111 User user = (User) userAdminWrapper.getUserAdmin().createRole(
112 getDn(username), Role.USER);
113
114 Dictionary props = user.getProperties();
115
116 String lastNameStr = lastNameTxt.getText();
117 if (EclipseUiUtils.notEmpty(lastNameStr))
118 props.put(LdifName.sn.name(), lastNameStr);
119
120 String firstNameStr = firstNameTxt.getText();
121 if (EclipseUiUtils.notEmpty(firstNameStr))
122 props.put(LdifName.givenName.name(), firstNameStr);
123
124 String cn = UserAdminUtils.buildDefaultCn(firstNameStr,
125 lastNameStr);
126 if (EclipseUiUtils.notEmpty(cn))
127 props.put(LdifName.cn.name(), cn);
128
129 String mailStr = primaryMailTxt.getText();
130 if (EclipseUiUtils.notEmpty(mailStr))
131 props.put(LdifName.mail.name(), mailStr);
132
133 char[] password = mainUserInfo.getPassword();
134 user.getCredentials().put(null, password);
135
136 userAdminWrapper.notifyListeners(new UserAdminEvent(null,
137 UserAdminEvent.ROLE_CREATED, user));
138 return true;
139 } catch (Exception e) {
140 ErrorFeedback.show("Cannot create new user " + username, e);
141 return false;
142 }
143 }
144
145 private class MainUserInfoWizardPage extends WizardPage implements
146 ModifyListener, ArgeoNames {
147 private static final long serialVersionUID = -3150193365151601807L;
148
149 public MainUserInfoWizardPage() {
150 super("Main");
151 setTitle("Required Information");
152 }
153
154 @Override
155 public void createControl(Composite parent) {
156 Composite composite = new Composite(parent, SWT.NONE);
157 composite.setLayout(new GridLayout(2, false));
158 dNameTxt = EclipseUiUtils.createGridLT(composite,
159 "Distinguished name", this);
160 dNameTxt.setEnabled(false);
161
162 baseDnCmb = createGridLC(composite, "Base DN");
163 initialiseDnCmb(baseDnCmb);
164 baseDnCmb.addModifyListener(this);
165 baseDnCmb.addModifyListener(new ModifyListener() {
166 private static final long serialVersionUID = -1435351236582736843L;
167
168 @Override
169 public void modifyText(ModifyEvent event) {
170 String name = usernameTxt.getText();
171 dNameTxt.setText(getDn(name));
172 }
173 });
174
175 usernameTxt = EclipseUiUtils.createGridLT(composite,
176 "Local ID", this);
177 usernameTxt.addModifyListener(new ModifyListener() {
178 private static final long serialVersionUID = -1435351236582736843L;
179
180 @Override
181 public void modifyText(ModifyEvent event) {
182 String name = usernameTxt.getText();
183 if (name.trim().equals("")) {
184 dNameTxt.setText("");
185 lastNameTxt.setText("");
186 primaryMailTxt.setText("");
187 pwd1Txt.setText("");
188 pwd2Txt.setText("");
189 } else {
190 dNameTxt.setText(getDn(name));
191 lastNameTxt.setText(name.toUpperCase());
192 primaryMailTxt.setText(getMail(name));
193 pwd1Txt.setText("demo");
194 pwd2Txt.setText("demo");
195 }
196 }
197 });
198
199 primaryMailTxt = EclipseUiUtils.createGridLT(composite,
200 "Email", this);
201 firstNameTxt = EclipseUiUtils.createGridLT(composite,
202 "First name", this);
203 lastNameTxt = EclipseUiUtils.createGridLT(composite,
204 "Last name", this);
205 pwd1Txt = EclipseUiUtils.createGridLP(composite, "Password",
206 this);
207 pwd2Txt = EclipseUiUtils.createGridLP(composite,
208 "Repeat password", this);
209 setControl(composite);
210
211 // Initialize buttons
212 setPageComplete(false);
213 getContainer().updateButtons();
214 }
215
216 @Override
217 public void modifyText(ModifyEvent event) {
218 String message = checkComplete();
219 if (message != null) {
220 setMessage(message, WizardPage.ERROR);
221 setPageComplete(false);
222 } else {
223 setMessage("Complete", WizardPage.INFORMATION);
224 setPageComplete(true);
225 }
226 getContainer().updateButtons();
227 }
228
229 /** @return error message or null if complete */
230 protected String checkComplete() {
231 String name = usernameTxt.getText();
232
233 if (name.trim().equals(""))
234 return "User name must not be empty";
235 Role role = userAdminWrapper.getUserAdmin()
236 .getRole(getDn(name));
237 if (role != null)
238 return "User " + name + " already exists";
239 if (!primaryMailTxt.getText().matches(EMAIL_PATTERN))
240 return "Not a valid email address";
241 if (lastNameTxt.getText().trim().equals(""))
242 return "Specify a last name";
243 if (pwd1Txt.getText().trim().equals(""))
244 return "Specify a password";
245 if (pwd2Txt.getText().trim().equals(""))
246 return "Repeat the password";
247 if (!pwd2Txt.getText().equals(pwd1Txt.getText()))
248 return "Passwords are different";
249 return null;
250 }
251
252 @Override
253 public void setVisible(boolean visible) {
254 super.setVisible(visible);
255 if (visible)
256 if (baseDnCmb.getSelectionIndex() == -1)
257 baseDnCmb.setFocus();
258 else
259 usernameTxt.setFocus();
260 }
261
262 public String getUsername() {
263 return usernameTxt.getText();
264 }
265
266 public char[] getPassword() {
267 return pwd1Txt.getTextChars();
268 }
269
270 }
271
272 private Map<String, String> getDns() {
273 return userAdminWrapper.getKnownBaseDns(true);
274 }
275
276 private String getDn(String uid) {
277 Map<String, String> dns = getDns();
278 String bdn = baseDnCmb.getText();
279 if (EclipseUiUtils.notEmpty(bdn)) {
280 Dictionary<String, ?> props = UserAdminConf.uriAsProperties(dns
281 .get(bdn));
282 String dn = LdifName.uid.name() + "=" + uid + ","
283 + UserAdminConf.userBase.getValue(props) + "," + bdn;
284 return dn;
285 }
286 return null;
287 }
288
289 private void initialiseDnCmb(Combo combo) {
290 Map<String, String> dns = userAdminWrapper.getKnownBaseDns(true);
291 if (dns.isEmpty())
292 throw new ArgeoException(
293 "No writable base dn found. Cannot create user");
294 combo.setItems(dns.keySet().toArray(new String[0]));
295 if (dns.size() == 1)
296 combo.select(0);
297 }
298
299 private String getMail(String username) {
300 if (baseDnCmb.getSelectionIndex() == -1)
301 return null;
302 String baseDn = baseDnCmb.getText();
303 try {
304 LdapName name = new LdapName(baseDn);
305 List<Rdn> rdns = name.getRdns();
306 return username + "@" + (String) rdns.get(1).getValue() + '.'
307 + (String) rdns.get(0).getValue();
308 } catch (InvalidNameException e) {
309 throw new ArgeoException("Unable to generate mail for "
310 + username + " with base dn " + baseDn, e);
311 }
312 }
313 }
314
315 private Combo createGridLC(Composite parent, String label) {
316 Label lbl = new Label(parent, SWT.LEAD);
317 lbl.setText(label);
318 lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
319 Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY);
320 combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
321 return combo;
322 }
323
324 /* DEPENDENCY INJECTION */
325 public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
326 this.userAdminWrapper = userAdminWrapper;
327 }
328 }