parent
							
								
									e15eec7fdd
								
							
						
					
					
						commit
						488a7d720b
					
				| @ -0,0 +1,133 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited | ||||||
|  |  * | ||||||
|  |  * 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.libresonic.player.security; | ||||||
|  | 
 | ||||||
|  | import org.libresonic.player.Logger; | ||||||
|  | import org.libresonic.player.domain.User; | ||||||
|  | import org.libresonic.player.service.SecurityService; | ||||||
|  | import org.libresonic.player.service.SettingsService; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.ldap.core.DirContextAdapter; | ||||||
|  | import org.springframework.ldap.core.DirContextOperations; | ||||||
|  | import org.springframework.security.authentication.BadCredentialsException; | ||||||
|  | import org.springframework.security.core.GrantedAuthority; | ||||||
|  | import org.springframework.security.core.userdetails.UserDetails; | ||||||
|  | import org.springframework.security.ldap.ppolicy.PasswordPolicyControl; | ||||||
|  | import org.springframework.security.ldap.ppolicy.PasswordPolicyResponseControl; | ||||||
|  | import org.springframework.security.ldap.userdetails.LdapUserDetailsImpl; | ||||||
|  | import org.springframework.security.ldap.userdetails.UserDetailsContextMapper; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | import java.util.Collection; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class LibresonicUserDetailsContextMapper implements UserDetailsContextMapper { | ||||||
|  |     // ~ Instance fields
 | ||||||
|  |     // ================================================================================================
 | ||||||
|  | 
 | ||||||
|  |     private final Logger logger = Logger.getLogger(LibresonicUserDetailsContextMapper.class); | ||||||
|  |     private String passwordAttributeName = "userPassword"; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     SecurityService securityService; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     SettingsService settingsService; | ||||||
|  | 
 | ||||||
|  |     // ~ Methods
 | ||||||
|  |     // ========================================================================================================
 | ||||||
|  | 
 | ||||||
|  |     public UserDetails mapUserFromContext(DirContextOperations ctx, String username, | ||||||
|  |                                           Collection<? extends GrantedAuthority> authorities) { | ||||||
|  |         String dn = ctx.getNameInNamespace(); | ||||||
|  | 
 | ||||||
|  |         logger.debug("Mapping user details from context with DN: " + dn); | ||||||
|  | 
 | ||||||
|  |         // User must be defined in Libresonic, unless auto-shadowing is enabled.
 | ||||||
|  |         User user = securityService.getUserByName(username, false); | ||||||
|  |         if (user == null && !settingsService.isLdapAutoShadowing()) { | ||||||
|  |             throw new BadCredentialsException("User does not exist."); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (user == null) { | ||||||
|  |             User newUser = new User(username, "", null, true, 0L, 0L, 0L); | ||||||
|  |             newUser.setStreamRole(true); | ||||||
|  |             newUser.setSettingsRole(true); | ||||||
|  |             securityService.createUser(newUser); | ||||||
|  |             logger.info("Created local user '" + username + "' for DN " + dn); | ||||||
|  |             user = securityService.getUserByName(username, false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // LDAP authentication must be enabled for the given user.
 | ||||||
|  |         if (!user.isLdapAuthenticated()) { | ||||||
|  |             throw new BadCredentialsException("LDAP authentication disabled for user."); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         LdapUserDetailsImpl.Essence essence = new LdapUserDetailsImpl.Essence(); | ||||||
|  |         essence.setDn(dn); | ||||||
|  | 
 | ||||||
|  |         Object passwordValue = ctx.getObjectAttribute(passwordAttributeName); | ||||||
|  | 
 | ||||||
|  |         if (passwordValue != null) { | ||||||
|  |             essence.setPassword(mapPassword(passwordValue)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         essence.setUsername(user.getUsername()); | ||||||
|  | 
 | ||||||
|  |         // Add the supplied authorities
 | ||||||
|  |         for (GrantedAuthority authority : securityService.getGrantedAuthorities(user.getUsername())) { | ||||||
|  |             essence.addAuthority(authority); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Check for PPolicy data
 | ||||||
|  | 
 | ||||||
|  |         PasswordPolicyResponseControl ppolicy = (PasswordPolicyResponseControl) ctx | ||||||
|  |                 .getObjectAttribute(PasswordPolicyControl.OID); | ||||||
|  | 
 | ||||||
|  |         if (ppolicy != null) { | ||||||
|  |             essence.setTimeBeforeExpiration(ppolicy.getTimeBeforeExpiration()); | ||||||
|  |             essence.setGraceLoginsRemaining(ppolicy.getGraceLoginsRemaining()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return essence.createUserDetails(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void mapUserToContext(UserDetails user, DirContextAdapter ctx) { | ||||||
|  |         throw new UnsupportedOperationException( | ||||||
|  |                 "LdapUserDetailsMapper only supports reading from a context. Please" | ||||||
|  |                         + "use a subclass if mapUserToContext() is required."); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Extension point to allow customized creation of the user's password from the | ||||||
|  |      * attribute stored in the directory. | ||||||
|  |      * | ||||||
|  |      * @param passwordValue the value of the password attribute | ||||||
|  |      * @return a String representation of the password. | ||||||
|  |      */ | ||||||
|  |     protected String mapPassword(Object passwordValue) { | ||||||
|  | 
 | ||||||
|  |         if (!(passwordValue instanceof String)) { | ||||||
|  |             // Assume it's binary
 | ||||||
|  |             passwordValue = new String((byte[]) passwordValue); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return (String) passwordValue; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in new issue