001: package ru.emdev.EmForge.security.ldap;
002:
003: import java.text.DateFormat;
004: import java.text.ParseException;
005: import java.util.ArrayList;
006: import java.util.Arrays;
007: import java.util.Date;
008: import java.util.List;
009:
010: import javax.naming.NamingException;
011: import javax.naming.directory.Attributes;
012: import javax.naming.directory.BasicAttributes;
013: import javax.naming.ldap.Control;
014:
015: import org.acegisecurity.GrantedAuthority;
016: import org.acegisecurity.userdetails.UserDetails;
017: import org.acegisecurity.userdetails.UserDetailsService;
018: import org.acegisecurity.userdetails.ldap.LdapUserDetails;
019: import org.apache.commons.lang.StringUtils;
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022: import org.springframework.util.Assert;
023:
024: import ru.emdev.EmForge.security.EmForgeUserDetails;
025:
026: /** Ldap Based User-Details Implementation */
027: public class EmForgeUserLdap implements LdapUserDetails,
028: EmForgeUserDetails {
029:
030: protected final Log logger = LogFactory.getLog(getClass());
031:
032: // ~ Static fields/initializers ===========================================
033:
034: private static final long serialVersionUID = 1L;
035: private static final GrantedAuthority[] NO_AUTHORITIES = new GrantedAuthority[0];
036: private static final Control[] NO_CONTROLS = new Control[0];
037:
038: // ~ Instance fields ======================================================
039:
040: private Attributes attributes = new BasicAttributes();
041: private String dn;
042: private String password;
043: private String username;
044: private GrantedAuthority[] authorities = NO_AUTHORITIES;
045: private Control[] controls = NO_CONTROLS;
046: private boolean accountNonExpired = true;
047: private boolean accountNonLocked = true;
048: private boolean credentialsNonExpired = true;
049: private boolean enabled = true;
050:
051: /** UserDetailsService is used for getting manager information */
052: private UserDetailsService m_userDetailsService = null;
053:
054: // ~ Constructors =========================================================
055:
056: /**
057: *
058: */
059: protected EmForgeUserLdap() {
060:
061: }
062:
063: // ~ Methods ==============================================================
064:
065: /**
066: * @see org.acegisecurity.userdetails.ldap.LdapUserDetails#getAttributes()
067: */
068: public Attributes getAttributes() {
069:
070: return attributes;
071: }
072:
073: /**
074: * @see org.acegisecurity.userdetails.UserDetails#getAuthorities()
075: */
076: public GrantedAuthority[] getAuthorities() {
077:
078: return authorities;
079: }
080:
081: /**
082: * @see org.acegisecurity.userdetails.ldap.LdapUserDetails#getControls()
083: */
084: public Control[] getControls() {
085:
086: return controls;
087: }
088:
089: /**
090: * @see org.acegisecurity.userdetails.ldap.LdapUserDetails#getDn()
091: */
092: public String getDn() {
093:
094: return dn;
095: }
096:
097: /**
098: * @see org.acegisecurity.userdetails.UserDetails#getPassword()
099: */
100: public String getPassword() {
101:
102: return password;
103: }
104:
105: /**
106: * @see org.acegisecurity.userdetails.UserDetails#getUsername()
107: */
108: public String getUsername() {
109:
110: return username;
111: }
112:
113: /**
114: * @see org.acegisecurity.userdetails.UserDetails#isAccountNonExpired()
115: */
116: public boolean isAccountNonExpired() {
117:
118: return accountNonExpired;
119: }
120:
121: /**
122: * @see org.acegisecurity.userdetails.UserDetails#isAccountNonLocked()
123: */
124: public boolean isAccountNonLocked() {
125:
126: return accountNonLocked;
127: }
128:
129: /**
130: * @see org.acegisecurity.userdetails.UserDetails#isCredentialsNonExpired()
131: */
132: public boolean isCredentialsNonExpired() {
133:
134: return credentialsNonExpired;
135: }
136:
137: /**
138: * @see org.acegisecurity.userdetails.UserDetails#isEnabled()
139: */
140: public boolean isEnabled() {
141:
142: return enabled;
143: }
144:
145: // ~ Inner Classes ========================================================
146:
147: /**
148: * Variation of essence pattern. Used to create mutable intermediate object
149: */
150: public static class Essence {
151:
152: EmForgeUserLdap instance = createTarget();
153: List<GrantedAuthority> mutableAuthorities = new ArrayList<GrantedAuthority>();
154:
155: /**
156: *
157: */
158: public Essence() {
159:
160: }
161:
162: /**
163: * @param copyMe
164: */
165: public Essence(LdapUserDetails copyMe) {
166:
167: setDn(copyMe.getDn());
168: setAttributes(copyMe.getAttributes());
169: setUsername(copyMe.getUsername());
170: setPassword(copyMe.getPassword());
171: setEnabled(copyMe.isEnabled());
172: setAccountNonExpired(copyMe.isAccountNonExpired());
173: setCredentialsNonExpired(copyMe.isCredentialsNonExpired());
174: setAccountNonLocked(copyMe.isAccountNonLocked());
175: setControls(copyMe.getControls());
176: setAuthorities(copyMe.getAuthorities());
177: }
178:
179: /**
180: * @return
181: */
182: EmForgeUserLdap createTarget() {
183:
184: return new EmForgeUserLdap();
185: }
186:
187: /**
188: * @param a
189: * @return
190: */
191: public Essence addAuthority(GrantedAuthority a) {
192:
193: mutableAuthorities.add(a);
194:
195: return this ;
196: }
197:
198: /**
199: * @return
200: */
201: public LdapUserDetails createUserDetails() {
202:
203: // TODO: Validation of properties
204: Assert
205: .notNull(instance,
206: "Essence can only be used to create a single instance");
207:
208: instance.authorities = getGrantedAuthorities();
209:
210: LdapUserDetails newInstance = instance;
211:
212: instance = null;
213:
214: return newInstance;
215: }
216:
217: /**
218: * @return
219: */
220: public GrantedAuthority[] getGrantedAuthorities() {
221:
222: return (GrantedAuthority[]) mutableAuthorities
223: .toArray(new GrantedAuthority[0]);
224: }
225:
226: /**
227: * @param accountNonExpired
228: * @return
229: */
230: public Essence setAccountNonExpired(boolean accountNonExpired) {
231:
232: instance.accountNonExpired = accountNonExpired;
233:
234: return this ;
235: }
236:
237: /**
238: * @param accountNonLocked
239: * @return
240: */
241: public Essence setAccountNonLocked(boolean accountNonLocked) {
242:
243: instance.accountNonLocked = accountNonLocked;
244:
245: return this ;
246: }
247:
248: /**
249: * @param attributes
250: * @return
251: */
252: public Essence setAttributes(Attributes attributes) {
253:
254: instance.attributes = attributes;
255:
256: return this ;
257: }
258:
259: /**
260: * @param authorities
261: * @return
262: */
263: public Essence setAuthorities(GrantedAuthority[] authorities) {
264:
265: mutableAuthorities = new ArrayList<GrantedAuthority>(Arrays
266: .asList(authorities));
267:
268: return this ;
269: }
270:
271: /**
272: * @param controls
273: */
274: public void setControls(Control[] controls) {
275:
276: instance.controls = controls;
277: }
278:
279: /**
280: * @param credentialsNonExpired
281: * @return
282: */
283: public Essence setCredentialsNonExpired(
284: boolean credentialsNonExpired) {
285:
286: instance.credentialsNonExpired = credentialsNonExpired;
287:
288: return this ;
289: }
290:
291: /**
292: * @param dn
293: * @return
294: */
295: public Essence setDn(String dn) {
296:
297: instance.dn = dn;
298:
299: return this ;
300: }
301:
302: /**
303: * @param enabled
304: * @return
305: */
306: public Essence setEnabled(boolean enabled) {
307:
308: instance.enabled = enabled;
309:
310: return this ;
311: }
312:
313: /**
314: * @param password
315: * @return
316: */
317: public Essence setPassword(String password) {
318:
319: instance.password = password;
320:
321: return this ;
322: }
323:
324: /**
325: * @param username
326: * @return
327: */
328: public Essence setUsername(String username) {
329:
330: instance.username = username;
331:
332: return this ;
333: }
334:
335: /**
336: * @param i_userDetailsService
337: * @return
338: */
339: public Essence setUserDetailsService(
340: UserDetailsService i_userDetailsService) {
341:
342: instance.m_userDetailsService = i_userDetailsService;
343:
344: return this ;
345: }
346: }
347:
348: // EmForge Specific Implementation
349: // ===============================
350:
351: /**
352: * @see ru.emdev.EmForge.security.EmForgeUserDetails#getDisplayName()
353: */
354: public String getDisplayName() {
355:
356: String displayName = getAttr("displayName");
357: // if display name is not available
358: if (displayName != null) {
359: return displayName;
360: } else {
361: // return just user name
362: return getUsername();
363: }
364: }
365:
366: /**
367: * @see ru.emdev.EmForge.security.EmForgeUserDetails#getEmail()
368: */
369: public String getEmail() {
370:
371: return getAttr("mail");
372: }
373:
374: /**
375: * @see ru.emdev.EmForge.security.EmForgeUserDetails#getManager()
376: */
377: public EmForgeUserDetails getManager() {
378:
379: assert m_userDetailsService != null;
380:
381: UserDetails user = null;
382: String userName = getAttr("manager");
383: if (userName != null) {
384: user = m_userDetailsService.loadUserByUsername(userName);
385: }
386:
387: return (EmForgeUserDetails) user;
388: }
389:
390: /**
391: * @return <code>True</code> if the user is an anonymous, otherwise <code>False</code>
392: */
393: public boolean isAnonymous() {
394:
395: return hasRole("ROLE_ANONYMOUS");
396: }
397:
398: /**
399: * @see ru.emdev.EmForge.security.EmForgeUserDetails#hasRole(java.lang.String)
400: */
401: public boolean hasRole(String i_role) {
402:
403: for (GrantedAuthority authority : authorities) {
404: if (authority.getAuthority().equals(i_role)) {
405: return true;
406: }
407: }
408:
409: return false;
410: }
411:
412: /**
413: * @return User registration date
414: */
415: public Date getRegisteredAt() {
416:
417: Date resistered = null;
418: DateFormat df = DateFormat.getDateInstance();
419: try {
420: resistered = df.parse(getAttr("whenCreated"));
421: } catch (ParseException ex) {
422: logger.error(ex);
423: }
424: return resistered;
425: }
426:
427: /**
428: * gets the attribute by name
429: *
430: * @todo change to naming binding
431: */
432: protected String getAttr(String i_name) {
433:
434: assert attributes != null;
435:
436: String result = null;
437: try {
438: // get name from attributes
439: if (attributes.get(i_name) != null
440: && attributes.get(i_name).get() != null) {
441: result = attributes.get(i_name).get().toString();
442: }
443: } catch (NamingException ex) {
444: logger.error(ex);
445: }
446:
447: return result;
448: }
449:
450: /**
451: * @see ru.emdev.EmForge.security.EmForgeUserDetails#getVcPassword()
452: */
453: public String getVcPassword() {
454:
455: return password;
456: }
457:
458: /**
459: * @see ru.emdev.EmForge.security.EmForgeUserDetails#getVcUserName()
460: */
461: public String getVcUserName() {
462:
463: return username;
464: }
465:
466: /**
467: * @see java.lang.Object#hashCode()
468: */
469: @Override
470: public int hashCode() {
471:
472: final int prime = 31;
473: int result = 1;
474: result = prime * result
475: + ((username == null) ? 0 : username.hashCode());
476: return result;
477: }
478:
479: /**
480: * @see java.lang.Object#equals(java.lang.Object)
481: */
482: @Override
483: public boolean equals(Object i_obj) {
484:
485: boolean result = false;
486:
487: if (i_obj != null) {
488: if (i_obj == this ) {
489: result = true;
490:
491: } else if (i_obj instanceof EmForgeUserDetails) {
492: result = StringUtils.equals(
493: ((EmForgeUserDetails) i_obj).getUsername(),
494: getUsername());
495: }
496: }
497:
498: return result;
499: }
500: }
|