1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.security.impl;
18
19 import java.security.Principal;
20 import java.sql.Date;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.LinkedList;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.prefs.BackingStoreException;
29 import java.util.prefs.Preferences;
30
31 import javax.security.auth.Subject;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.jetspeed.security.AuthenticationProviderProxy;
36 import org.apache.jetspeed.security.HierarchyResolver;
37 import org.apache.jetspeed.security.SecurityException;
38 import org.apache.jetspeed.security.SecurityProvider;
39 import org.apache.jetspeed.security.User;
40 import org.apache.jetspeed.security.UserManager;
41 import org.apache.jetspeed.security.UserPrincipal;
42 import org.apache.jetspeed.security.spi.SecurityMappingHandler;
43 import org.apache.jetspeed.util.ArgUtil;
44
45 /***
46 * <p>
47 * Implementation for managing users and provides access to the {@link User}.
48 * </p>
49 *
50 * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
51 * @version $Id: UserManagerImpl.java 603894 2007-12-13 11:42:22Z woonsan $
52 */
53 public class UserManagerImpl implements UserManager
54 {
55
56 private static final Log log = LogFactory.getLog(UserManagerImpl.class);
57
58 /*** The authenticatino provider proxy. */
59 private AuthenticationProviderProxy atnProviderProxy = null;
60
61 /*** The security mapping handler. */
62 private SecurityMappingHandler securityMappingHandler = null;
63
64 private String anonymousUser = "guest";
65 private User guest = null;
66
67 /***
68 * Flag whether the principals's user group matches the user group to which the role has been mapped. (See SRV.12.4)
69 * If this flag is set to true, roles can be inherited to users via groups.
70 */
71 private boolean rolesInheritableViaGroups = true;
72
73 /***
74 * @param securityProvider
75 * The security provider.
76 */
77 public UserManagerImpl(SecurityProvider securityProvider)
78 {
79 this.atnProviderProxy = securityProvider
80 .getAuthenticationProviderProxy();
81 this.securityMappingHandler = securityProvider
82 .getSecurityMappingHandler();
83 }
84
85 /***
86 * @param securityProvider
87 * The security provider.
88 * @param anonymousUser
89 * The anonymous user name
90 */
91 public UserManagerImpl(SecurityProvider securityProvider,
92 String anonymousUser)
93 {
94 this.atnProviderProxy = securityProvider
95 .getAuthenticationProviderProxy();
96 this.securityMappingHandler = securityProvider
97 .getSecurityMappingHandler();
98 if (anonymousUser != null)
99 {
100 this.anonymousUser = anonymousUser;
101 }
102 }
103
104 /***
105 * @param securityProvider
106 * The security provider.
107 * @param roleHierarchyResolver
108 * The role hierachy resolver.
109 * @param groupHierarchyResolver
110 * The group hierarchy resolver.
111 */
112 public UserManagerImpl(SecurityProvider securityProvider,
113 HierarchyResolver roleHierarchyResolver,
114 HierarchyResolver groupHierarchyResolver)
115 {
116 securityProvider.getSecurityMappingHandler().setRoleHierarchyResolver(
117 roleHierarchyResolver);
118 securityProvider.getSecurityMappingHandler().setGroupHierarchyResolver(
119 groupHierarchyResolver);
120 this.atnProviderProxy = securityProvider
121 .getAuthenticationProviderProxy();
122 this.securityMappingHandler = securityProvider
123 .getSecurityMappingHandler();
124 }
125
126 /***
127 * @param securityProvider
128 * The security provider.
129 * @param roleHierarchyResolver
130 * The role hierachy resolver.
131 * @param groupHierarchyResolver
132 * The group hierarchy resolver.
133 * @param anonymousUser
134 * The anonymous user name
135 */
136 public UserManagerImpl(SecurityProvider securityProvider,
137 HierarchyResolver roleHierarchyResolver,
138 HierarchyResolver groupHierarchyResolver, String anonymousUser)
139 {
140 securityProvider.getSecurityMappingHandler().setRoleHierarchyResolver(
141 roleHierarchyResolver);
142 securityProvider.getSecurityMappingHandler().setGroupHierarchyResolver(
143 groupHierarchyResolver);
144 this.atnProviderProxy = securityProvider
145 .getAuthenticationProviderProxy();
146 this.securityMappingHandler = securityProvider
147 .getSecurityMappingHandler();
148 if (anonymousUser != null)
149 {
150 this.anonymousUser = anonymousUser;
151 }
152 }
153
154
155
156
157
158
159 public String getAnonymousUser()
160 {
161 return this.anonymousUser;
162 }
163
164 public void setRolesInheritableViaGroups(boolean rolesInheritableViaGroups)
165 {
166 this.rolesInheritableViaGroups = rolesInheritableViaGroups;
167 }
168
169 /***
170 * @see org.apache.jetspeed.security.UserManager#authenticate(java.lang.String,
171 * java.lang.String)
172 */
173 public boolean authenticate(String username, String password)
174 {
175 ArgUtil.notNull(new Object[]
176 { username, password}, new String[]
177 { "username", "password"},
178 "authenticate(java.lang.String, java.lang.String)");
179
180 boolean authenticated = false;
181 try
182 {
183 if (!getAnonymousUser().equals(username))
184 {
185 authenticated = atnProviderProxy.authenticate(username,
186 password);
187 if (authenticated && log.isDebugEnabled())
188 {
189 log.debug("Authenticated user: " + username);
190 }
191 }
192 } catch (SecurityException e)
193 {
194
195 }
196 return authenticated;
197 }
198
199 /***
200 * @see org.apache.jetspeed.security.UserManager#addUser(java.lang.String,
201 * java.lang.String)
202 */
203 public void addUser(String username, String password)
204 throws SecurityException
205 {
206 ArgUtil.notNull(new Object[]
207 { username}, new String[]
208 { "username"}, "addUser(java.lang.String, java.lang.String)");
209
210 createUser(username, password, atnProviderProxy
211 .getDefaultAuthenticationProvider(),false);
212 }
213
214
215
216 /***
217 * @see org.apache.jetspeed.security.UserManager#addUser(java.lang.String,
218 * java.lang.String, java.lang.String)
219 */
220 public void addUser(String username, String password, String atnProviderName)
221 throws SecurityException
222 {
223 ArgUtil.notNull(new Object[]
224 { username}, new String[]
225 { "username"}, "addUser(java.lang.String, java.lang.String)");
226
227 createUser(username, password, atnProviderName, false);
228 }
229
230 /***
231 * @see org.apache.jetspeed.security.UserManager#importUser(java.lang.String,
232 * java.lang.String, boolean)
233 */
234 public void importUser(String username, String password, boolean passThrough)
235 throws SecurityException
236 {
237 ArgUtil.notNull(new Object[]
238 { username}, new String[]
239 { "username"}, "addUser(java.lang.String, java.lang.String)");
240
241 createUser(username, password, atnProviderProxy
242 .getDefaultAuthenticationProvider(),passThrough);
243 }
244
245 /***
246 * @see org.apache.jetspeed.security.UserManager#importUser(java.lang.String,
247 * java.lang.String, java.lang.String, boolean)
248 */
249 public void importUser(String username, String password, String atnProviderName, boolean passThrough)
250 throws SecurityException
251 {
252 ArgUtil.notNull(new Object[]
253 { username}, new String[]
254 { "username"}, "addUser(java.lang.String, java.lang.String)");
255
256 createUser(username, password, atnProviderName,passThrough);
257 }
258 /***
259 * @see org.apache.jetspeed.security.UserManager#addUser(java.lang.String,
260 * java.lang.String, java.lang.String)
261 */
262 protected void createUser(String username, String password, String atnProviderName, boolean raw)
263 throws SecurityException
264 {
265 ArgUtil
266 .notNull(new Object[]
267 { username, atnProviderName}, new String[]
268 { "username", "atnProviderName"},
269 "addUser(java.lang.String, java.lang.String, java.lang.String)");
270
271
272
273
274
275 if (userExists(username)) {
276 throw new SecurityException(SecurityException.USER_ALREADY_EXISTS.create(username));
277 }
278
279 UserPrincipal userPrincipal = new UserPrincipalImpl(username);
280 String fullPath = userPrincipal.getFullPath();
281
282 Preferences preferences = Preferences.userRoot().node(fullPath);
283 if (log.isDebugEnabled())
284 {
285 log.debug("Added user preferences node: " + fullPath);
286 }
287 try
288 {
289 if ((null != preferences)
290 && preferences.absolutePath().equals(fullPath))
291 {
292
293 atnProviderProxy.addUserPrincipal(userPrincipal);
294 if (password != null)
295 {
296 try
297 {
298
299 if (raw)
300 atnProviderProxy.importPassword(username, password,atnProviderName);
301 else
302 atnProviderProxy.setPassword(username, null, password,atnProviderName);
303 }
304 catch (SecurityException se1)
305 {
306 try
307 {
308
309 atnProviderProxy.removeUserPrincipal(userPrincipal);
310 }
311 catch (SecurityException se2)
312 {
313 log.error("Failed to rollback created user after its password turned out to be invalid", se2);
314 }
315 throw se1;
316 }
317 }
318 if (log.isDebugEnabled())
319 {
320 log.debug("Added user: " + fullPath);
321 }
322 }
323 } catch (SecurityException se)
324 {
325 log.error(se.getMessage(), se);
326
327
328 try
329 {
330 preferences.removeNode();
331 } catch (BackingStoreException bse)
332 {
333 bse.printStackTrace();
334 }
335 throw se;
336 }
337 }
338
339
340
341 /***
342 * @see org.apache.jetspeed.security.UserManager#removeUser(java.lang.String)
343 *
344 * TODO Enforce that only administrators can do this.
345 */
346 public void removeUser(String username) throws SecurityException
347 {
348 ArgUtil.notNull(new Object[]
349 { username}, new String[]
350 { "username"}, "removeUser(java.lang.String)");
351
352 if (getAnonymousUser().equals(username)) { throw new SecurityException(
353 SecurityException.ANONYMOUS_USER_PROTECTED.create(username)); }
354 UserPrincipal userPrincipal = new UserPrincipalImpl(username);
355 String fullPath = userPrincipal.getFullPath();
356 atnProviderProxy.removeUserPrincipal(userPrincipal);
357
358 Preferences preferences = Preferences.userRoot().node(fullPath);
359 try
360 {
361 preferences.removeNode();
362 } catch (BackingStoreException bse)
363 {
364 bse.printStackTrace();
365 }
366 }
367
368 /***
369 * @see org.apache.jetspeed.security.UserManager#userExists(java.lang.String)
370 */
371 public boolean userExists(String username)
372 {
373 ArgUtil.notNull(new Object[]
374 { username}, new String[]
375 { "username"}, "userExists(java.lang.String)");
376
377 return atnProviderProxy.getUserPrincipal(username) != null;
378 }
379
380 /***
381 * @see org.apache.jetspeed.security.UserManager#getUser(java.lang.String)
382 */
383 public User getUser(String username) throws SecurityException
384 {
385 ArgUtil.notNull(new Object[]
386 { username}, new String[]
387 { "username"}, "getUser(java.lang.String)");
388
389
390 if (guest != null && getAnonymousUser().equals(username))
391 {
392
393 return guest;
394 }
395
396 Set principals = new PrincipalsSet();
397 String fullPath = (new UserPrincipalImpl(username)).getFullPath();
398
399 Principal userPrincipal = atnProviderProxy.getUserPrincipal(username);
400 if (null == userPrincipal) {
401 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(username));
402 }
403
404 principals.add(userPrincipal);
405 principals.addAll(securityMappingHandler.getRolePrincipals(username));
406 Set groupPrincipals = securityMappingHandler.getGroupPrincipals(username);
407 principals.addAll(groupPrincipals);
408
409 if (this.rolesInheritableViaGroups)
410 {
411 for (Iterator it = groupPrincipals.iterator(); it.hasNext(); )
412 {
413 Principal groupPrincipal = (Principal) it.next();
414 Set rolePrincipalsInGroup = securityMappingHandler.getRolePrincipalsInGroup(groupPrincipal.getName());
415 principals.addAll(rolePrincipalsInGroup);
416 }
417 }
418
419 Subject subject = null;
420 if (getAnonymousUser().equals(username))
421 {
422 subject = new Subject(true, principals, new HashSet(),
423 new HashSet());
424 } else
425 {
426 subject = new Subject(true, principals, atnProviderProxy
427 .getPublicCredentials(username), atnProviderProxy
428 .getPrivateCredentials(username));
429 }
430 Preferences preferences = Preferences.userRoot().node(fullPath);
431 User user = new UserImpl(subject, preferences);
432 if (getAnonymousUser().equals(username))
433 {
434 guest = user;
435 }
436 return user;
437 }
438
439 /***
440 * @see org.apache.jetspeed.security.UserManager#getUsers(java.lang.String)
441 */
442 public Iterator getUsers(String filter) throws SecurityException
443 {
444 List users = new LinkedList();
445 Iterator userPrincipals = atnProviderProxy.getUserPrincipals(filter)
446 .iterator();
447 while (userPrincipals.hasNext())
448 {
449 String username = ((Principal) userPrincipals.next()).getName();
450 User user = getUser(username);
451 users.add(user);
452 }
453 return users.iterator();
454 }
455
456 /***
457 * @see org.apache.jetspeed.security.UserManager#getUserNames(java.lang.String)
458 */
459 public Iterator getUserNames(String filter) throws SecurityException
460 {
461 List usernames = new LinkedList();
462 Iterator userPrincipals = atnProviderProxy.getUserPrincipals(filter).iterator();
463 while (userPrincipals.hasNext())
464 {
465 usernames.add(((Principal) userPrincipals.next()).getName());
466 }
467 return usernames.iterator();
468 }
469
470 /***
471 * @see org.apache.jetspeed.security.UserManager#getUsersInRole(java.lang.String)
472 */
473 public Collection getUsersInRole(String roleFullPathName)
474 throws SecurityException
475 {
476 ArgUtil.notNull(new Object[]
477 { roleFullPathName}, new String[]
478 { "roleFullPathName"}, "getUsersInRole(java.lang.String)");
479
480 Collection users = new ArrayList();
481
482 Set userPrincipals = securityMappingHandler
483 .getUserPrincipalsInRole(roleFullPathName);
484 Iterator userPrincipalsIter = userPrincipals.iterator();
485 while (userPrincipalsIter.hasNext())
486 {
487 Principal userPrincipal = (Principal) userPrincipalsIter.next();
488 users.add(getUser(userPrincipal.getName()));
489 }
490 return users;
491 }
492
493 /***
494 * @see org.apache.jetspeed.security.UserManager#getUsersInGroup(java.lang.String)
495 */
496 public Collection getUsersInGroup(String groupFullPathName)
497 throws SecurityException
498 {
499 ArgUtil.notNull(new Object[]
500 { groupFullPathName}, new String[]
501 { "groupFullPathName"}, "getUsersInGroup(java.lang.String)");
502
503 Collection users = new ArrayList();
504
505 Set userPrincipals = securityMappingHandler
506 .getUserPrincipalsInGroup(groupFullPathName);
507 Iterator userPrincipalsIter = userPrincipals.iterator();
508 while (userPrincipalsIter.hasNext())
509 {
510 Principal userPrincipal = (Principal) userPrincipalsIter.next();
511 users.add(getUser(userPrincipal.getName()));
512 }
513 return users;
514 }
515
516 /***
517 * @see org.apache.jetspeed.security.UserManager#setPassword(java.lang.String,
518 * java.lang.String, java.lang.String)
519 *
520 * TODO Enforce that only administrators can do this.
521 */
522 public void setPassword(String username, String oldPassword,
523 String newPassword) throws SecurityException
524 {
525 ArgUtil
526 .notNull(new Object[]
527 { username, newPassword}, new String[]
528 { "username", "newPassword"},
529 "setPassword(java.lang.String, java.lang.String, java.lang.String)");
530
531 if (getAnonymousUser().equals(username)) { throw new SecurityException(
532 SecurityException.ANONYMOUS_USER_PROTECTED.create(username)); }
533 atnProviderProxy.setPassword(username, oldPassword, newPassword);
534 }
535
536 /***
537 * @see org.apache.jetspeed.security.UserManager#setPasswordEnabled(java.lang.String,
538 * boolean)
539 */
540 public void setPasswordEnabled(String userName, boolean enabled)
541 throws SecurityException
542 {
543 ArgUtil.notNull(new Object[]
544 { userName,}, new String[]
545 { "userName"}, "setPasswordEnabled(java.lang.String, boolean)");
546
547 if (getAnonymousUser().equals(userName)) { throw new SecurityException(
548 SecurityException.ANONYMOUS_USER_PROTECTED.create(userName)); }
549 atnProviderProxy.setPasswordEnabled(userName, enabled);
550 }
551
552 /***
553 * @see org.apache.jetspeed.security.UserManager#setPasswordUpdateRequired(java.lang.String,
554 * boolean)
555 */
556 public void setPasswordUpdateRequired(String userName,
557 boolean updateRequired) throws SecurityException
558 {
559 ArgUtil.notNull(new Object[]
560 { userName,}, new String[]
561 { "userName"}, "setPasswordUpdateRequired(java.lang.String, boolean)");
562
563 if (getAnonymousUser().equals(userName)) { throw new SecurityException(
564 SecurityException.ANONYMOUS_USER_PROTECTED.create(userName)); }
565 atnProviderProxy.setPasswordUpdateRequired(userName, updateRequired);
566 }
567
568
569 /***
570 * @see org.apache.jetspeed.security.UserManager#setUserEnabled(java.lang.String, boolean)
571 */
572 public void setUserEnabled(String userName, boolean enabled) throws SecurityException
573 {
574 ArgUtil.notNull(new Object[] { userName, }, new String[] { "userName" },
575 "setUserEnabled(java.lang.String, boolean)");
576
577 if (getAnonymousUser().equals(userName))
578 {
579 throw new SecurityException(SecurityException.ANONYMOUS_USER_PROTECTED.create(userName));
580 }
581
582 UserPrincipalImpl userPrincipal = (UserPrincipalImpl)atnProviderProxy.getUserPrincipal(userName);
583 if (null == userPrincipal)
584 {
585 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(userName));
586 }
587 if ( enabled != userPrincipal.isEnabled() )
588 {
589 userPrincipal.setEnabled(enabled);
590 atnProviderProxy.updateUserPrincipal(userPrincipal);
591 }
592 }
593
594 /***
595 * @see org.apache.jetspeed.security.UserManager#setPasswordExpiration(java.lang.String, java.sql.Date)
596 */
597 public void setPasswordExpiration(String userName, Date expirationDate) throws SecurityException
598 {
599 ArgUtil.notNull(new Object[]
600 { userName,}, new String[]
601 { "userName"}, "setPasswordExpiration(java.lang.String, java.sql.Date)");
602
603 if (getAnonymousUser().equals(userName))
604 {
605 throw new SecurityException(SecurityException.ANONYMOUS_USER_PROTECTED.create(userName));
606 }
607 atnProviderProxy.setPasswordExpiration(userName, expirationDate);
608 }
609 }