/* * Copyright (C) 2007-2012 GeoSolutions S.A.S. * http://www.geo-solutions.it * * GPLv3 + Classpath exception * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package it.geosolutions.geostore.services; import it.geosolutions.geostore.core.dao.ResourceDAO; import it.geosolutions.geostore.core.dao.SecurityDAO; import it.geosolutions.geostore.core.dao.UserDAO; import it.geosolutions.geostore.core.dao.UserGroupDAO; import it.geosolutions.geostore.core.model.Resource; import it.geosolutions.geostore.core.model.SecurityRule; import it.geosolutions.geostore.core.model.User; import it.geosolutions.geostore.core.model.UserGroup; import it.geosolutions.geostore.core.model.enums.GroupReservedNames; import it.geosolutions.geostore.core.model.enums.Role; import it.geosolutions.geostore.services.dto.ShortResource; import it.geosolutions.geostore.services.exception.BadRequestServiceEx; import it.geosolutions.geostore.services.exception.NotFoundServiceEx; import it.geosolutions.geostore.services.exception.ReservedUserGroupNameEx; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.googlecode.genericdao.search.Search; /** * @author DamianoG * */ public class UserGroupServiceImpl implements UserGroupService{ private static final Logger LOGGER = Logger.getLogger(UserGroupServiceImpl.class); private UserGroupDAO userGroupDAO; private UserDAO userDAO; private ResourceDAO resourceDAO; private SecurityDAO securityDAO; /** * @param userGroupDAO the userGroupDAO to set */ public void setUserGroupDAO(UserGroupDAO userGroupDAO) { this.userGroupDAO = userGroupDAO; } /** * * @param userDAO the userDAO to set */ public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } /** * * @param resourceDAO the resourceDAO to set */ public void setResourceDAO(ResourceDAO resourceDAO) { this.resourceDAO = resourceDAO; } /** * @param securityDAO the securityDAO to set */ public void setSecurityDAO(SecurityDAO securityDAO) { this.securityDAO = securityDAO; } /* (non-Javadoc) * @see it.geosolutions.geostore.services.UserGroupService#insert(it.geosolutions.geostore.core.model.UserGroup) */ @Override public long insert(UserGroup userGroup) throws BadRequestServiceEx { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Persisting UserGroup... "); } if (userGroup == null || StringUtils.isEmpty(userGroup.getGroupName())) { throw new BadRequestServiceEx("The provided UserGroup instance is null or group Name is not specified!"); } if(!GroupReservedNames.isAllowedName(userGroup.getGroupName())){ throw new ReservedUserGroupNameEx("The usergroup name you try to save: '" + userGroup.getGroupName() + "' is a reserved name!"); } userGroup.setGroupName(userGroup.getGroupName()); userGroupDAO.persist(userGroup); if (LOGGER.isDebugEnabled()) { LOGGER.debug("UserGroup '" + userGroup.getGroupName() + "' persisted!"); } return userGroup.getId(); } /* (non-Javadoc) * @see it.geosolutions.geostore.services.UserGroupService#delete(long) */ @Override public boolean delete(long id) throws NotFoundServiceEx, BadRequestServiceEx { UserGroup group = userGroupDAO.find(id); if(group == null){ LOGGER.error("Can't find usergroup with id '" + id + "'"); throw new NotFoundServiceEx("Can't find usergroup with id '" + id + "'"); } if(!GroupReservedNames.isAllowedName(group.getGroupName())){ throw new BadRequestServiceEx("Delete a special usergroup ('" + group.getGroupName() + "' in this case) isn't possible"); } Set<User> users = group.getUsers(); for(User u : users){ u.getGroups().remove(group); userDAO.merge(u); } userGroupDAO.remove(group); return true; } /* (non-Javadoc) * @see it.geosolutions.geostore.services.UserGroupService#assignUserGroup(long, long) */ @Override public void assignUserGroup(long userId, long groupId) throws NotFoundServiceEx{ UserGroup groupToAssign = userGroupDAO.find(groupId); // Check if the group user want to assign is an allowed one if(!GroupReservedNames.isAllowedName(groupToAssign.getGroupName())){ throw new NotFoundServiceEx("You can't re-assign the group EVERYONE or any other reserved groups..."); } User targetUser = userDAO.find(userId); if(groupToAssign == null || targetUser == null){ throw new NotFoundServiceEx("The userGroup or the user you provide doesn't exist"); } if(targetUser.getGroups() == null){ Set<UserGroup> groups = new HashSet<UserGroup>(); groups.add(groupToAssign); targetUser.setGroups(groups); userDAO.merge(targetUser); } else{ targetUser.getGroups().add(groupToAssign); userDAO.merge(targetUser); } } /* (non-Javadoc) * @see it.geosolutions.geostore.services.UserGroupService#deassignUserGroup(long, long) */ @Override public void deassignUserGroup(long userId, long groupId) throws NotFoundServiceEx{ UserGroup groupToAssign = userGroupDAO.find(groupId); // Check if the group user want to remove is an allowed one if(!GroupReservedNames.isAllowedName(groupToAssign.getGroupName())){ throw new NotFoundServiceEx("You can't remove the group EVERYONE or any other reserved groups from the users group list..."); } User targetUser = userDAO.find(userId); if(groupToAssign == null || targetUser == null){ throw new NotFoundServiceEx("The userGroup or the user you provide doesn't exist"); } if(targetUser.getGroups() != null){ Set<UserGroup> ugs = targetUser.getGroups(); for( UserGroup group : ugs){ if( group.getId() == groupId){ targetUser.getGroups().remove(group); userDAO.merge(targetUser); return; } } } } /* (non-Javadoc) * @see it.geosolutions.geostore.services.UserGroupService#getAll(java.lang.Integer, java.lang.Integer) */ @Override public List<UserGroup> getAll(Integer page, Integer entries) throws BadRequestServiceEx { if (((page != null) && (entries == null)) || ((page == null) && (entries != null))) { throw new BadRequestServiceEx("Page and entries params should be declared together."); } Search searchCriteria = new Search(UserGroup.class); if (page != null) { searchCriteria.setMaxResults(entries); searchCriteria.setPage(page); } searchCriteria.addSortAsc("groupName"); List<UserGroup> found = userGroupDAO.search(searchCriteria); return found; } @Override public List<UserGroup> getAllAllowed(User user, Integer page, Integer entries, String nameLike, boolean all) throws BadRequestServiceEx { if (user == null) throw new BadRequestServiceEx("User must be defined."); if (((page != null) && (entries == null)) || ((page == null) && (entries != null))) { throw new BadRequestServiceEx("Page and entries params should be declared together."); } Search searchCriteria = new Search(UserGroup.class); if (page != null) { searchCriteria.setMaxResults(entries); searchCriteria.setPage(page); } searchCriteria.addSortAsc("groupName"); Role userRole = user.getRole(); if (userRole.equals((Role)Role.USER)){ Set<UserGroup> userGrp = user.getGroups(); Collection<Long> grpIds = new Vector<Long>(); for(UserGroup grp :userGrp){ grpIds.add(grp.getId()); } searchCriteria.addFilterIn("id", grpIds); } if (nameLike != null) searchCriteria.addFilterILike("groupName", nameLike); if(!all) searchCriteria.addFilterNotEqual("groupName", GroupReservedNames.EVERYONE.groupName()); List<UserGroup> found = userGroupDAO.search(searchCriteria); return found; } /* (non-Javadoc) * @see it.geosolutions.geostore.services.UserGroupService#updateSecurityRules(java.lang.Long, java.util.List, boolean, boolean) */ @Override public List<ShortResource> updateSecurityRules(Long groupId, List<Long> resourcesIds, boolean canRead, boolean canWrite) throws NotFoundServiceEx, BadRequestServiceEx { List<ShortResource> updated = new ArrayList<ShortResource>(); UserGroup group = userGroupDAO.find(groupId); if(group == null){ throw new NotFoundServiceEx("The usergroup id you provide doesn't exist!"); } if(group.getGroupName().equals(GroupReservedNames.EVERYONE.groupName())){ if(!canRead || canWrite){ LOGGER.error("You are trying to assign to a resource the following permissions for the group EVERYONE: [canRead='" + canRead + "',canWrite'" + canWrite + "'] but..."); LOGGER.error("...the group EVERYONE can be set only in this way: [canRead='true',canWrite='false'] ."); throw new BadRequestServiceEx("GroupEveryone cannot be set with this grants [canRead='" + canRead + "',canWrite'" + canWrite + "']"); } } List<Resource> resourceToSet = resourceDAO.findResources(resourcesIds); for(Resource resource : resourceToSet){ SecurityRule sr = getRuleForGroup(resource.getSecurity(), group); if(sr == null){ // Create new rule SecurityRule newSR = new SecurityRule(); newSR.setCanRead(canRead); newSR.setCanWrite(canWrite); newSR.setGroup(group); newSR.setResource(resource); securityDAO.persist(newSR); resource.getSecurity().add(newSR); ShortResource out = new ShortResource(resource); // In this case the short resource to return is not related to the permission available by the user // who call the service (like in other service) but can Delete/Edit are set as the rule updated. out.setCanDelete(canWrite); out.setCanEdit(canWrite); updated.add(out); } else{ // Update the existing rule sr.setCanRead(canRead); sr.setCanWrite(canWrite); securityDAO.merge(sr); ShortResource out = new ShortResource(resource); // In this case the short resource to return is not related to the permission available by the user // who call the sevrice (like in other service) but can Delete/Edit are set as the rule updated. out.setCanDelete(canWrite); out.setCanEdit(canWrite); updated.add(out); } } return updated; } private SecurityRule getRuleForGroup(List<SecurityRule> securityList, UserGroup group){ for(SecurityRule sr : securityList){ if(sr.getGroup() != null && sr.getGroup().getGroupName() != null && sr.getGroup().getGroupName().equals(group.getGroupName())){ return sr; } } return null; } public boolean insertSpecialUsersGroups(){ if (LOGGER.isDebugEnabled()) { LOGGER.debug("Persisting Reserved UsersGroup... "); } UserGroup ug = new UserGroup(); ug.setGroupName(GroupReservedNames.EVERYONE.groupName()); userGroupDAO.persist(ug); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Special UserGroup '" + ug.getGroupName() + "' persisted!"); } return true; } @Override public UserGroup get(long id) throws BadRequestServiceEx { return userGroupDAO.find(id); } @Override public UserGroup get(String name) { // // Searching the corresponding UserGroups // Search searchCriteria = new Search(UserGroup.class); searchCriteria.addFilterEqual("groupName", name); List<UserGroup> existingGroups = userGroupDAO.search(searchCriteria); if(existingGroups.size()>0){ return existingGroups.get(0); } return null; } @Override public long getCount(User user, String nameLike, boolean all) throws BadRequestServiceEx { if (user == null) throw new BadRequestServiceEx("User must be defined."); Search searchCriteria = new Search(UserGroup.class); searchCriteria.addSortAsc("groupName"); Role userRole = user.getRole(); if (userRole.equals((Role)Role.USER)){ Set<UserGroup> userGrp = user.getGroups(); Collection<Long> grpIds = new Vector<Long>(); for(UserGroup grp :userGrp){ grpIds.add(grp.getId()); } searchCriteria.addFilterIn("id", grpIds); } if (nameLike != null) { searchCriteria.addFilterILike("groupName", nameLike); } if(!all) searchCriteria.addFilterNotEqual("groupName", GroupReservedNames.EVERYONE.groupName()); return userGroupDAO.count(searchCriteria); } public long getCount(User user, String nameLike) throws BadRequestServiceEx { return getCount(user, nameLike, false); } }