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