/* * 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.core.facade.webservice.admin.impl; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.Validate; import org.linagora.linshare.core.domain.constants.AccountType; import org.linagora.linshare.core.domain.constants.Role; import org.linagora.linshare.core.domain.entities.AbstractDomain; import org.linagora.linshare.core.domain.entities.AllowedContact; import org.linagora.linshare.core.domain.entities.Guest; import org.linagora.linshare.core.domain.entities.User; import org.linagora.linshare.core.exception.BusinessErrorCode; import org.linagora.linshare.core.exception.BusinessException; import org.linagora.linshare.core.facade.webservice.admin.UserFacade; import org.linagora.linshare.core.facade.webservice.admin.dto.InconsistentSearchDto; import org.linagora.linshare.core.facade.webservice.common.dto.PasswordDto; import org.linagora.linshare.core.facade.webservice.common.dto.UserDto; import org.linagora.linshare.core.facade.webservice.common.dto.UserSearchDto; import org.linagora.linshare.core.service.AbstractDomainService; import org.linagora.linshare.core.service.AccountService; import org.linagora.linshare.core.service.GuestService; import org.linagora.linshare.core.service.InconsistentUserService; import org.linagora.linshare.core.service.UserProviderService; import org.linagora.linshare.core.service.UserService; import com.google.common.collect.Lists; import com.google.common.collect.Sets; public class UserFacadeImpl extends AdminGenericFacadeImpl implements UserFacade { final private static int AUTO_COMPLETE_LIMIT = 20; private final UserService userService; private final GuestService guestService; private final InconsistentUserService inconsistentUserService; private final AbstractDomainService abstractDomainService; private final UserProviderService userProviderService; public UserFacadeImpl(final AccountService accountService, final UserService userService, final InconsistentUserService inconsistentUserService, final GuestService guestService, final AbstractDomainService abstractDomainService, final UserProviderService userProviderService) { super(accountService); this.userService = userService; this.inconsistentUserService = inconsistentUserService; this.guestService = guestService; this.abstractDomainService = abstractDomainService; this.userProviderService = userProviderService; } @Override public List<UserDto> search(UserSearchDto userSearchDto) throws BusinessException { User actor = checkAuthentication(Role.ADMIN); return searchUsers(userSearchDto.getFirstName(), userSearchDto.getLastName(), userSearchDto.getMail(), null); } @Override public Set<UserDto> searchInternals(String pattern) throws BusinessException { User actor = checkAuthentication(Role.ADMIN); return searchUsers(pattern, AccountType.INTERNAL); } @Override public Set<UserDto> searchGuests(String pattern) throws BusinessException { User actor = checkAuthentication(Role.ADMIN); return searchUsers(pattern, AccountType.GUEST); } /** * Search users using firstname, lastname and mail as search criteria. Each * param can be null. If all parameters are null, return all. * * @param firstName * @param lastName * @param mail * @param type * @return * @throws BusinessException */ private List<UserDto> searchUsers(String firstName, String lastName, String mail, AccountType type) throws BusinessException { User currentUser = super.checkAuthentication(Role.ADMIN); List<UserDto> usersDto = Lists.newArrayList(); Set<User> users = new HashSet<User>(); users.addAll(userService.searchUser(mail, firstName, lastName, type, currentUser)); for (User user : users) { UserDto userDto = UserDto.getFull(user); if (user.isGuest() && user.isRestricted()) { Guest guest = guestService.find(currentUser, currentUser, user.getLsUuid()); Set<AllowedContact> contacts = guest.getRestrictedContacts(); for (AllowedContact contact : contacts) { userDto.getRestrictedContacts().add( UserDto.getSimple(contact.getContact())); } } usersDto.add(userDto); } return usersDto; } private Set<UserDto> searchUsers(String pattern, AccountType type) throws BusinessException { Set<UserDto> usersDto = new HashSet<UserDto>(); usersDto.addAll(searchUsers(pattern, null, null, type)); usersDto.addAll(searchUsers(null, pattern, null, type)); usersDto.addAll(searchUsers(null, null, pattern, type)); return usersDto; } @Override public UserDto update(UserDto userDto) throws BusinessException { Validate.notNull(userDto, "user must be set."); Validate.notEmpty(userDto.getUuid(), "uuid must be set."); Validate.notNull(userDto.getLocale(), "locale must be set."); User actor = checkAuthentication(Role.ADMIN); User entity = userService.findByLsUuid(userDto.getUuid()); if (entity == null) { throw new BusinessException(BusinessErrorCode.USER_NOT_FOUND, "Can not find user"); } User userToUpdate = userDto.toUserObject(entity.isGuest()); User update; if (entity.isGuest()) { List<String> ac = null; if (userDto.isRestricted()) { ac = Lists.newArrayList(); for (UserDto contactDto : userDto.getRestrictedContacts()) { ac.add(contactDto.getMail()); } } update = guestService.update(actor, (User) entity.getOwner(), (Guest) userToUpdate, ac); } else { update = userService.updateUser(actor, userToUpdate, userDto.getDomain()); } return UserDto.getSimple(update); } @Override public UserDto delete(UserDto userDto) throws BusinessException { User actor = checkAuthentication(Role.ADMIN); String uuid = userDto.getUuid(); Validate.notEmpty(uuid, "user unique identifier must be set."); User user = userService.deleteUser(actor, uuid); return UserDto.getFull(user); } @Override public Set<UserDto> findAllInconsistent() throws BusinessException { User actor = checkAuthentication(Role.SUPERADMIN); Set<UserDto> ret = Sets.newHashSet(); for (User user : inconsistentUserService.findAllInconsistent(actor)) { ret.add(UserDto.getFull(user)); } return ret; } @Override public void updateInconsistent(UserDto userDto) throws BusinessException { User actor = checkAuthentication(Role.SUPERADMIN); update(userDto); inconsistentUserService.updateDomain(actor, userDto.getUuid(), userDto.getDomain()); } @Override public List<InconsistentSearchDto> checkInconsistentUserStatus(UserSearchDto searchDto) { Validate.notNull(searchDto, "searchDto must not be null"); String mail = searchDto.getMail(); Validate.notEmpty(mail, "User mail must not be empty"); checkAuthentication(Role.SUPERADMIN); List<InconsistentSearchDto> res = Lists.newArrayList(); for (AbstractDomain domain : abstractDomainService.getAllDomains()) { User user = userService.findUserInDB(domain.getUuid(), mail); if (user != null) { if (!(user.isGuest() || user.isInternal())) { // we exclude technical users and root continue; } InconsistentSearchDto dto = new InconsistentSearchDto(domain, mail); dto.setDatabase(true); dto.setGuest(user.isGuest()); dto.setUuid(user.getLsUuid()); if (user.isInternal()) { dto.setLdap(abstractDomainService.isUserExist(domain, mail)); if (dto.isLdap()) { if (user.isInconsistent()) { user.setInconsistent(false); accountService.update(user); } } else { if (!user.isInconsistent()) { user.setInconsistent(true); accountService.update(user); } } } res.add(dto); } else { if (abstractDomainService.isUserExist(domain, mail)) { InconsistentSearchDto dto = new InconsistentSearchDto(domain, mail); dto.setLdap(true); res.add(dto); } } } return res; } @Override public List<String> autocompleteInconsistent(UserSearchDto dto) throws BusinessException { User actor = checkAuthentication(Role.SUPERADMIN); Set<String> res = Sets.newHashSet(); List<User> internals = abstractDomainService .autoCompleteUserWithoutDomainPolicies(actor, dto.getMail()); for (User user : internals) { res.add(user.getMail()); } res.addAll(accountService.findAllKnownEmails(actor, dto.getMail())); int range = (res.size() < AUTO_COMPLETE_LIMIT ? res.size() : AUTO_COMPLETE_LIMIT); return Lists.newArrayList(res).subList(0, range); } @Override public void changePassword(PasswordDto password) throws BusinessException { User actor = checkAuthentication(Role.SUPERADMIN); userService.changePassword(actor.getLsUuid(), actor.getMail(), password.getOldPwd(), password.getNewPwd()); } @Override public UserDto findUser(String uuid) throws BusinessException { User currentUser = checkAuthentication(Role.ADMIN); Validate.notEmpty(uuid, "User uuid must be set."); UserDto userDto = null; User user = userService.findByLsUuid(uuid); if (user.isGuest() && user.isRestricted()) { Guest guest = guestService.find(currentUser, currentUser, uuid); userDto = UserDto.getFull(guest); } else { userDto = UserDto.getFull(user); } return userDto; } @Override public boolean exist(String uuid) throws BusinessException { checkAuthentication(Role.ADMIN); Validate.notEmpty(uuid, "User uuid must be set."); return userService.exist(uuid); } @Override public UserDto create(UserDto userDto) throws BusinessException { User actor = checkAuthentication(Role.ADMIN); Validate.notNull(userDto, "User dto must be set."); String uuid = userDto.getUuid(); if (uuid != null) { if (userService.exist(uuid)) { return UserDto.getFull(userService.findByLsUuid(uuid)); } } String mail = userDto.getMail(); String domain = userDto.getDomain(); Validate.notEmpty(mail, "User mail must be set."); Validate.notEmpty(domain, "User domain identifier must be set."); User user = userService.findOrCreateUserWithDomainPolicies(domain, mail, actor.getDomainId()); return UserDto.getFull(user); } @Override public boolean updateEmail(String currentEmail, String newEmail) { User actor = checkAuthentication(Role.SUPERADMIN); logger.info("Start email migration..."); logger.info("Step 1: Find and update user's email ..."); boolean hasBeenUpdated = userService.updateUserEmail(actor, currentEmail, newEmail); if(hasBeenUpdated) { logger.info("Step 2: start updateMailingListEmail ..."); userService.updateMailingListEmail(actor, currentEmail, newEmail); logger.info("Step 3: start updateEmailLogEntry ..."); userService.updateEmailLogEntry(actor, currentEmail, newEmail); logger.info("Step 4: start updateRecipientFavourite ..."); userService.updateRecipientFavourite(actor, currentEmail, newEmail); } logger.info("End of email migration..."); return hasBeenUpdated; } }