package eu.dnetlib.repo.manager.service.security; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import eu.dnetlib.repo.manager.domain.dto.User; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.mitre.openid.connect.model.UserInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Collection; import java.util.List; @Service("authorizationService") public class AuthorizationServiceImpl implements AuthorizationService { public static final String SUPER_ADMINISTRATOR = "SUPER_ADMINISTRATOR"; public static final String CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR = "CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR"; public static final String REGISTERED_USER = "REGISTERED_USER"; private final RoleMappingService roleMappingService; private final AaiRegistryService aaiRegistryService; private final AuthoritiesUpdater authoritiesUpdater; @Autowired AuthorizationServiceImpl(RoleMappingService roleMappingService, AaiRegistryService aaiRegistryService, AuthoritiesUpdater authoritiesUpdater) { this.roleMappingService = roleMappingService; this.aaiRegistryService = aaiRegistryService; this.authoritiesUpdater = authoritiesUpdater; } private String mapType(String type) { if (type.equals("datasource")) { type = "datasource"; } return type; } /** * Type = DATASOURCE */ @Override public String member(String type, String id) { return mapType(type).toUpperCase() + "_" + id.toUpperCase(); } @Override public boolean isMemberOf(String repoId) { String repoRole = roleMappingService.convertRepoIdToEncodedAuthorityId(repoId); return SecurityContextHolder.getContext().getAuthentication().getAuthorities() .stream().anyMatch(authority -> authority.toString().equals(repoRole)); } @Override public boolean isMemberOfInterface(String interfaceId) { //TODO blame Konstantinos Spyrou. He forced my hand... String repoId = interfaceId.split("::")[1] + "::" + interfaceId.split("::")[2]; return isMemberOf(repoId); } @Override public List getAdminsOfRepo(String repoId) { List userList = new ArrayList<>(); // find couId by role name String role = roleMappingService.getRoleIdByRepoId(repoId); Integer couId = aaiRegistryService.getCouId(role); if (couId != null) { JsonArray users = aaiRegistryService.getUsersByCouId(couId); for (JsonElement jsonElement : users) { userList.add(jsonElement.toString()); } } return aaiRegistryService.getUsers(couId); } @Override public boolean addAdmin(String id, String email) throws ResourceNotFoundException { Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); if (coPersonId != null) { String role = roleMappingService.getRoleIdByRepoId(id); Integer couId = aaiRegistryService.getCouId(role); if (couId != null) { Integer roleId = aaiRegistryService.getRoleId(coPersonId, couId); aaiRegistryService.assignMemberRole(coPersonId, couId, roleId); // Add role to user current authorities authoritiesUpdater.addRole(email, roleMappingService.convertRepoIdToAuthority(id)); return true; } else { throw new ResourceNotFoundException("Cannot find CouId for role: " + role); } } else { throw new ResourceNotFoundException("Cannot find coPersonId for user with email: " + email); } } @Override public boolean removeAdmin(String id, String email) throws ResourceNotFoundException { Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); if (coPersonId != null) { String role = roleMappingService.getRoleIdByRepoId(id); Integer couId = aaiRegistryService.getCouId(role); Integer roleId = null; if (couId != null) { roleId = aaiRegistryService.getRoleId(coPersonId, couId); } if (couId != null && roleId != null) { aaiRegistryService.removeMemberRole(coPersonId, couId, roleId); // Remove role from user current authorities authoritiesUpdater.removeRole(email, roleMappingService.convertRepoIdToAuthority(id)); return true; } else { throw new ResourceNotFoundException("Cannot find CouId for role: " + role); } } else { throw new ResourceNotFoundException("Cannot find coPersonId for user with email: " + email); } } @Override public Collection getUserRoles() { List roles; JsonArray entitlements; UserInfo userInfo = ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo(); if (userInfo.getSource().getAsJsonArray("edu_person_entitlements") != null) { entitlements = userInfo.getSource().getAsJsonArray("edu_person_entitlements"); } else if (userInfo.getSource().getAsJsonArray("eduperson_entitlement") != null) { entitlements = userInfo.getSource().getAsJsonArray("eduperson_entitlement"); } else { entitlements = new JsonArray(); } roles = AuthoritiesMapper.entitlementRoles(entitlements); return roles; } @Override public Collection getUserRoles(String email) { int coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); List list = new ArrayList<>(); for (JsonElement element : aaiRegistryService.getRolesWithStatus(coPersonId, AaiRegistryService.RoleStatus.ACTIVE)) { list.add(element.getAsJsonObject().get("CouId").getAsInt()); } return aaiRegistryService.getCouNames(list).values(); } }