From 891dc0919c8fdcb6777ba02523432c1e2adc9e58 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 17 Mar 2011 14:23:25 +0000 Subject: [PATCH] Move security admin services git-svn-id: https://svn.argeo.org/commons/trunk@4314 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- demo/argeo-node-web.properties | 1 + .../META-INF/spring/ldap-osgi.xml | 6 +- .../META-INF/spring/ldap.xml | 4 +- .../META-INF/spring/osgi.xml | 18 +- .../META-INF/spring/services.xml | 42 +---- .../META-INF/spring/osgi.xml | 7 +- .../META-INF/spring/services.xml | 17 +- .../org/argeo/security/ArgeoSecurity.java | 28 --- .../org/argeo/security/CurrentUserDao.java | 2 +- .../java/org/argeo/security/UserAdminDao.java | 4 + .../org/argeo/security/UserAdminService.java | 7 - .../security/core/DefaultArgeoSecurity.java | 52 ----- .../core/DefaultCurrentUserService.java | 31 +-- .../security/core/DefaultSecurityService.java | 177 ------------------ .../core/DefaultUserAdminService.java | 111 +++++++++++ .../core/SystemAuthenticatedTaskExecutor.java | 37 ---- .../security/ldap/ArgeoSecurityDaoLdap.java | 63 ++++++- 17 files changed, 190 insertions(+), 417 deletions(-) delete mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoSecurity.java delete mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultArgeoSecurity.java delete mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultSecurityService.java create mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java delete mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemAuthenticatedTaskExecutor.java diff --git a/demo/argeo-node-web.properties b/demo/argeo-node-web.properties index 50e012054..477bafdf7 100644 --- a/demo/argeo-node-web.properties +++ b/demo/argeo-node-web.properties @@ -4,6 +4,7 @@ org.argeo.server.ads.server,\ org.argeo.node.repo.jackrabbit,\ org.argeo.security.manager.ldap,\ org.argeo.security.services,\ +org.argeo.security.services.admin,\ com.springsource.javax.servlet,\ org.argeo.security.equinox,\ org.eclipse.core.runtime,\ diff --git a/security/modules/org.argeo.security.manager.ldap/META-INF/spring/ldap-osgi.xml b/security/modules/org.argeo.security.manager.ldap/META-INF/spring/ldap-osgi.xml index b3a95cefc..7a0fa89fa 100644 --- a/security/modules/org.argeo.security.manager.ldap/META-INF/spring/ldap-osgi.xml +++ b/security/modules/org.argeo.security.manager.ldap/META-INF/spring/ldap-osgi.xml @@ -11,12 +11,12 @@ cardinality="0..N" /> - - + - osgibundle:ldap.properties - + osgibundle:ldap.properties @@ -39,6 +38,7 @@ + - - - - - - - + - - - - - \ No newline at end of file diff --git a/security/modules/org.argeo.security.services.admin/META-INF/spring/services.xml b/security/modules/org.argeo.security.services.admin/META-INF/spring/services.xml index c602a6bc5..e7b9a4b28 100644 --- a/security/modules/org.argeo.security.services.admin/META-INF/spring/services.xml +++ b/security/modules/org.argeo.security.services.admin/META-INF/spring/services.xml @@ -4,45 +4,7 @@ xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - - - - osgibundle:security.properties - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/security/modules/org.argeo.security.services/META-INF/spring/osgi.xml b/security/modules/org.argeo.security.services/META-INF/spring/osgi.xml index 6822ed70a..2ee9bf3f5 100644 --- a/security/modules/org.argeo.security.services/META-INF/spring/osgi.xml +++ b/security/modules/org.argeo.security.services/META-INF/spring/osgi.xml @@ -7,10 +7,7 @@ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - - - + - - - osgibundle:security.properties - + osgibundle:security.properties - - - - - + + @@ -38,11 +34,4 @@ - - - - - - - \ No newline at end of file diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoSecurity.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoSecurity.java deleted file mode 100644 index 388ea3b7d..000000000 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoSecurity.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2010 Mathieu Baudier - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.argeo.security; - -/** Callback related to the lifecycle of a user. */ -public interface ArgeoSecurity { - /** - * Called before a user is actually created. Default user natures and roles - * should be added there. - */ - public void beforeCreate(ArgeoUser user); - - public String getSuperUsername(); -} diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java index b9fee6f3a..6e5b4ec3c 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserDao.java @@ -20,7 +20,7 @@ package org.argeo.security; * Access to user backend for the currently logged in user */ public interface CurrentUserDao { - public void updateUser(ArgeoUser user); + public void updateCurrentUserPassword(String oldPassword, String newPassword); public String getDefaultRole(); diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java index 0d07daec3..1ca452a74 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminDao.java @@ -29,6 +29,10 @@ public interface UserAdminDao{ /** List roles that can be modified */ public Set listEditableRoles(); + public void updateUser(ArgeoUser user); + + public void updateUserPassword(String username, String password); + /** * Creates a new user in the underlying storage. DO NOT CALL DIRECTLY * use {@link ArgeoSecurityService#newUser(ArgeoUser)} instead. diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java index 4bd887ec7..cd49d6566 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserAdminService.java @@ -31,11 +31,4 @@ public interface UserAdminService { public Set listEditableRoles(); public void deleteRole(String role); - - /* - * SYSTEM - */ - @Deprecated - /** @deprecated Use ${link SystemExecutionService} instead.*/ - public Runnable wrapWithSystemAuthentication(final Runnable runnable); } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultArgeoSecurity.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultArgeoSecurity.java deleted file mode 100644 index 47497d182..000000000 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultArgeoSecurity.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2010 Mathieu Baudier - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.argeo.security.core; - -import org.argeo.security.ArgeoUser; -import org.argeo.security.ArgeoSecurity; -import org.argeo.security.nature.SimpleUserNature; - -/** Holds deployment specific security information. */ -public class DefaultArgeoSecurity implements ArgeoSecurity { - private String superUsername = "root"; - - public void beforeCreate(ArgeoUser user) { - SimpleUserNature simpleUserNature; - try { - simpleUserNature = SimpleUserNature - .findSimpleUserNature(user, null); - } catch (Exception e) { - simpleUserNature = new SimpleUserNature(); - user.getUserNatures().put("simpleUserNature", simpleUserNature); - } - - if (simpleUserNature.getLastName() == null - || simpleUserNature.getLastName().equals("")) - simpleUserNature.setLastName("empty");// to prevent issue with sn in - // LDAP - - } - - public String getSuperUsername() { - return superUsername; - } - - public void setSuperUsername(String superUsername) { - this.superUsername = superUsername; - } - -} diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java index 49e9efe5d..34e4375d8 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultCurrentUserService.java @@ -16,30 +16,17 @@ package org.argeo.security.core; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; import java.util.Map; -import java.util.Random; -import org.argeo.ArgeoException; import org.argeo.security.ArgeoUser; import org.argeo.security.CurrentUserDao; import org.argeo.security.CurrentUserService; -import org.argeo.security.SimpleArgeoUser; import org.argeo.security.UserNature; -import org.springframework.security.providers.encoding.PasswordEncoder; public class DefaultCurrentUserService implements CurrentUserService { private CurrentUserDao currentUserDao; - private PasswordEncoder passwordEncoder; - private Random random; public DefaultCurrentUserService() { - try { - random = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - random = new Random(System.currentTimeMillis()); - } } public ArgeoUser getCurrentUser() { @@ -52,18 +39,7 @@ public class DefaultCurrentUserService implements CurrentUserService { } public void updateCurrentUserPassword(String oldPassword, String newPassword) { - SimpleArgeoUser user = new SimpleArgeoUser(getCurrentUser()); - if (!passwordEncoder.isPasswordValid(user.getPassword(), oldPassword, - null)) - throw new ArgeoException("Old password is not correct."); - user.setPassword(encodePassword(newPassword)); - currentUserDao.updateUser(user); - } - - protected String encodePassword(String password) { - byte[] salt = new byte[16]; - random.nextBytes(salt); - return passwordEncoder.encodePassword(password, salt); + currentUserDao.updateCurrentUserPassword(oldPassword, newPassword); } public void updateCurrentUserNatures(Map userNatures) { @@ -74,9 +50,4 @@ public class DefaultCurrentUserService implements CurrentUserService { public void setCurrentUserDao(CurrentUserDao dao) { this.currentUserDao = dao; } - - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultSecurityService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultSecurityService.java deleted file mode 100644 index 62ce6c759..000000000 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultSecurityService.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2010 Mathieu Baudier - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.argeo.security.core; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.argeo.security.ArgeoSecurity; -import org.argeo.security.ArgeoSecurityDao; -import org.argeo.security.ArgeoSecurityService; -import org.argeo.security.ArgeoUser; -import org.argeo.security.SimpleArgeoUser; -import org.argeo.security.UserAdminService; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.TaskExecutor; -import org.springframework.security.Authentication; -import org.springframework.security.AuthenticationManager; -import org.springframework.security.context.SecurityContext; -import org.springframework.security.context.SecurityContextHolder; - -public class DefaultSecurityService extends DefaultCurrentUserService implements - UserAdminService, ArgeoSecurityService { - private ArgeoSecurity argeoSecurity = new DefaultArgeoSecurity(); - private ArgeoSecurityDao securityDao; - private AuthenticationManager authenticationManager; - - private String systemAuthenticationKey; - - public ArgeoSecurityDao getSecurityDao() { - return securityDao; - } - - public void newRole(String role) { - securityDao.createRole(role, argeoSecurity.getSuperUsername()); - } - - public void updateUserPassword(String username, String password) { - SimpleArgeoUser user = new SimpleArgeoUser( - securityDao.getUser(username)); - user.setPassword(encodePassword(password)); - securityDao.updateUser(user); - } - - public void newUser(ArgeoUser user) { - argeoSecurity.beforeCreate(user); - // normalize password - if (user instanceof SimpleArgeoUser) { - if (user.getPassword() == null || user.getPassword().equals("")) - ((SimpleArgeoUser) user).setPassword(encodePassword(user - .getUsername())); - else if (!user.getPassword().startsWith("{")) - ((SimpleArgeoUser) user).setPassword(encodePassword(user - .getPassword())); - } - securityDao.createUser(user); - } - - public ArgeoUser getUser(String username) { - return securityDao.getUser(username); - } - - public Boolean userExists(String username) { - return securityDao.userExists(username); - } - - public void updateUser(ArgeoUser user) { - String password = user.getPassword(); - if (password == null) - password = securityDao.getUserWithPassword(user.getUsername()) - .getPassword(); - if (!password.startsWith("{")) - password = encodePassword(user.getPassword()); - SimpleArgeoUser simpleArgeoUser = new SimpleArgeoUser(user); - simpleArgeoUser.setPassword(password); - securityDao.updateUser(simpleArgeoUser); - } - - public void deleteUser(String username) { - securityDao.deleteUser(username); - - } - - public void deleteRole(String role) { - securityDao.deleteRole(role); - } - - @Deprecated - public TaskExecutor createSystemAuthenticatedTaskExecutor() { - return new SimpleAsyncTaskExecutor() { - private static final long serialVersionUID = -8126773862193265020L; - - @Override - public Thread createThread(Runnable runnable) { - return super - .createThread(wrapWithSystemAuthentication(runnable)); - } - - }; - } - - /** - * Wraps another runnable, adding security context
- * TODO: secure the call to this method with Java Security - */ - @Deprecated - public Runnable wrapWithSystemAuthentication(final Runnable runnable) { - return new Runnable() { - - public void run() { - SecurityContext securityContext = SecurityContextHolder - .getContext(); - Authentication auth = authenticationManager - .authenticate(new InternalAuthentication( - systemAuthenticationKey)); - securityContext.setAuthentication(auth); - - runnable.run(); - } - }; - } - - public Set listUsersInRole(String role) { - Set lst = new HashSet( - securityDao.listUsersInRole(role)); - Iterator it = lst.iterator(); - while (it.hasNext()) { - if (it.next().getUsername() - .equals(argeoSecurity.getSuperUsername())) { - it.remove(); - break; - } - } - return lst; - } - - public Set listUsers() { - return securityDao.listUsers(); - } - - public Set listEditableRoles() { - // TODO Auto-generated method stub - return securityDao.listEditableRoles(); - } - - public void setArgeoSecurity(ArgeoSecurity argeoSecurity) { - this.argeoSecurity = argeoSecurity; - } - - public void setSecurityDao(ArgeoSecurityDao dao) { - this.securityDao = dao; - setCurrentUserDao(dao); - } - - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - - public void setSystemAuthenticationKey(String systemAuthenticationKey) { - this.systemAuthenticationKey = systemAuthenticationKey; - } -} diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java new file mode 100644 index 000000000..94cdfa94f --- /dev/null +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/DefaultUserAdminService.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2010 Mathieu Baudier + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.argeo.security.core; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.argeo.security.ArgeoUser; +import org.argeo.security.UserAdminDao; +import org.argeo.security.UserAdminService; +import org.argeo.security.nature.SimpleUserNature; + +public class DefaultUserAdminService implements UserAdminService { + private String superUsername = "root"; + private UserAdminDao userAdminDao; + + public void newRole(String role) { + userAdminDao.createRole(role, getSuperUsername()); + } + + public void updateUserPassword(String username, String password) { + userAdminDao.updateUserPassword(username, password); + } + + public void newUser(ArgeoUser user) { + // pre-process + SimpleUserNature simpleUserNature; + try { + simpleUserNature = SimpleUserNature + .findSimpleUserNature(user, null); + } catch (Exception e) { + simpleUserNature = new SimpleUserNature(); + user.getUserNatures().put("simpleUserNature", simpleUserNature); + } + + if (simpleUserNature.getLastName() == null + || simpleUserNature.getLastName().equals("")) { + // to prevent issue with sn in LDAP + simpleUserNature.setLastName("empty"); + } + + userAdminDao.createUser(user); + } + + public ArgeoUser getUser(String username) { + return userAdminDao.getUser(username); + } + + public Boolean userExists(String username) { + return userAdminDao.userExists(username); + } + + public void updateUser(ArgeoUser user) { + userAdminDao.updateUser(user); + } + + public void deleteUser(String username) { + userAdminDao.deleteUser(username); + + } + + public void deleteRole(String role) { + userAdminDao.deleteRole(role); + } + + public Set listUsersInRole(String role) { + Set lst = new HashSet( + userAdminDao.listUsersInRole(role)); + Iterator it = lst.iterator(); + while (it.hasNext()) { + if (it.next().getUsername().equals(getSuperUsername())) { + it.remove(); + break; + } + } + return lst; + } + + public Set listUsers() { + return userAdminDao.listUsers(); + } + + public Set listEditableRoles() { + return userAdminDao.listEditableRoles(); + } + + // TODO: expose it via the interface as well? + public String getSuperUsername() { + return superUsername; + } + + public void setUserAdminDao(UserAdminDao userAdminDao) { + this.userAdminDao = userAdminDao; + } + +} diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemAuthenticatedTaskExecutor.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemAuthenticatedTaskExecutor.java deleted file mode 100644 index dd5dc2b26..000000000 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemAuthenticatedTaskExecutor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010 Mathieu Baudier - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.argeo.security.core; - -import org.argeo.security.ArgeoSecurityService; -import org.springframework.core.task.SimpleAsyncTaskExecutor; - -public class SystemAuthenticatedTaskExecutor extends SimpleAsyncTaskExecutor { - private static final long serialVersionUID = 453384889461147359L; - - private ArgeoSecurityService securityService; - - @Override - public Thread createThread(Runnable runnable) { - return super.createThread(securityService - .wrapWithSystemAuthentication(runnable)); - } - - public void setSecurityService(ArgeoSecurityService securityService) { - this.securityService = securityService; - } - -} diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java index f5e41232e..0a10cce3f 100644 --- a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java +++ b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java @@ -18,8 +18,11 @@ package org.argeo.security.ldap; import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.util.Collections; import java.util.List; +import java.util.Random; import java.util.Set; import java.util.TreeSet; @@ -27,7 +30,7 @@ import javax.naming.Name; import javax.naming.NamingException; import javax.naming.directory.DirContext; -import org.argeo.security.ArgeoSecurityDao; +import org.argeo.ArgeoException; import org.argeo.security.ArgeoUser; import org.argeo.security.CurrentUserDao; import org.argeo.security.SimpleArgeoUser; @@ -48,6 +51,7 @@ import org.springframework.security.ldap.LdapUtils; import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator; import org.springframework.security.ldap.search.FilterBasedLdapUserSearch; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; +import org.springframework.security.providers.encoding.PasswordEncoder; import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetailsManager; import org.springframework.security.userdetails.UserDetailsService; @@ -55,8 +59,8 @@ import org.springframework.security.userdetails.ldap.LdapUserDetailsManager; import org.springframework.security.userdetails.ldap.LdapUserDetailsService; import org.springframework.security.userdetails.ldap.UserDetailsContextMapper; -public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao, - UserAdminDao, InitializingBean { +public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, + InitializingBean { // private final static Log log = LogFactory.getLog(UserDaoLdap.class); private UserDetailsManager userDetailsManager; @@ -79,9 +83,18 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao, private LdapUserDetailsService ldapUserDetailsService; private List userNatureMappers; + private PasswordEncoder passwordEncoder; + private Random random; + public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) { this.contextSource = contextSource; ldapTemplate = new LdapTemplate(this.contextSource); + + try { + random = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + random = new Random(System.currentTimeMillis()); + } } public void afterPropertiesSet() throws Exception { @@ -124,6 +137,15 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao, } public synchronized void createUser(ArgeoUser user) { + // normalize password + if (user instanceof SimpleArgeoUser) { + if (user.getPassword() == null || user.getPassword().equals("")) + ((SimpleArgeoUser) user).setPassword(encodePassword(user + .getUsername())); + else if (!user.getPassword().startsWith("{")) + ((SimpleArgeoUser) user).setPassword(encodePassword(user + .getPassword())); + } userDetailsManager.createUser(new ArgeoUserDetails(user)); } @@ -197,6 +219,15 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao, } public synchronized void updateUser(ArgeoUser user) { + // normalize password + String password = user.getPassword(); + if (password == null) + password = getUserWithPassword(user.getUsername()).getPassword(); + if (!password.startsWith("{")) + password = encodePassword(user.getPassword()); + SimpleArgeoUser simpleArgeoUser = new SimpleArgeoUser(user); + simpleArgeoUser.setPassword(password); + ArgeoUserDetails argeoUserDetails = new ArgeoUserDetails(user); userDetailsManager.updateUser(new ArgeoUserDetails(user)); // refresh logged in user @@ -208,6 +239,28 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao, } } + public void updateCurrentUserPassword(String oldPassword, String newPassword) { + SimpleArgeoUser user = new SimpleArgeoUser( + ArgeoUserDetails.securityContextUser()); + if (!passwordEncoder.isPasswordValid(user.getPassword(), oldPassword, + null)) + throw new ArgeoException("Old password is not correct."); + user.setPassword(encodePassword(newPassword)); + updateUser(user); + } + + public void updateUserPassword(String username, String password) { + SimpleArgeoUser user = new SimpleArgeoUser(getUser(username)); + user.setPassword(encodePassword(password)); + updateUser(user); + } + + protected String encodePassword(String password) { + byte[] salt = new byte[16]; + random.nextBytes(salt); + return passwordEncoder.encodePassword(password, salt); + } + public synchronized void deleteUser(String username) { userDetailsManager.deleteUser(username); } @@ -338,4 +391,8 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, CurrentUserDao, return ldapUserDetailsService; } + public void setPasswordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + } -- 2.30.2