/* * LinShare is an open source filesharing software, part of the LinPKI software * suite, developed by Linagora. * * Copyright (C) 2015 LINAGORA * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version, provided you comply with the Additional Terms applicable for * LinShare software by Linagora pursuant to Section 7 of the GNU Affero General * Public License, subsections (b), (c), and (e), pursuant to which you must * notably (i) retain the display of the “LinShare™” trademark/logo at the top * of the interface window, the display of the “You are using the Open Source * and free version of LinShare™, powered by Linagora © 2009–2015. Contribute to * Linshare R&D by subscribing to an Enterprise offer!” infobox and in the * e-mails sent with the Program, (ii) retain all hypertext links between * LinShare and linshare.org, between linagora.com and Linagora, and (iii) * refrain from infringing Linagora intellectual property rights over its * trademarks and commercial brands. Other Additional Terms apply, see * <http://www.linagora.com/licenses/> for more details. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License and * its applicable Additional Terms for LinShare along with this program. If not, * see <http://www.gnu.org/licenses/> for the GNU Affero General Public License * version 3 and <http://www.linagora.com/licenses/> for the Additional Terms * applicable to LinShare software. */ package org.linagora.linshare.auth.dao; import java.io.IOException; import java.util.List; import javax.naming.NamingException; import org.linagora.linshare.core.domain.entities.AbstractDomain; import org.linagora.linshare.core.domain.entities.User; import org.linagora.linshare.core.exception.BusinessException; import org.linagora.linshare.core.facade.auth.AuthentificationFacade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.userdetails.UsernameNotFoundException; public class LdapUserDetailsProvider extends UserDetailsProvider { private static final Logger logger = LoggerFactory.getLogger(LdapUserDetailsProvider.class); public LdapUserDetailsProvider(AuthentificationFacade authentificationFacade) { super(authentificationFacade); } /** * Looking for an user in the database and then into the LDAP directory. * @param domainIdentifier : could be null. * @param login : user login, ie mail * @return User account. */ @Override public User retrieveUser(String domainIdentifier, String login) { User foundUser = null; // if domain was specified at the connection, we try to search the // user on this domain and its sub domains. try { if (domainIdentifier != null) { foundUser = findUserInDomainAndSubdomains(login, domainIdentifier); } else { // There is no constraints, we have to search the current user in // all domains. foundUser = findUserInAllDomain(login); } // Check if it is a guest. Should not happen. if (!foundUser.isInternal()) { logger.debug("Guest found during ldap authentification process."); logAuthError(foundUser, domainIdentifier, "User not found."); String message = "Guest found : " + foundUser.getAccountRepresentation() + " in domain : '" + domainIdentifier + "'"; logAuthError(login, domainIdentifier, message); throw new UsernameNotFoundException(message); } if (foundUser.getDomain() == null) { String message = "Bad credentials"; logAuthError(foundUser, domainIdentifier, message); logger.error("The user found in the database contain a null domain reference."); throw new BadCredentialsException("Could not authenticate user: " + login); } } catch (BusinessException e) { logger.error("Couldn't find user during authentication process : " + e.getMessage()); logAuthError(login, null, e.getMessage()); throw new AuthenticationServiceException( "Could not authenticate user: " + login); } return foundUser; } private User findUserInDomainAndSubdomains(String login, String domainIdentifier) throws BusinessException { User foundUser; logger.debug("The domain was specified at the connection time : " + domainIdentifier); // check if domain really exist. AbstractDomain domain = retrieveDomain(login, domainIdentifier); // looking in database for a user. foundUser = authentificationFacade.findByLoginAndDomain(domainIdentifier, login); if (foundUser != null) { foundUser = checkStillInLdap(login, foundUser); } else { logger.debug("Can't find the user in the DB. Searching in LDAP."); // searching in LDAP foundUser = authentificationFacade.ldapSearchForAuth( domain.getUuid(), login); if (foundUser != null) { // if found we set the domain which belong the user. foundUser.setDomain(domain); } else { List<String> subdomainIdentifiers = authentificationFacade.getAllSubDomainIdentifiers(domainIdentifier); for (String subdomainIdentifier : subdomainIdentifiers) { foundUser = authentificationFacade.ldapSearchForAuth( subdomainIdentifier, login); if (foundUser != null) { // if found we set the domain which belong the user. foundUser.setDomain(authentificationFacade.retrieveDomain(subdomainIdentifier)); logger.debug("User found and authenticated in domain " + subdomainIdentifier); break; } } } } if (foundUser == null) { String message = "User not found ! Login : '" + login + "' in domain : '" + domainIdentifier + "'"; logAuthError(login, domainIdentifier, message); throw new UsernameNotFoundException(message); } else { logger.debug("User found in ldap : " + foundUser.getAccountRepresentation() + " (domain:" + foundUser.getDomainId() + ")"); } return foundUser; } private User findUserInAllDomain(String login) throws BusinessException { User foundUser = null; try { foundUser = authentificationFacade.findByLogin(login); } catch (IllegalStateException e) { throw new AuthenticationServiceException( "Could not authenticate user: " + login); } if (foundUser != null) { foundUser = checkStillInLdap(login, foundUser); } else { logger.debug("Can't find the user in DB. Searching user in all LDAP domains."); List<AbstractDomain> domains = authentificationFacade .getAllDomains(); for (AbstractDomain loopedDomain : domains) { foundUser = authentificationFacade.ldapSearchForAuth( loopedDomain.getUuid(), login); if (foundUser != null) { foundUser.setDomain(loopedDomain); logger.debug("User found in domain " + loopedDomain.getUuid()); break; } } } if (foundUser == null) { String message = "User not found ! Login : " + login; logAuthError(login, null, message); throw new UsernameNotFoundException("No user found for login: " + message); } else { logger.debug("User found in ldap : " + foundUser.getAccountRepresentation() + " (domain:" + foundUser.getDomainId() + ")"); } return foundUser; } private User checkStillInLdap(String login, User foundUser) throws BusinessException { return authentificationFacade.checkStillInLdap(foundUser, login); } public User auth(String domainIdentifier, String login, String userPasswd) throws NamingException, IOException , BusinessException { return authentificationFacade.ldapAuth(domainIdentifier, login, userPasswd); } public User findOrCreateUser(String domainIdentifier, String mail) throws BusinessException { return authentificationFacade.findOrCreateUser(domainIdentifier, mail); } }