]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/ldap/ArgeoLdapUserDetailsManager.java
Prepare next development cycle
[lgpl/argeo-commons.git] / security / ldap / ArgeoLdapUserDetailsManager.java
1 package org.argeo.security.ldap;
2
3 import java.security.NoSuchAlgorithmException;
4 import java.security.SecureRandom;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Random;
10 import java.util.Set;
11 import java.util.TreeSet;
12
13 import org.argeo.ArgeoException;
14 import org.argeo.security.UserAdminService;
15 import org.springframework.ldap.core.ContextSource;
16 import org.springframework.security.Authentication;
17 import org.springframework.security.GrantedAuthority;
18 import org.springframework.security.context.SecurityContextHolder;
19 import org.springframework.security.providers.encoding.PasswordEncoder;
20 import org.springframework.security.userdetails.UserDetails;
21 import org.springframework.security.userdetails.ldap.LdapUserDetailsManager;
22
23 /** Extends {@link LdapUserDetailsManager} by adding password encoding support. */
24 public class ArgeoLdapUserDetailsManager extends LdapUserDetailsManager
25 implements UserAdminService {
26 private String superUsername = "root";
27 private ArgeoUserAdminDaoLdap userAdminDao;
28 private PasswordEncoder passwordEncoder;
29 private final Random random;
30
31 public ArgeoLdapUserDetailsManager(ContextSource contextSource) {
32 super(contextSource);
33 this.random = createRandom();
34 }
35
36 private static Random createRandom() {
37 try {
38 return SecureRandom.getInstance("SHA1PRNG");
39 } catch (NoSuchAlgorithmException e) {
40 return new Random(System.currentTimeMillis());
41 }
42 }
43
44 @Override
45 public void changePassword(String oldPassword, String newPassword) {
46 Authentication authentication = SecurityContextHolder.getContext()
47 .getAuthentication();
48 if (authentication == null)
49 throw new ArgeoException(
50 "Cannot change password without authentication");
51 String username = authentication.getName();
52 UserDetails userDetails = loadUserByUsername(username);
53 String currentPassword = userDetails.getPassword();
54 if (currentPassword == null)
55 throw new ArgeoException("Cannot access current password");
56 if (!passwordEncoder
57 .isPasswordValid(currentPassword, oldPassword, null))
58 throw new ArgeoException("Old password invalid");
59 // Spring Security LDAP 2.0 is buggy when used with OpenLDAP and called
60 // with oldPassword argument
61 super.changePassword(null, encodePassword(newPassword));
62 }
63
64 public void newRole(String role) {
65 userAdminDao.createRole(role, superUsername);
66 }
67
68 public void synchronize() {
69 for (String username : userAdminDao.listUsers())
70 loadUserByUsername(username);
71 // TODO: find a way to remove from JCR
72 }
73
74 public void deleteRole(String role) {
75 userAdminDao.deleteRole(role);
76 }
77
78 public Set<String> listUsers() {
79 return userAdminDao.listUsers();
80 }
81
82 public Set<String> listUsersInRole(String role) {
83 Set<String> lst = new TreeSet<String>(
84 userAdminDao.listUsersInRole(role));
85 Iterator<String> it = lst.iterator();
86 while (it.hasNext()) {
87 if (it.next().equals(superUsername)) {
88 it.remove();
89 break;
90 }
91 }
92 return lst;
93 }
94
95 public List<String> listUserRoles(String username) {
96 UserDetails userDetails = loadUserByUsername(username);
97 List<String> roles = new ArrayList<String>();
98 for (GrantedAuthority ga : userDetails.getAuthorities()) {
99 roles.add(ga.getAuthority());
100 }
101 return Collections.unmodifiableList(roles);
102 }
103
104 public Set<String> listEditableRoles() {
105 return userAdminDao.listEditableRoles();
106 }
107
108 protected String encodePassword(String password) {
109 if (!password.startsWith("{")) {
110 byte[] salt = new byte[16];
111 random.nextBytes(salt);
112 return passwordEncoder.encodePassword(password, salt);
113 } else {
114 return password;
115 }
116 }
117
118 public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
119 this.passwordEncoder = passwordEncoder;
120 }
121
122 public void setSuperUsername(String superUsername) {
123 this.superUsername = superUsername;
124 }
125
126 public void setUserAdminDao(ArgeoUserAdminDaoLdap userAdminDao) {
127 this.userAdminDao = userAdminDao;
128 }
129
130 }