package org.gcube.portal.oidc.lr62; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.gcube.oidc.D4ScienceMappings; import org.gcube.oidc.OIDCToSitesAndRolesMapper; import org.gcube.oidc.Site; import org.gcube.oidc.SitesMapperExecption; import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.RoleManager; import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.RoleRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserManagementPortalException; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeGroup; import org.gcube.vomanagement.usermanagement.model.GCubeRole; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.model.User; import com.liferay.portal.security.auth.PrincipalThreadLocal; import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil; import com.liferay.portal.security.permission.PermissionThreadLocal; import com.liferay.portal.service.UserLocalServiceUtil; public class UserSitesToGroupsAndRolesMapper { protected static final Log log = LogFactoryUtil.getLog(UserSitesToGroupsAndRolesMapper.class); protected User user; protected OIDCToSitesAndRolesMapper mapper; protected UserManager userManager; protected GroupManager groupManager; protected RoleManager roleManager; protected String rootVOName; protected Map> actualGroupAndRoles; protected Map roleNameToRole; public UserSitesToGroupsAndRolesMapper(User user, OIDCToSitesAndRolesMapper mapper) { this.user = user; this.mapper = mapper; try { if (log.isDebugEnabled()) { log.debug("Creating the permission checker for admin user"); } long adminUserId = LiferayUserManager.getAdmin().getUserId(); PrincipalThreadLocal.setName(adminUserId); PermissionThreadLocal.setPermissionChecker( PermissionCheckerFactoryUtil.create(UserLocalServiceUtil.getUser(adminUserId))); } catch (Exception e) { log.fatal("Cannot create permission checker for admin user", e); return; } userManager = new LiferayUserManager(); groupManager = new LiferayGroupManager(); roleManager = new LiferayRoleManager(); try { this.rootVOName = groupManager.getRootVOName(); } catch (UserManagementSystemException | GroupRetrievalFault e) { log.error("Cannot get infrastructure's Root VO", e); return; } try { Map> retrivedGroupAndRoles = groupManager .listGroupsAndRolesByUser(user.getUserId()); actualGroupAndRoles = new TreeMap>(); for (GCubeGroup gCubeGroup : retrivedGroupAndRoles.keySet()) { List newList = new ArrayList(); actualGroupAndRoles.put(gCubeGroup.getGroupId(), newList); for (GCubeRole gCubeRole : retrivedGroupAndRoles.get(gCubeGroup)) { newList.add(gCubeRole.getRoleName()); } } } catch (UserManagementSystemException e) { log.error("Cannot get sites and roles membership for user", e); return; } roleNameToRole = new TreeMap<>(); for (GCubeRole role : roleManager.listAllGroupRoles()) { roleNameToRole.put(role.getRoleName(), role); } } public void map() { log.debug("Mapping roles to sites for user: " + user.getScreenName()); Site gwSitesTree = null; try { gwSitesTree = mapper.map(rootVOName); if (log.isDebugEnabled()) { log.debug("Sites tree is: " + (gwSitesTree != null ? gwSitesTree.dump() : "null")); } } catch (SitesMapperExecption e) { log.error("Computing sites tree in concrete mapper class", e); } if (gwSitesTree != null) { if (log.isDebugEnabled()) { log.debug("Check user to sites assignemnts"); } rolesToSiteDescendant(gwSitesTree); } if (log.isDebugEnabled()) { log.debug("Check user to sites removal"); } checkForSiteRemoval(gwSitesTree); } protected void rolesToSiteDescendant(Site actualSite) { Long actualSiteGroupId = null; try { if (log.isDebugEnabled()) { log.debug("Getting actual site group from group manager, actual site: " + actualSite.getName()); } actualSiteGroupId = groupManager.getGroupId(actualSite.getName()); } catch (UserManagementSystemException | GroupRetrievalFault e) { log.error("Cannot retrieve group for site: " + actualSite.getName(), e); return; } if (actualSiteGroupId < 0) { log.info("Retrieved group id is not valid for the site: " + actualSite.getName()); return; } try { if (groupManager.isVRE(actualSiteGroupId) && !actualGroupAndRoles.containsKey(actualSiteGroupId)) { log.debug("Assigning user to new VRE site: " + actualSite.getName()); userManager.assignUserToGroup(actualSiteGroupId, user.getUserId()); if (actualSite.getRoles() != null && !actualSite.getRoles().isEmpty()) { log.debug("Assiging roles for the new assigned VRE site"); for (String roleName : actualSite.getRoles()) { if (D4ScienceMappings.Role.MEMBER.asString().equals(roleName)) { // Member role is only to assure that the user belongs to context, covered by the assign continue; } roleManager.assignRoleToUser(user.getUserId(), actualSiteGroupId, roleNameToRole.get(roleName).getRoleId()); } // Since it's a VRE we can return return; } else { log.debug("User has no roles in the VRE site"); } } } catch (UserManagementSystemException | GroupRetrievalFault | UserRetrievalFault | UserManagementPortalException | RoleRetrievalFault | RuntimeException e) { log.error("Assigning user to new VRE site: " + actualSite.getName(), e); } if (actualSite.getRoles() != null) { List actualSiteGroupRoles = actualGroupAndRoles.get(actualSiteGroupId); List newRoles = new ArrayList<>(actualSite.getRoles()); // Removing the Member role that is not a real role in LR newRoles.remove(D4ScienceMappings.Role.MEMBER.asString()); if (actualSiteGroupRoles != null && !actualSiteGroupRoles.isEmpty()) { log.debug("Checking actual roles in the site's group"); for (String gcRoleName : actualSiteGroupRoles) { String actualSiteName = actualSite.getName(); // 'D4ScienceMappings.Role.exists(gcRoleName)' is used to be sure that is a d4s role and not // a Liferay role that must be let as it is if (D4ScienceMappings.Role.exists(gcRoleName) && !actualSite.getRoles().contains(gcRoleName)) { try { log.debug("Removing '" + gcRoleName + "' user's role for site: " + actualSiteName); roleManager.removeRoleFromUser(user.getUserId(), actualSiteGroupId, roleNameToRole.get(gcRoleName).getRoleId()); } catch (UserManagementSystemException | UserRetrievalFault | GroupRetrievalFault | RoleRetrievalFault e) { log.error("Can't remove user role '" + gcRoleName + "' from: " + actualSiteName, e); continue; } } else { if (log.isTraceEnabled()) { log.trace("User still have role in the site, emoving it from the new roles list: " + gcRoleName); } newRoles.remove(gcRoleName); } } } else { log.debug("User actually has no roles different from Member in the site"); } if (!newRoles.isEmpty()) { // Adding roles that remaining in newRoles list, if any, for the user in this site for (String newRole : newRoles) { if (log.isDebugEnabled()) { log.debug("Adding new role to user. New role: " + newRole); } GCubeRole newGcRole = roleNameToRole.get(newRole); if (newGcRole != null) { try { log.debug("Assinging new role '" + newRole + "' to user"); roleManager.assignRoleToUser(user.getUserId(), actualSiteGroupId, newGcRole.getRoleId()); } catch (UserManagementSystemException | UserRetrievalFault | GroupRetrievalFault | RoleRetrievalFault e) { log.error("Cannot assign new role '" + newRole + "' for site: " + actualSite.getName(), e); continue; } } else { log.warn("New site's gc role is null (doesn't exist?) after getting it from role manager: " + newRole); } } } else { if (log.isDebugEnabled()) { log.debug("User has no new roles for the site"); } } } else { log.debug("Roles were not set, continuing descending letting them untouched in site: " + actualSite.getName()); } for (Site childSite : actualSite.getChildren().values()) { log.debug("Recursive call to child site: " + childSite.getName()); rolesToSiteDescendant(childSite); } } protected void checkForSiteRemoval(Site gwSitesTree) { List vreNames = new ArrayList<>(); if (gwSitesTree != null) { log.debug("Collecting VREs user belongs to"); for (Site vo : gwSitesTree.getChildren().values()) { for (Site vre : vo.getChildren().values()) { String vreName = vre.getName(); log.trace("Adding VRE to the list: " + vreName); vreNames.add(vreName); } } } else { log.debug("User not belongs to any VRE"); } for (Long actualGroupId : actualGroupAndRoles.keySet()) { try { String actualGroupName = groupManager.getGroup(actualGroupId).getGroupName(); if (groupManager.isVRE(actualGroupId)) { if (!vreNames.contains(actualGroupName)) { log.debug("Removing user from VRE: " + actualGroupName); try { userManager.dismissUserFromGroup(actualGroupId, user.getUserId()); } catch (UserRetrievalFault e) { log.error("Removing user from VRE: " + actualGroupName, e); } } else { if (log.isDebugEnabled()) { log.debug("User still belong to VRE: " + actualGroupName); } } } else { log.debug("Do not check membership for non VRE: " + actualGroupName); } } catch (UserManagementSystemException | GroupRetrievalFault e) { log.error("Checking if site group is a VRE", e); } } } }