2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.security
.ui
.admin
.internal
.commands
;
18 import java
.util
.Dictionary
;
19 import java
.util
.List
;
21 import javax
.naming
.InvalidNameException
;
22 import javax
.naming
.ldap
.LdapName
;
23 import javax
.naming
.ldap
.Rdn
;
25 import org
.argeo
.ArgeoException
;
26 import org
.argeo
.eclipse
.ui
.EclipseUiUtils
;
27 import org
.argeo
.eclipse
.ui
.dialogs
.ErrorFeedback
;
28 import org
.argeo
.jcr
.ArgeoNames
;
29 import org
.argeo
.osgi
.useradmin
.LdifName
;
30 import org
.argeo
.security
.ui
.admin
.SecurityAdminPlugin
;
31 import org
.argeo
.security
.ui
.admin
.internal
.UiAdminUtils
;
32 import org
.argeo
.security
.ui
.admin
.internal
.UserAdminWrapper
;
33 import org
.eclipse
.core
.commands
.AbstractHandler
;
34 import org
.eclipse
.core
.commands
.ExecutionEvent
;
35 import org
.eclipse
.core
.commands
.ExecutionException
;
36 import org
.eclipse
.jface
.wizard
.Wizard
;
37 import org
.eclipse
.jface
.wizard
.WizardDialog
;
38 import org
.eclipse
.jface
.wizard
.WizardPage
;
39 import org
.eclipse
.swt
.SWT
;
40 import org
.eclipse
.swt
.events
.ModifyEvent
;
41 import org
.eclipse
.swt
.events
.ModifyListener
;
42 import org
.eclipse
.swt
.layout
.GridData
;
43 import org
.eclipse
.swt
.layout
.GridLayout
;
44 import org
.eclipse
.swt
.widgets
.Combo
;
45 import org
.eclipse
.swt
.widgets
.Composite
;
46 import org
.eclipse
.swt
.widgets
.Label
;
47 import org
.eclipse
.swt
.widgets
.Text
;
48 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
49 import org
.osgi
.service
.useradmin
.Role
;
50 import org
.osgi
.service
.useradmin
.User
;
51 import org
.osgi
.service
.useradmin
.UserAdminEvent
;
53 /** Open a wizard that enables creation of a new user. */
54 public class NewUser
extends AbstractHandler
{
56 * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}.
58 * "http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/"
61 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,})$";
62 // private final static Log log = LogFactory.getLog(NewUser.class);
63 public final static String ID
= SecurityAdminPlugin
.PLUGIN_ID
+ ".newUser";
65 /* DEPENDENCY INJECTION */
66 private UserAdminWrapper userAdminWrapper
;
68 public Object
execute(ExecutionEvent event
) throws ExecutionException
{
69 NewUserWizard newUserWizard
= new NewUserWizard();
70 newUserWizard
.setWindowTitle("User creation");
71 WizardDialog dialog
= new WizardDialog(
72 HandlerUtil
.getActiveShell(event
), newUserWizard
);
77 private class NewUserWizard
extends Wizard
{
80 private MainUserInfoWizardPage mainUserInfo
;
83 private Text dNameTxt
, usernameTxt
, firstNameTxt
, lastNameTxt
,
84 primaryMailTxt
, pwd1Txt
, pwd2Txt
;
85 private Combo baseDnCmb
;
87 public NewUserWizard() {
92 public void addPages() {
93 mainUserInfo
= new MainUserInfoWizardPage();
94 addPage(mainUserInfo
);
95 String message
= "Default wizard that also eases user creation tests:\n "
96 + "Mail and last name are automatically "
97 + "generated form the uid. Password are defauted to 'demo'.";
98 mainUserInfo
.setMessage(message
, WizardPage
.WARNING
);
101 @SuppressWarnings({ "rawtypes", "unchecked" })
103 public boolean performFinish() {
106 String username
= mainUserInfo
.getUsername();
108 userAdminWrapper
.beginTransactionIfNeeded();
109 User user
= (User
) userAdminWrapper
.getUserAdmin().createRole(
110 getDn(username
), Role
.USER
);
112 Dictionary props
= user
.getProperties();
114 String lastNameStr
= lastNameTxt
.getText();
115 if (UiAdminUtils
.notNull(lastNameStr
))
116 props
.put(LdifName
.sn
.name(), lastNameStr
);
118 String firstNameStr
= firstNameTxt
.getText();
119 if (UiAdminUtils
.notNull(firstNameStr
))
120 props
.put(LdifName
.givenname
.name(), firstNameStr
);
122 String cn
= UiAdminUtils
123 .getDefaultCn(firstNameStr
, lastNameStr
);
124 if (UiAdminUtils
.notNull(cn
))
125 props
.put(LdifName
.cn
.name(), cn
);
127 String mailStr
= primaryMailTxt
.getText();
128 if (UiAdminUtils
.notNull(mailStr
))
129 props
.put(LdifName
.mail
.name(), mailStr
);
131 char[] password
= mainUserInfo
.getPassword();
132 user
.getCredentials().put(null, password
);
134 userAdminWrapper
.notifyListeners(new UserAdminEvent(null,
135 UserAdminEvent
.ROLE_CREATED
, user
));
137 } catch (Exception e
) {
138 ErrorFeedback
.show("Cannot create new user " + username
, e
);
143 private class MainUserInfoWizardPage
extends WizardPage
implements
144 ModifyListener
, ArgeoNames
{
145 private static final long serialVersionUID
= -3150193365151601807L;
147 public MainUserInfoWizardPage() {
149 setTitle("Required Information");
153 public void createControl(Composite parent
) {
154 Composite composite
= new Composite(parent
, SWT
.NONE
);
155 composite
.setLayout(new GridLayout(2, false));
156 dNameTxt
= EclipseUiUtils
.createGridLT(composite
,
157 "Distinguished name", this);
158 dNameTxt
.setEnabled(false);
160 baseDnCmb
= createGridLC(composite
, "Base DN");
161 initialiseDnCmb(baseDnCmb
);
162 baseDnCmb
.addModifyListener(this);
163 baseDnCmb
.addModifyListener(new ModifyListener() {
164 private static final long serialVersionUID
= -1435351236582736843L;
167 public void modifyText(ModifyEvent event
) {
168 String name
= usernameTxt
.getText();
169 dNameTxt
.setText(getDn(name
));
173 usernameTxt
= EclipseUiUtils
.createGridLT(composite
,
175 usernameTxt
.addModifyListener(new ModifyListener() {
176 private static final long serialVersionUID
= -1435351236582736843L;
179 public void modifyText(ModifyEvent event
) {
180 String name
= usernameTxt
.getText();
181 if (name
.trim().equals("")) {
182 dNameTxt
.setText("");
183 lastNameTxt
.setText("");
184 primaryMailTxt
.setText("");
188 dNameTxt
.setText(getDn(name
));
189 lastNameTxt
.setText(name
.toUpperCase());
190 primaryMailTxt
.setText(getMail(name
));
191 pwd1Txt
.setText("demo");
192 pwd2Txt
.setText("demo");
197 primaryMailTxt
= EclipseUiUtils
.createGridLT(composite
,
199 firstNameTxt
= EclipseUiUtils
.createGridLT(composite
,
201 lastNameTxt
= EclipseUiUtils
.createGridLT(composite
,
203 pwd1Txt
= EclipseUiUtils
.createGridLP(composite
, "Password",
205 pwd2Txt
= EclipseUiUtils
.createGridLP(composite
,
206 "Repeat password", this);
207 setControl(composite
);
209 // Initialize buttons
210 setPageComplete(false);
211 getContainer().updateButtons();
215 public void modifyText(ModifyEvent event
) {
216 String message
= checkComplete();
217 if (message
!= null) {
218 setMessage(message
, WizardPage
.ERROR
);
219 setPageComplete(false);
221 setMessage("Complete", WizardPage
.INFORMATION
);
222 setPageComplete(true);
224 getContainer().updateButtons();
227 /** @return error message or null if complete */
228 protected String
checkComplete() {
229 String name
= usernameTxt
.getText();
231 if (name
.trim().equals(""))
232 return "User name must not be empty";
233 Role role
= userAdminWrapper
.getUserAdmin()
234 .getRole(getDn(name
));
236 return "User " + name
+ " already exists";
237 if (!primaryMailTxt
.getText().matches(EMAIL_PATTERN
))
238 return "Not a valid email address";
239 if (lastNameTxt
.getText().trim().equals(""))
240 return "Specify a last name";
241 if (pwd1Txt
.getText().trim().equals(""))
242 return "Specify a password";
243 if (pwd2Txt
.getText().trim().equals(""))
244 return "Repeat the password";
245 if (!pwd2Txt
.getText().equals(pwd1Txt
.getText()))
246 return "Passwords are different";
251 public void setVisible(boolean visible
) {
252 super.setVisible(visible
);
254 if (baseDnCmb
.getSelectionIndex() == -1)
255 baseDnCmb
.setFocus();
257 usernameTxt
.setFocus();
260 public String
getUsername() {
261 return usernameTxt
.getText();
264 public char[] getPassword() {
265 return pwd1Txt
.getTextChars();
270 private String
getDn(String uid
) {
271 return "uid=" + uid
+ ",ou=users," + baseDnCmb
.getText();
274 private void initialiseDnCmb(Combo combo
) {
275 List
<String
> dns
= userAdminWrapper
.getKnownBaseDns(true);
277 throw new ArgeoException(
278 "No writable base dn found. Cannot create user");
279 combo
.setItems(dns
.toArray(new String
[0]));
284 private String
getMail(String username
) {
285 if (baseDnCmb
.getSelectionIndex() == -1)
287 String baseDn
= baseDnCmb
.getText();
289 LdapName name
= new LdapName(baseDn
);
290 List
<Rdn
> rdns
= name
.getRdns();
291 return username
+ "@" + (String
) rdns
.get(1).getValue() + '.'
292 + (String
) rdns
.get(0).getValue();
293 } catch (InvalidNameException e
) {
294 throw new ArgeoException("Unable to generate mail for "
295 + username
+ " with base dn " + baseDn
, e
);
300 private Combo
createGridLC(Composite parent
, String label
) {
301 Label lbl
= new Label(parent
, SWT
.LEAD
);
303 lbl
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false));
304 Combo combo
= new Combo(parent
, SWT
.LEAD
| SWT
.BORDER
| SWT
.READ_ONLY
);
305 combo
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false));
309 /* DEPENDENCY INJECTION */
310 public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper
) {
311 this.userAdminWrapper
= userAdminWrapper
;