diff --git a/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/adapters/impl/PerunAdapterRpc.java b/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/adapters/impl/PerunAdapterRpc.java index 05501b4c4395eb565b6b4d45ecb4920573d4d0e7..326e06ccf8f7abec9a1d4b095dee245fd71d80f5 100644 --- a/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/adapters/impl/PerunAdapterRpc.java +++ b/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/adapters/impl/PerunAdapterRpc.java @@ -37,11 +37,54 @@ import java.util.Set; import java.util.stream.Collectors; import static cz.muni.ics.oidc.models.PerunAttributeValue.STRING_TYPE; +import static cz.muni.ics.oidc.models.PerunAttributeValueAwareModel.ARRAY_TYPE; import static cz.muni.ics.oidc.models.enums.MemberStatus.VALID; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.ATTRIBUTES_MANAGER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.EXT_SOURCE_IDP; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.FACILITIES_MANAGER; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.GROUPS_MANAGER; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.MEMBERS_MANAGER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ALLOWED_GROUPS; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ALLOWED_RESOURCES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_APPLICATION_FORM; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ASSIGNED_GROUPS; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ASSIGNED_RESOURCES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ASSIGNED_RICH_RESOURCES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ATTRIBUTE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ATTRIBUTES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ENTITYLESS_ATTRIBUTES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_ENTITYLESS_KEYS; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_FACILITIES_BY_ATTRIBUTE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_GROUPS_WHERE_USER_IS_ACTIVE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_GROUP_BY_ID; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_MEMBERS_BY_USER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_MEMBER_BY_USER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_MEMBER_GROUPS; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_RICH_GROUPS_ASSIGNED_TO_RESOURCE_WITH_ATTRIBUTES_BY_NAMES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_USER_BY_EXT_SOURCE_NAME_AND_EXT_LOGIN; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_USER_BY_ID; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_USER_EXT_SOURCES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_VO_BY_ID; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_GET_VO_BY_SHORT_NAME; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_IS_GROUP_MEMBER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.METHOD_SET_ATTRIBUTE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ATTRIBUTE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ATTRIBUTE_DEFINITION; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ATTRIBUTE_NAME; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ATTRIBUTE_VALUE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ATTR_NAME; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ATTR_NAMES; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_EXT_LOGIN; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_EXT_SOURCE_NAME; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_FACILITY; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_GROUP; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_ID; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_MEMBER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_RESOURCE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_SHORT_NAME; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_USER; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_USER_EXT_SOURCE; +import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.PARAM_VO; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.REGISTRAR_MANAGER; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.RESOURCES_MANAGER; import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.USERS_MANAGER; @@ -55,1354 +98,1371 @@ import static cz.muni.ics.oidc.server.connectors.PerunConnectorRpc.VOS_MANAGER; * @author Peter Jancus jancus@ics.muni.cz */ @Slf4j -public class PerunAdapterRpc extends PerunAdapterWithMappingServices implements PerunAdapterMethods, PerunAdapterMethodsRpc { - - private PerunConnectorRpc connectorRpc; - - private String oidcClientIdAttr; - private String oidcCheckMembershipAttr; - private String orgUrlAttr; - private String affiliationsAttr; - - public void setConnectorRpc(PerunConnectorRpc connectorRpc) { - this.connectorRpc = connectorRpc; - } - - public void setOidcClientIdAttr(String oidcClientIdAttr) { - this.oidcClientIdAttr = oidcClientIdAttr; - } - - public void setOidcCheckMembershipAttr(String oidcCheckMembershipAttr) { - this.oidcCheckMembershipAttr = oidcCheckMembershipAttr; - } - - public void setOrgUrlAttr(String orgUrlAttr) { - this.orgUrlAttr = orgUrlAttr; - } - - public void setAffiliationsAttr(String affiliationsAttr) { - this.affiliationsAttr = affiliationsAttr; - } - - @Override - public PerunUser getPreauthenticatedUserId(String extLogin, String extSourceName) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - Map<String, Object> map = new LinkedHashMap<>(); - map.put("extLogin", extLogin); - map.put("extSourceName", extSourceName); - - JsonNode response = connectorRpc.post(USERS_MANAGER, "getUserByExtSourceNameAndExtLogin", map); - return RpcMapper.mapPerunUser(response); - } - - @Override - public Facility getFacilityByClientId(String clientId) { - if (!this.connectorRpc.isEnabled()) { - return null; - } else if (!StringUtils.hasText(clientId)) { - return null; - } - - AttributeMapping mapping = this.getFacilityAttributesMappingService().getMappingByIdentifier(oidcClientIdAttr); - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("attributeName", mapping.getRpcName()); - map.put("attributeValue", clientId); - JsonNode jsonNode = connectorRpc.post(FACILITIES_MANAGER, "getFacilitiesByAttribute", map); - - return (jsonNode.size() > 0) ? RpcMapper.mapFacility(jsonNode.get(0)) : null; - } - - @Override - public boolean isMembershipCheckEnabledOnFacility(Facility facility) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - - AttributeMapping mapping = this.getFacilityAttributesMappingService().getMappingByIdentifier(oidcCheckMembershipAttr); - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("facility", facility.getId()); - map.put("attributeName", mapping.getRpcName()); - JsonNode res = connectorRpc.post(ATTRIBUTES_MANAGER, "getAttribute", map); - - return res.get("value").asBoolean(false); - } - - @Override - public boolean canUserAccessBasedOnMembership(Facility facility, Long userId, String ignoreAttr) { - if (!this.connectorRpc.isEnabled()) { - return true; - } - - Set<Group> activeGroups = getGroupsWhereUserIsActive(facility.getId(), userId, ignoreAttr); - return !activeGroups.isEmpty(); - } - - @Override - public Map<Vo, List<Group>> getGroupsForRegistration(Facility facility, Long userId, List<String> voShortNames) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - List<Vo> vos = getVosByShortNames(voShortNames); - Map<Long, Vo> vosMap = convertVoListToMap(vos); - List<Member> userMembers = getMembersByUser(userId); - userMembers = new ArrayList<>(new HashSet<>(userMembers)); - - //Filter out vos where member is other than valid or expired. These vos cannot be used for registration - Map<Long, MemberStatus> memberVoStatuses = convertMembersListToStatusesMap(userMembers); - Map<Long, Vo> vosForRegistration = new HashMap<>(); - for (Map.Entry<Long, Vo> entry : vosMap.entrySet()) { - if (memberVoStatuses.containsKey(entry.getKey())) { - MemberStatus status = memberVoStatuses.get(entry.getKey()); - if (VALID.equals(status) || MemberStatus.EXPIRED.equals(status)) { - vosForRegistration.put(entry.getKey(), entry.getValue()); - } - } else { - vosForRegistration.put(entry.getKey(), entry.getValue()); - } - } - - // filter groups only if their VO is in the allowed VOs and if they have registration form - List<Group> allowedGroups = getAllowedGroups(facility); - List<Group> groupsForRegistration = allowedGroups.stream() - .filter(group -> vosForRegistration.containsKey(group.getVoId()) && hasApplicationForm(group)) - .collect(Collectors.toList()); - - // create map for processing - Map<Vo, List<Group>> result = new HashMap<>(); - for (Group group : groupsForRegistration) { - Vo vo = vosMap.get(group.getVoId()); - result.computeIfAbsent(vo, v -> new ArrayList<>()); - result.get(vo).add(group); - } - - return result; - } - - @Override - public boolean groupWhereCanRegisterExists(Facility facility) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - - List<Group> allowedGroups = getAllowedGroups(facility); - - if (!allowedGroups.isEmpty()) { - for (Group group : allowedGroups) { - if (hasApplicationForm(group)) { - return true; - } - } - } - - return false; - } - - @Override - public boolean isUserInGroup(Long userId, Long groupId) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - - Map<String, Object> groupParams = new LinkedHashMap<>(); - groupParams.put("id", groupId); - JsonNode groupResponse = connectorRpc.post(GROUPS_MANAGER, "getGroupById", groupParams); - Group group = RpcMapper.mapGroup(groupResponse); - - Map<String, Object> memberParams = new LinkedHashMap<>(); - memberParams.put("vo", group.getVoId()); - memberParams.put("user", userId); - JsonNode memberResponse = connectorRpc.post(MEMBERS_MANAGER, "getMemberByUser", memberParams); - Member member = RpcMapper.mapMember(memberResponse); - - Map<String, Object> isGroupMemberParams = new LinkedHashMap<>(); - isGroupMemberParams.put("group", groupId); - isGroupMemberParams.put("member", member.getId()); - JsonNode res = connectorRpc.post(GROUPS_MANAGER, "isGroupMember", isGroupMemberParams); - - return res.asBoolean(false); - } - - @Override - public boolean setUserAttribute(Long userId, PerunAttribute attribute) { - if (!this.connectorRpc.isEnabled()) { - return true; - } - - JsonNode attributeJson = attribute.toJson(); - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("user", userId); - map.put("attribute", attributeJson); - - JsonNode response = connectorRpc.post(ATTRIBUTES_MANAGER, "setAttribute", map); - return (response == null || response.isNull() || response instanceof NullNode); - } - - @Override - public List<Affiliation> getUserExtSourcesAffiliations(Long userId) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - List<UserExtSource> userExtSources = getUserExtSources(userId); - List<Affiliation> affiliations = new ArrayList<>(); - - AttributeMapping affMapping = new AttributeMapping("affMapping", affiliationsAttr, "", PerunAttributeValue.ARRAY_TYPE); - AttributeMapping orgUrlMapping = new AttributeMapping("orgUrl", orgUrlAttr, "", STRING_TYPE); - Set<AttributeMapping> attributeMappings = new HashSet<>(Arrays.asList(affMapping, orgUrlMapping)); - - for (UserExtSource ues : userExtSources) { - if ("cz.metacentrum.perun.core.impl.ExtSourceIdp".equals(ues.getExtSource().getType())) { - Map<String, PerunAttributeValue> uesAttrValues = getUserExtSourceAttributeValues(ues.getId(), attributeMappings); - - long asserted = ues.getLastAccess().getTime() / 1000L; - - String orgUrl = uesAttrValues.get(orgUrlMapping.getIdentifier()).valueAsString(); - String affs = uesAttrValues.get(affMapping.getIdentifier()).valueAsString(); - if (affs != null) { - for (String aff : affs.split(";")) { - String source = ( (orgUrl != null) ? orgUrl : ues.getExtSource().getName() ); - Affiliation affiliation = new Affiliation(source, aff, asserted); - log.debug("found {} from IdP {} with orgURL {} asserted at {}", aff, ues.getExtSource().getName(), - orgUrl, asserted); - affiliations.add(affiliation); - } - } - } - } - - return affiliations; - } - - @Override - public List<Affiliation> getGroupAffiliations(Long userId, String groupAffiliationsAttr) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - List<Affiliation> affiliations = new ArrayList<>(); - - List<Member> userMembers = getMembersByUser(userId); - for (Member member : userMembers) { - if (VALID.equals(member.getStatus())) { - List<Group> memberGroups = getMemberGroups(member.getId()); - for (Group group : memberGroups) { - PerunAttributeValue attrValue = this.getGroupAttributeValue(group, groupAffiliationsAttr); - if (attrValue != null && attrValue.valueAsString() != null) { - long linuxTime = System.currentTimeMillis() / 1000L; - for (String value : attrValue.valueAsList()) { - Affiliation affiliation = new Affiliation(null, value, linuxTime); - log.debug("found {} on group {}", value, group.getName()); - affiliations.add(affiliation); - } - } - } - } - } - - return affiliations; - } - - @Override - public List<String> getGroupsAssignedToResourcesWithUniqueNames(Facility facility) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - List<Resource> resources = getAssignedResources(facility); - List<String> result = new ArrayList<>(); - - String voShortName = "urn:perun:group:attribute-def:virt:voShortName"; - - for (Resource res : resources) { - List<Group> groups = getRichGroupsAssignedToResourceWithAttributesByNames(res, Collections.singletonList(voShortName)); - - for (Group group : groups) { - if (group.getAttributeByUrnName(voShortName) != null && - group.getAttributeByUrnName(voShortName).hasNonNull("value")) { - String value = group.getAttributeByUrnName(voShortName).get("value").textValue(); - group.setUniqueGroupName(value + ":" + group.getName()); - result.add(group.getUniqueGroupName()); - } - } - } - - return result; - } - - @Override - public Map<String, PerunAttribute> getEntitylessAttributes(String attributeName) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, Object> attrNameMap = new LinkedHashMap<>(); - attrNameMap.put("attrName", attributeName); - JsonNode entitylessAttributesJson = connectorRpc.post(ATTRIBUTES_MANAGER, "getEntitylessAttributes", attrNameMap); - - Long attributeDefinitionId = RpcMapper.mapAttribute(entitylessAttributesJson.get(0)).getId(); - - Map<String, Object> attributeDefinitionIdMap = new LinkedHashMap<>(); - attributeDefinitionIdMap.put("attributeDefinition", attributeDefinitionId); - JsonNode entitylessKeysJson = connectorRpc.post(ATTRIBUTES_MANAGER, "getEntitylessKeys", attributeDefinitionIdMap); - - Map<String, PerunAttribute> result = new LinkedHashMap<>(); - - for(int i = 0; i < entitylessKeysJson.size(); i++) { - result.put(entitylessKeysJson.get(i).asText(), RpcMapper.mapAttribute(entitylessAttributesJson.get(i))); - } - - if (result.size() == 0) { - return null; - } - - return result; - } - - @Override - public Vo getVoByShortName(String shortName) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - Map<String, Object> params = new LinkedHashMap<>(); - params.put("shortName", shortName); - - JsonNode jsonNode = connectorRpc.post(VOS_MANAGER, "getVoByShortName", params); - return RpcMapper.mapVo(jsonNode); - } - - @Override - public Map<String, PerunAttributeValue> getUserAttributeValues(PerunUser user, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getUserAttributeValues(user.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttributeValue> getUserAttributeValues(Long userId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, PerunAttribute> userAttributes = this.getUserAttributes(userId, attrsToFetch); - return extractValues(userAttributes); - } - - @Override - public PerunAttributeValue getUserAttributeValue(PerunUser user, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getUserAttributeValue(user.getId(), attrToFetch); - } - - @Override - public PerunAttributeValue getUserAttributeValue(Long userId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getUserAttribute(userId, attrToFetch).toPerunAttributeValue(); - } - - @Override - public Map<String, PerunAttributeValue> getFacilityAttributeValues(Facility facility, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getFacilityAttributeValues(facility.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttributeValue> getFacilityAttributeValues(Long facilityId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, PerunAttribute> facilityAttributes = this.getFacilityAttributes(facilityId, attrsToFetch); - return extractValues(facilityAttributes); - } - - @Override - public PerunAttributeValue getFacilityAttributeValue(Facility facility, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getFacilityAttributeValue(facility.getId(), attrToFetch); - } - - @Override - public PerunAttributeValue getFacilityAttributeValue(Long facilityId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getFacilityAttribute(facilityId, attrToFetch).toPerunAttributeValue(); - } - - @Override - public Map<String, PerunAttributeValue> getVoAttributeValues(Vo vo, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getVoAttributeValues(vo.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttributeValue> getVoAttributeValues(Long voId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, PerunAttribute> voAttributes = this.getVoAttributes(voId, attrsToFetch); - return extractValues(voAttributes); - } - - @Override - public PerunAttributeValue getVoAttributeValue(Vo vo, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getVoAttributeValue(vo.getId(), attrToFetch); - } - - @Override - public PerunAttributeValue getVoAttributeValue(Long voId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getVoAttribute(voId, attrToFetch).toPerunAttributeValue(); - } - - @Override - public Map<String, PerunAttributeValue> getGroupAttributeValues(Group group, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getGroupAttributeValues(group.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttributeValue> getGroupAttributeValues(Long groupId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, PerunAttribute> groupAttributes = this.getGroupAttributes(groupId, attrsToFetch); - return extractValues(groupAttributes); - } - - @Override - public PerunAttributeValue getGroupAttributeValue(Group group, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getGroupAttributeValue(group.getId(), attrToFetch); - } - - @Override - public PerunAttributeValue getGroupAttributeValue(Long groupId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getGroupAttribute(groupId, attrToFetch).toPerunAttributeValue(); - } - - @Override - public Map<String, PerunAttributeValue> getResourceAttributeValues(Resource resource, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getResourceAttributeValues(resource.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttributeValue> getResourceAttributeValues(Long resourceId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, PerunAttribute> resourceAttributes = this.getResourceAttributes(resourceId, attrsToFetch); - return extractValues(resourceAttributes); - } - - @Override - public PerunAttributeValue getResourceAttributeValue(Resource resource, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getResourceAttributeValue(resource.getId(), attrToFetch); - } - - @Override - public PerunAttributeValue getResourceAttributeValue(Long resourceId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getResourceAttribute(resourceId, attrToFetch).toPerunAttributeValue(); - } - - @Override - public Map<String, PerunAttribute> getFacilityAttributes(Facility facility, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getFacilityAttributes(facility.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttribute> getFacilityAttributes(Long facilityId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return getAttributes(PerunEntityType.FACILITY, facilityId, attrsToFetch); - } - - @Override - public PerunAttribute getFacilityAttribute(Facility facility, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getFacilityAttribute(facility.getId(), attrToFetch); - } - - @Override - public PerunAttribute getFacilityAttribute(Long facilityId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return getAttribute(PerunEntityType.FACILITY, facilityId, attrToFetch); - } - - @Override - public Map<String, PerunAttribute> getGroupAttributes(Group group, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getGroupAttributes(group.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttribute> getGroupAttributes(Long groupId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return getAttributes(PerunEntityType.GROUP, groupId, attrsToFetch); - } - - @Override - public PerunAttribute getGroupAttribute(Group group, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getGroupAttribute(group.getId(), attrToFetch); - } - - @Override - public PerunAttribute getGroupAttribute(Long groupId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return getAttribute(PerunEntityType.GROUP, groupId, attrToFetch); - } - - @Override - public Map<String, PerunAttribute> getUserAttributes(PerunUser user, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getUserAttributes(user.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttribute> getUserAttributes(Long userId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return getAttributes(PerunEntityType.USER, userId, attrsToFetch); - } - - @Override - public PerunAttribute getUserAttribute(PerunUser user, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getUserAttribute(user.getId(), attrToFetch); - } - - @Override - public PerunAttribute getUserAttribute(Long userId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return getAttribute(PerunEntityType.USER, userId, attrToFetch); - } - - @Override - public Map<String, PerunAttribute> getVoAttributes(Vo vo, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getVoAttributes(vo.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttribute> getVoAttributes(Long voId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return getAttributes(PerunEntityType.VO, voId, attrsToFetch); - } - - @Override - public PerunAttribute getVoAttribute(Vo vo, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getVoAttribute(vo.getId(), attrToFetch); - } - - @Override - public PerunAttribute getVoAttribute(Long voId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return getAttribute(PerunEntityType.VO, voId, attrToFetch); - } - - @Override - public Map<String, PerunAttribute> getResourceAttributes(Resource resource, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return this.getResourceAttributes(resource.getId(), attrsToFetch); - } - - @Override - public Map<String, PerunAttribute> getResourceAttributes(Long resourceId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - return getAttributes(PerunEntityType.RESOURCE, resourceId, attrsToFetch); - } - - @Override - public PerunAttribute getResourceAttribute(Resource resource, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return this.getResourceAttribute(resource.getId(), attrToFetch); - } - - @Override - public PerunAttribute getResourceAttribute(Long resourceId, String attrToFetch) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - return getAttribute(PerunEntityType.RESOURCE, resourceId, attrToFetch); - } - - @Override - public Set<String> getCapabilities(Facility facility, Set<String> groupNames, - String facilityCapabilitiesAttrName, - String resourceCapabilitiesAttrName) - { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - if (facility == null) { - return new HashSet<>(); - } - - Set<String> capabilities = new HashSet<>(); - Set<String> resourceGroupNames = new HashSet<>(); - - if (null != resourceCapabilitiesAttrName) { - List<Resource> resources = this.getAssignedRichResources(facility); - for (Resource resource : resources) { - PerunAttributeValue attrValue = this.getResourceAttributeValue(resource.getId(), resourceCapabilitiesAttrName); - - List<String> resourceCapabilities = attrValue.valueAsList(); - if (resourceCapabilities == null || resourceCapabilities.size() == 0) { - continue; - } - List<Group> groups = this.getAssignedGroups(resource.getId()); - for (Group group : groups) { - resourceGroupNames.add(group.getName()); - String groupName = group.getName(); - if (resource.getVo() != null) { - groupName = resource.getVo().getShortName() + ':' + groupName; - } - group.setUniqueGroupName(groupName); - - if (groupNames.contains(groupName)) { - log.trace("Group [{}] found in users groups, add capabilities [{}]", groupName, resourceCapabilities); - capabilities.addAll(resourceCapabilities); - } else { - log.trace("Group [{}] not found in users groups, continue to the next one", groupName); - } - } - } - } - - if (null != facilityCapabilitiesAttrName && !Collections.disjoint(groupNames, resourceGroupNames)) { - Set<String> facilityCapabilities = this.getFacilityCapabilities(facility, facilityCapabilitiesAttrName); - capabilities.addAll(facilityCapabilities); - } - - return capabilities; - } - - @Override - public Set<String> getCapabilities(Facility facility, Map<Long, String> idToGnameMap, - String facilityCapabilitiesAttrName, String resourceCapabilitiesAttrName) - { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - if (facility == null) { - return new HashSet<>(); - } - - return this.getCapabilities(facility, new HashSet<>(idToGnameMap.values()), facilityCapabilitiesAttrName, - resourceCapabilitiesAttrName); - } - - @Override - public Set<Group> getGroupsWhereUserIsActiveWithUniqueNames(Long facilityId, - Long userId, - String resourceGroupEntitlementDisabledAttribute) - { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Set<Group> groups = this.getGroupsWhereUserIsActive(facilityId, userId, resourceGroupEntitlementDisabledAttribute); - - Map<Long, String> voIdToShortNameMap = new HashMap<>(); - groups.forEach(g -> { - if (!voIdToShortNameMap.containsKey(g.getVoId())) { - Vo vo = this.getVoById(g.getVoId()); - if (vo != null) { - voIdToShortNameMap.put(vo.getId(), vo.getShortName()); - } - } - g.setUniqueGroupName(voIdToShortNameMap.get(g.getVoId()) + ':' + g.getName()); - }); - - return groups; - } - - @Override - public Set<Long> getUserGroupsIds(Long userId, Long voId) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Member member = getMemberByUser(userId, voId); - Set<Long> groups = new HashSet<>(); - if (member != null) { - groups = getMemberGroups(member.getId()).stream().map(Group::getId).collect(Collectors.toSet()); - } - - return groups; - } - - @Override - public boolean isValidMemberInGroupsAndVos(Long userId, Set<Long> mandatoryVos, Set<Long> mandatoryGroups, - Set<Long> envVos, Set<Long> envGroups) - { - if (!this.connectorRpc.isEnabled()) { - return false; - } - List<Member> members = getMembersByUser(userId); - Set<Long> foundVoIds = new HashSet<>(); - Set<Long> foundGroupIds = new HashSet<>(); - boolean skipGroups = mandatoryGroups.isEmpty() && envGroups.isEmpty(); - for (Member m: members) { - if (MemberStatus.VALID.equals(m.getStatus())) { - foundVoIds.add(m.getVoId()); - } - if (!skipGroups) { - foundGroupIds.addAll(getMemberGroups(m.getId()).stream().map(Model::getId).collect(Collectors.toList())); - } - } - - return PerunAdapter.decideAccess(foundVoIds, foundGroupIds, mandatoryVos, mandatoryGroups, envVos, envGroups); - } - - @Override - public boolean isValidMemberInGroupsAndVos(Long userId, Set<Long> vos, Set<Long> groups) - { - if (!this.connectorRpc.isEnabled()) { - return false; - } - List<Member> members = getMembersByUser(userId); - Set<Long> foundVoIds = new HashSet<>(); - Set<Long> foundGroupIds = new HashSet<>(); - boolean skipGroups = groups.isEmpty(); - - for (Member m: members) { - if (MemberStatus.VALID.equals(m.getStatus())) { - foundVoIds.add(m.getVoId()); - } - if (!skipGroups) { - foundGroupIds.addAll(getMemberGroups(m.getId()).stream().map(Model::getId).collect(Collectors.toList())); - } - } - - return PerunAdapter.decideAccess(foundVoIds, foundGroupIds, vos, groups); - } - - @Override - public boolean isUserInVo(Long userId, String voShortName) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - if (userId == null) { - throw new IllegalArgumentException("No userId"); - } else if (!StringUtils.hasText(voShortName)) { - throw new IllegalArgumentException("No voShortName"); - } - - Vo vo = getVoByShortName(voShortName); - if (vo == null || vo.getId() == null) { - log.debug("isUserInVo - No VO found, returning false"); - return false; - } - try { - Member member = getMemberByUser(userId, vo.getId()); - if (member == null) { - log.debug("isUserInVo - No member found, returning false"); - return false; - } - return VALID.equals(member.getStatus()); - } catch (Exception e) { - log.debug("isUserInVo - caught exception, probably user is not a member"); - log.trace("{}", e.getMessage(), e); - return false; - } - } - - @Override - public boolean hasApplicationForm(String voShortName) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - - Vo vo = getVoByShortName(voShortName); - if (vo == null || vo.getId() == null) { - return false; - } - return hasApplicationForm(vo.getId()); - } - - @Override - public PerunUser getPerunUser(Long userId) { - if (!this.connectorRpc.isEnabled()) { - return null; - } else if (userId == null) { - throw new IllegalArgumentException("No userId"); - } - Map<String, Object> map = new LinkedHashMap<>(); - map.put("id", userId); - - JsonNode response = connectorRpc.post(USERS_MANAGER, "getUserById", map); - return RpcMapper.mapPerunUser(response); - } - - @Override - public Set<Long> getUserVoIds(Long userId) { - if (!this.connectorRpc.isEnabled()) { - return Collections.emptySet(); - } else if (userId == null) { - throw new IllegalArgumentException("No userId"); - } - List<Member> members = getMembersByUser(userId); - Set<Long> voIds = new HashSet<>(); - for (Member member: members) { - if (VALID == member.getStatus()) { - voIds.add(member.getVoId()); - } - } - return voIds; - } - - private Member getMemberByUser(Long userId, Long voId) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - Map<String, Object> params = new LinkedHashMap<>(); - params.put("user", userId); - params.put("vo", voId); - JsonNode jsonNode = connectorRpc.post(MEMBERS_MANAGER, "getMemberByUser", params); - - return RpcMapper.mapMember(jsonNode); - } - - private Set<Group> getGroupsWhereUserIsActive(Long facilityId, Long userId, String ignoreGroupsAttribute) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Set<Group> groups = new HashSet<>(); - if (StringUtils.hasText(ignoreGroupsAttribute)) { - Set<Resource> resources = getResourcesAssignedToFacility(facilityId, userId, ignoreGroupsAttribute); - for (Resource resource : resources) { - groups.addAll( - getGroupsWhereUserIsActiveByResource(resource.getId(), userId) - ); - } - } else { - groups.addAll(getGroupsWhereUserIsActiveByFacility(facilityId, userId)); - } - return groups; - } - - private Set<Group> getGroupsWhereUserIsActiveByFacility(Long facilityId, Long userId) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("facility", facilityId); - map.put("user", userId); - JsonNode jsonNode = connectorRpc.post(USERS_MANAGER, "getGroupsWhereUserIsActive", map); - - return new HashSet<>(RpcMapper.mapGroups(jsonNode)); - } - - private Set<Resource> getResourcesAssignedToFacility(Long facilityId, Long userId, String ignoreAttribute) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - Set<Resource> resources = getAllowedResources(facilityId, userId); - Set<Resource> result = new HashSet<>(); - for (Resource resource : resources) { - PerunAttributeValue attrValue = getResourceAttributeValue(resource.getId(), ignoreAttribute); - if (attrValue == null || attrValue.isNullValue() || !attrValue.valueAsBoolean()) { - result.add(resource); - } else { - log.debug( - "getResourcesAssignedToFacility - non null attr value for '{}', skipping resource '{}'", - ignoreAttribute, resource - ); - } - } - return result; - } - - private Set<Group> getGroupsWhereUserIsActiveByResource(Long resourceId, Long userId) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("user", userId); - map.put("resource", resourceId); - - JsonNode res = connectorRpc.post(USERS_MANAGER, "getGroupsWhereUserIsActive", map); - return new HashSet<>(RpcMapper.mapGroups(res)); - } - - private Set<Resource> getAllowedResources(Long facilityId, Long userId) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("user", userId); - map.put("facility", facilityId); - - JsonNode res = connectorRpc.post(USERS_MANAGER, "getAllowedResources", map); - return new HashSet<>(RpcMapper.mapResources(res)); - } - - private Vo getVoById(Long voId) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("id", voId); - - JsonNode res = connectorRpc.post(VOS_MANAGER, "getVoById", map); - return RpcMapper.mapVo(res); - } - - private List<Group> getAssignedGroups(Long resourceId) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> params = new LinkedHashMap<>(); - params.put("resource", resourceId); - - JsonNode response = connectorRpc.post(RESOURCES_MANAGER, "getAssignedGroups", params); - - return RpcMapper.mapGroups(response); - } - - private Map<String, PerunAttributeValue> extractValues(Map<String, PerunAttribute> attributeMap) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, PerunAttributeValue> resultMap = new LinkedHashMap<>(); - for (Map.Entry<String, PerunAttribute> attrPair: attributeMap.entrySet()) { - String attrName = attrPair.getKey(); - PerunAttribute attr = attrPair.getValue(); - if (attr != null) { - resultMap.put(attrName, attr.toPerunAttributeValue()); - } - } - - return resultMap; - } - - private Map<String, PerunAttribute> getAttributes(PerunEntityType entity, Long entityId, Collection<String> attrsToFetch) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } else if (attrsToFetch == null || attrsToFetch.isEmpty()) { - return new HashMap<>(); - } - - Set<AttributeMapping> mappings; - switch (entity) { - case USER: mappings = this.getUserAttributesMappingService() - .getMappingsByIdentifiers(attrsToFetch); - break; - case FACILITY: mappings = this.getFacilityAttributesMappingService() - .getMappingsByIdentifiers(attrsToFetch); - break; - case VO: mappings = this.getVoAttributesMappingService() - .getMappingsByIdentifiers(attrsToFetch); - break; - case GROUP: mappings = this.getGroupAttributesMappingService() - .getMappingsByIdentifiers(attrsToFetch); - break; - case RESOURCE: mappings = this.getResourceAttributesMappingService() - .getMappingsByIdentifiers(attrsToFetch); - break; - default: mappings = new HashSet<>(); - break; - } - - List<String> rpcNames = mappings.stream().map(AttributeMapping::getRpcName).collect(Collectors.toList()); - - Map<String, Object> map = new LinkedHashMap<>(); - map.put(entity.toString().toLowerCase(), entityId); - map.put("attrNames", rpcNames); - - JsonNode res = connectorRpc.post(ATTRIBUTES_MANAGER, "getAttributes", map); - return RpcMapper.mapAttributes(res, mappings); - } - - private List<Group> getMemberGroups(Long memberId) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("member", memberId); - - JsonNode response = connectorRpc.post(GROUPS_MANAGER, "getMemberGroups", map); - return RpcMapper.mapGroups(response); - } - - private List<Member> getMembersByUser(Long userId) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> params = new LinkedHashMap<>(); - params.put("user", userId); - JsonNode jsonNode = connectorRpc.post(MEMBERS_MANAGER, "getMembersByUser", params); - - return RpcMapper.mapMembers(jsonNode); - } - - private List<Vo> getVosByShortNames(List<String> voShortNames) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - List<Vo> vos = new ArrayList<>(); - for (String shortName : voShortNames) { - Vo vo = getVoByShortName(shortName); - vos.add(vo); - } - - return vos; - } - - private Map<Long, MemberStatus> convertMembersListToStatusesMap(List<Member> userMembers) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<Long, MemberStatus> res = new HashMap<>(); - for (Member m : userMembers) { - res.put(m.getVoId(), m.getStatus()); - } - - return res; - } - - private Map<String, PerunAttributeValue> getUserExtSourceAttributeValues(Long uesId, Set<AttributeMapping> attrMappings) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("userExtSource", uesId); - map.put("attrNames", attrMappings.stream().map(AttributeMapping::getRpcName).collect(Collectors.toList())); - - JsonNode response = connectorRpc.post(ATTRIBUTES_MANAGER, "getAttributes", map); - Map<String, PerunAttribute> attributeMap = RpcMapper.mapAttributes(response, attrMappings); - return extractValues(attributeMap); - } - - private List<Group> getAllowedGroups(Facility facility) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("facility", facility.getId()); - JsonNode jsonNode = connectorRpc.post(FACILITIES_MANAGER, "getAllowedGroups", map); - List<Group> result = new ArrayList<>(); - for (int i = 0; i < jsonNode.size(); i++) { - JsonNode groupNode = jsonNode.get(i); - result.add(RpcMapper.mapGroup(groupNode)); - } - - return result; - } - - private boolean hasApplicationForm(Group group) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("group", group.getId()); - try { - if (group.getName().equalsIgnoreCase("members")) { - log.debug("hasApplicationForm({}) continues to call regForm for VO {}", group, group.getVoId()); - return hasApplicationForm(group.getVoId()); - } else { - connectorRpc.post(REGISTRAR_MANAGER, "getApplicationForm", map); - } - } catch (Exception e) { - // when group does not have form exception is thrown. Every error thus is supposed as group without form - // this method will be used after calling other RPC methods - if RPC is not available other methods should discover it first - return false; - } - - return true; - } - - private boolean hasApplicationForm(Long voId) { - if (!this.connectorRpc.isEnabled()) { - return false; - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("vo", voId); - try { - connectorRpc.post(REGISTRAR_MANAGER, "getApplicationForm", map); - } catch (Exception e) { - // when vo does not have form exception is thrown. Every error thus is supposed as vo without form - // this method will be used after calling other RPC methods - if RPC is not available other methods should discover it first - return false; - } - - return true; - } - - private Map<Long, Vo> convertVoListToMap(List<Vo> vos) { - if (!this.connectorRpc.isEnabled()) { - return new HashMap<>(); - } - - Map<Long, Vo> map = new HashMap<>(); - for (Vo vo : vos) { - map.put(vo.getId(), vo); - } - - return map; - } - - private List<Resource> getAssignedResources(Facility facility) { - return getAssignedResources(facility.getId()); - } - - private List<Resource> getAssignedResources(Long facilityId) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("facility", facilityId); - - JsonNode res = connectorRpc.post(FACILITIES_MANAGER, "getAssignedResources", map); - return RpcMapper.mapResources(res); - } - - private List<Resource> getAssignedRichResources(Facility facility) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("facility", facility.getId()); - - JsonNode res = connectorRpc.post(FACILITIES_MANAGER, "getAssignedRichResources", map); - return RpcMapper.mapResources(res); - } - - private List<Group> getRichGroupsAssignedToResourceWithAttributesByNames(Resource resource, List<String> attrNames) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - Set<AttributeMapping> mappings = this.getGroupAttributesMappingService() - .getMappingsByIdentifiers(attrNames); - List<String> rpcNames = mappings.stream().map(AttributeMapping::getRpcName).collect(Collectors.toList()); - map.put("resource", resource.getId()); - map.put("attrNames", rpcNames); - - JsonNode res = connectorRpc.post(GROUPS_MANAGER, "getRichGroupsAssignedToResourceWithAttributesByNames", map); - List<Group> groups = new ArrayList<>(); - - for (int i = 0; i < res.size(); i++) { - JsonNode jsonNode = res.get(i); - Group group = RpcMapper.mapGroup(jsonNode); - - JsonNode groupAttrs = jsonNode.get("attributes"); - Map<String, JsonNode> attrsMap = new HashMap<>(); - - for (int j = 0; j < groupAttrs.size(); j++) { - JsonNode attr = groupAttrs.get(j); - - String namespace = attr.get("namespace").textValue(); - String friendlyName = attr.get("friendlyName").textValue(); - - attrsMap.put(namespace + ":" + friendlyName, attr); - } - - group.setAttributes(attrsMap); - groups.add(group); - } - - return groups; - } - - private PerunAttribute getAttribute(PerunEntityType entity, Long entityId, String attributeName) { - if (!this.connectorRpc.isEnabled()) { - return null; - } - - AttributeMapping mapping; - switch (entity) { - case USER: mapping = this.getUserAttributesMappingService() - .getMappingByIdentifier(attributeName); - break; - case FACILITY: mapping = this.getFacilityAttributesMappingService() - .getMappingByIdentifier(attributeName); - break; - case VO: mapping = this.getVoAttributesMappingService() - .getMappingByIdentifier(attributeName); - break; - case GROUP: mapping = this.getGroupAttributesMappingService() - .getMappingByIdentifier(attributeName); - break; - case RESOURCE: mapping = this.getResourceAttributesMappingService() - .getMappingByIdentifier(attributeName); - break; - default: - throw new IllegalArgumentException("Unrecognized entity"); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put(entity.toString().toLowerCase(), entityId); - map.put("attributeName", mapping.getRpcName()); - - JsonNode res = connectorRpc.post(ATTRIBUTES_MANAGER, "getAttribute", map); - return RpcMapper.mapAttribute(res); - } - - private List<UserExtSource> getUserExtSources(Long userId) { - if (!this.connectorRpc.isEnabled()) { - return new ArrayList<>(); - } - - Map<String, Object> map = new LinkedHashMap<>(); - map.put("user", userId); - - JsonNode response = connectorRpc.post(USERS_MANAGER, "getUserExtSources", map); - return RpcMapper.mapUserExtSources(response); - } - - private Set<String> getFacilityCapabilities(Facility facility, String capabilitiesAttrName) { - if (!this.connectorRpc.isEnabled()) { - return new HashSet<>(); - } - - Set<String> capabilities = new HashSet<>(); - if (facility != null) { - PerunAttributeValue attr = getFacilityAttributeValue(facility, capabilitiesAttrName); - if (attr != null && attr.valueAsList() != null) { - capabilities = new HashSet<>(attr.valueAsList()); - } - } - - return capabilities; - } +public class PerunAdapterRpc + extends PerunAdapterWithMappingServices + implements PerunAdapterMethods, PerunAdapterMethodsRpc +{ + + // FIELD NAMES + + protected static final String FIELD_ATTRIBUTES = "attributes"; + protected static final String FIELD_NAMESPACE = "namespace"; + protected static final String FIELD_FRIENDLY_NAME = "friendlyName"; + protected static final String FIELD_VALUE = "value"; + + // OTHERS + + protected static final String ORG_URL = "orgUrl"; + protected static final String AFF_MAPPING = "affMapping"; + + // VARIABLES + + private PerunConnectorRpc connectorRpc; + private String oidcClientIdAttr; + private String oidcCheckMembershipAttr; + private String orgUrlAttr; + private String affiliationsAttr; + + public void setConnectorRpc(PerunConnectorRpc connectorRpc) { + this.connectorRpc = connectorRpc; + } + + public void setOidcClientIdAttr(String oidcClientIdAttr) { + this.oidcClientIdAttr = oidcClientIdAttr; + } + + public void setOidcCheckMembershipAttr(String oidcCheckMembershipAttr) { + this.oidcCheckMembershipAttr = oidcCheckMembershipAttr; + } + + public void setOrgUrlAttr(String orgUrlAttr) { + this.orgUrlAttr = orgUrlAttr; + } + + public void setAffiliationsAttr(String affiliationsAttr) { + this.affiliationsAttr = affiliationsAttr; + } + + @Override + public PerunUser getPreauthenticatedUserId(String extLogin, String extSourceName) { + if (!connectorRpc.isEnabled()) { + return null; + } + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_EXT_LOGIN, extLogin); + map.put(PARAM_EXT_SOURCE_NAME, extSourceName); + + JsonNode response = connectorRpc.post(USERS_MANAGER, METHOD_GET_USER_BY_EXT_SOURCE_NAME_AND_EXT_LOGIN, map); + return RpcMapper.mapPerunUser(response); + } + + @Override + public Facility getFacilityByClientId(String clientId) { + if (!connectorRpc.isEnabled()) { + return null; + } else if (!StringUtils.hasText(clientId)) { + return null; + } + + AttributeMapping mapping = getFacilityAttributesMappingService().getMappingByIdentifier(oidcClientIdAttr); + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_ATTRIBUTE_NAME, mapping.getRpcName()); + map.put(PARAM_ATTRIBUTE_VALUE, clientId); + JsonNode jsonNode = connectorRpc.post(FACILITIES_MANAGER, METHOD_GET_FACILITIES_BY_ATTRIBUTE, map); + + return (jsonNode.size() > 0) ? RpcMapper.mapFacility(jsonNode.get(0)) : null; + } + + @Override + public boolean isMembershipCheckEnabledOnFacility(Facility facility) { + if (!connectorRpc.isEnabled()) { + return false; + } + + AttributeMapping mapping = getFacilityAttributesMappingService().getMappingByIdentifier(oidcCheckMembershipAttr); + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_FACILITY, facility.getId()); + map.put(PARAM_ATTRIBUTE_NAME, mapping.getRpcName()); + JsonNode res = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_GET_ATTRIBUTE, map); + + return res.get(FIELD_VALUE).asBoolean(false); + } + + @Override + public boolean canUserAccessBasedOnMembership(Facility facility, Long userId, String ignoreAttr) { + if (!connectorRpc.isEnabled()) { + return true; + } + + Set<Group> activeGroups = getGroupsWhereUserIsActive(facility.getId(), userId, ignoreAttr); + return !activeGroups.isEmpty(); + } + + @Override + public Map<Vo, List<Group>> getGroupsForRegistration(Facility facility, Long userId, List<String> voShortNames) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + List<Vo> vos = getVosByShortNames(voShortNames); + Map<Long, Vo> vosMap = convertVoListToMap(vos); + List<Member> userMembers = getMembersByUser(userId); + userMembers = new ArrayList<>(new HashSet<>(userMembers)); + + //Filter out vos where member is other than valid or expired. These vos cannot be used for registration + Map<Long, MemberStatus> memberVoStatuses = convertMembersListToStatusesMap(userMembers); + Map<Long, Vo> vosForRegistration = new HashMap<>(); + for (Map.Entry<Long, Vo> entry : vosMap.entrySet()) { + if (memberVoStatuses.containsKey(entry.getKey())) { + MemberStatus status = memberVoStatuses.get(entry.getKey()); + if (VALID.equals(status) || MemberStatus.EXPIRED.equals(status)) { + vosForRegistration.put(entry.getKey(), entry.getValue()); + } + } else { + vosForRegistration.put(entry.getKey(), entry.getValue()); + } + } + + // filter groups only if their VO is in the allowed VOs and if they have registration form + List<Group> allowedGroups = getAllowedGroups(facility); + List<Group> groupsForRegistration = allowedGroups.stream() + .filter(group -> vosForRegistration.containsKey(group.getVoId()) && hasApplicationForm(group)) + .collect(Collectors.toList()); + + // create map for processing + Map<Vo, List<Group>> result = new HashMap<>(); + for (Group group : groupsForRegistration) { + Vo vo = vosMap.get(group.getVoId()); + result.computeIfAbsent(vo, v -> new ArrayList<>()); + result.get(vo).add(group); + } + + return result; + } + + @Override + public boolean groupWhereCanRegisterExists(Facility facility) { + if (!connectorRpc.isEnabled()) { + return false; + } + + List<Group> allowedGroups = getAllowedGroups(facility); + + if (!allowedGroups.isEmpty()) { + for (Group group : allowedGroups) { + if (hasApplicationForm(group)) { + return true; + } + } + } + return false; + } + + @Override + public boolean isUserInGroup(Long userId, Long groupId) { + if (!connectorRpc.isEnabled()) { + return false; + } + + Map<String, Object> groupParams = new LinkedHashMap<>(); + groupParams.put(PARAM_ID, groupId); + JsonNode groupResponse = connectorRpc.post(GROUPS_MANAGER, METHOD_GET_GROUP_BY_ID, groupParams); + Group group = RpcMapper.mapGroup(groupResponse); + + Map<String, Object> memberParams = new LinkedHashMap<>(); + memberParams.put(PARAM_VO, group.getVoId()); + memberParams.put(PARAM_USER, userId); + JsonNode memberResponse = connectorRpc.post(MEMBERS_MANAGER, METHOD_GET_MEMBER_BY_USER, memberParams); + Member member = RpcMapper.mapMember(memberResponse); + + Map<String, Object> isGroupMemberParams = new LinkedHashMap<>(); + isGroupMemberParams.put(PARAM_GROUP, groupId); + isGroupMemberParams.put(PARAM_MEMBER, member.getId()); + JsonNode res = connectorRpc.post(GROUPS_MANAGER, METHOD_IS_GROUP_MEMBER, isGroupMemberParams); + + return res.asBoolean(false); + } + + @Override + public boolean setUserAttribute(Long userId, PerunAttribute attribute) { + if (!connectorRpc.isEnabled()) { + return true; + } + + JsonNode attributeJson = attribute.toJson(); + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_USER, userId); + map.put(PARAM_ATTRIBUTE, attributeJson); + + JsonNode response = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_SET_ATTRIBUTE, map); + return (response == null || response.isNull() || response instanceof NullNode); + } + + @Override + public List<Affiliation> getUserExtSourcesAffiliations(Long userId) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + List<UserExtSource> userExtSources = getUserExtSources(userId); + List<Affiliation> affiliations = new ArrayList<>(); + + AttributeMapping affMapping = new AttributeMapping(AFF_MAPPING, affiliationsAttr, "", ARRAY_TYPE); + AttributeMapping orgUrlMapping = new AttributeMapping(ORG_URL, orgUrlAttr, "", STRING_TYPE); + Set<AttributeMapping> attributeMappings = new HashSet<>(Arrays.asList(affMapping, orgUrlMapping)); + + for (UserExtSource ues : userExtSources) { + if (EXT_SOURCE_IDP.equals(ues.getExtSource().getType())) { + Map<String, PerunAttributeValue> uesAttrValues = getUserExtSourceAttributeValues(ues.getId(), attributeMappings); + + long asserted = ues.getLastAccess().getTime() / 1000L; + + String orgUrl = uesAttrValues.get(orgUrlMapping.getIdentifier()).valueAsString(); + String affs = uesAttrValues.get(affMapping.getIdentifier()).valueAsString(); + if (affs != null) { + for (String aff : affs.split(";")) { + String source = ((orgUrl != null) ? orgUrl : ues.getExtSource().getName()); + Affiliation affiliation = new Affiliation(source, aff, asserted); + log.debug("found {} from IdP {} with orgURL {} asserted at {}", aff, ues.getExtSource().getName(), + orgUrl, asserted); + affiliations.add(affiliation); + } + } + } + } + + return affiliations; + } + + @Override + public List<Affiliation> getGroupAffiliations(Long userId, String groupAffiliationsAttr) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + List<Affiliation> affiliations = new ArrayList<>(); + + List<Member> userMembers = getMembersByUser(userId); + for (Member member : userMembers) { + if (VALID.equals(member.getStatus())) { + List<Group> memberGroups = getMemberGroups(member.getId()); + for (Group group : memberGroups) { + PerunAttributeValue attrValue = getGroupAttributeValue(group, groupAffiliationsAttr); + if (attrValue != null && attrValue.valueAsString() != null) { + long linuxTime = System.currentTimeMillis() / 1000L; + for (String value : attrValue.valueAsList()) { + Affiliation affiliation = new Affiliation(null, value, linuxTime); + log.debug("found {} on group {}", value, group.getName()); + affiliations.add(affiliation); + } + } + } + } + } + + return affiliations; + } + + @Override + public List<String> getGroupsAssignedToResourcesWithUniqueNames(Facility facility) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + List<Resource> resources = getAssignedResources(facility); + List<String> result = new ArrayList<>(); + + String voShortName = "urn:perun:group:attribute-def:virt:voShortName"; + + for (Resource res : resources) { + List<Group> groups = getRichGroupsAssignedToResourceWithAttributesByNames(res, Collections.singletonList(voShortName)); + + for (Group group : groups) { + if (group.getAttributeByUrnName(voShortName) != null && + group.getAttributeByUrnName(voShortName).hasNonNull(FIELD_VALUE)) { + String value = group.getAttributeByUrnName(voShortName).get(FIELD_VALUE).textValue(); + group.setUniqueGroupName(value + ":" + group.getName()); + result.add(group.getUniqueGroupName()); + } + } + } + + return result; + } + + @Override + public Map<String, PerunAttribute> getEntitylessAttributes(String attributeName) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, Object> attrNameMap = new LinkedHashMap<>(); + attrNameMap.put(PARAM_ATTR_NAME, attributeName); + JsonNode entitylessAttributesJson = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_GET_ENTITYLESS_ATTRIBUTES, attrNameMap); + + Long attributeDefinitionId = RpcMapper.mapAttribute(entitylessAttributesJson.get(0)).getId(); + + Map<String, Object> attributeDefinitionIdMap = new LinkedHashMap<>(); + attributeDefinitionIdMap.put(PARAM_ATTRIBUTE_DEFINITION, attributeDefinitionId); + JsonNode entitylessKeysJson = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_GET_ENTITYLESS_KEYS, attributeDefinitionIdMap); + + Map<String, PerunAttribute> result = new LinkedHashMap<>(); + + for (int i = 0; i < entitylessKeysJson.size(); i++) { + result.put(entitylessKeysJson.get(i).asText(), RpcMapper.mapAttribute(entitylessAttributesJson.get(i))); + } + + return result; + } + + @Override + public Vo getVoByShortName(String shortName) { + if (!connectorRpc.isEnabled()) { + return null; + } + + Map<String, Object> params = new LinkedHashMap<>(); + params.put(PARAM_SHORT_NAME, shortName); + + JsonNode jsonNode = connectorRpc.post(VOS_MANAGER, METHOD_GET_VO_BY_SHORT_NAME, params); + return RpcMapper.mapVo(jsonNode); + } + + @Override + public Map<String, PerunAttributeValue> getUserAttributeValues(PerunUser user, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getUserAttributeValues(user.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttributeValue> getUserAttributeValues(Long userId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, PerunAttribute> userAttributes = getUserAttributes(userId, attrsToFetch); + return extractValues(userAttributes); + } + + @Override + public PerunAttributeValue getUserAttributeValue(PerunUser user, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getUserAttributeValue(user.getId(), attrToFetch); + } + + @Override + public PerunAttributeValue getUserAttributeValue(Long userId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getUserAttribute(userId, attrToFetch).toPerunAttributeValue(); + } + + @Override + public Map<String, PerunAttributeValue> getFacilityAttributeValues(Facility facility, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getFacilityAttributeValues(facility.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttributeValue> getFacilityAttributeValues(Long facilityId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, PerunAttribute> facilityAttributes = getFacilityAttributes(facilityId, attrsToFetch); + return extractValues(facilityAttributes); + } + + @Override + public PerunAttributeValue getFacilityAttributeValue(Facility facility, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getFacilityAttributeValue(facility.getId(), attrToFetch); + } + + @Override + public PerunAttributeValue getFacilityAttributeValue(Long facilityId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getFacilityAttribute(facilityId, attrToFetch).toPerunAttributeValue(); + } + + @Override + public Map<String, PerunAttributeValue> getVoAttributeValues(Vo vo, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getVoAttributeValues(vo.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttributeValue> getVoAttributeValues(Long voId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, PerunAttribute> voAttributes = getVoAttributes(voId, attrsToFetch); + return extractValues(voAttributes); + } + + @Override + public PerunAttributeValue getVoAttributeValue(Vo vo, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getVoAttributeValue(vo.getId(), attrToFetch); + } + + @Override + public PerunAttributeValue getVoAttributeValue(Long voId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getVoAttribute(voId, attrToFetch).toPerunAttributeValue(); + } + + @Override + public Map<String, PerunAttributeValue> getGroupAttributeValues(Group group, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getGroupAttributeValues(group.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttributeValue> getGroupAttributeValues(Long groupId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, PerunAttribute> groupAttributes = getGroupAttributes(groupId, attrsToFetch); + return extractValues(groupAttributes); + } + + @Override + public PerunAttributeValue getGroupAttributeValue(Group group, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getGroupAttributeValue(group.getId(), attrToFetch); + } + + @Override + public PerunAttributeValue getGroupAttributeValue(Long groupId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getGroupAttribute(groupId, attrToFetch).toPerunAttributeValue(); + } + + @Override + public Map<String, PerunAttributeValue> getResourceAttributeValues(Resource resource, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getResourceAttributeValues(resource.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttributeValue> getResourceAttributeValues(Long resourceId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, PerunAttribute> resourceAttributes = getResourceAttributes(resourceId, attrsToFetch); + return extractValues(resourceAttributes); + } + + @Override + public PerunAttributeValue getResourceAttributeValue(Resource resource, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getResourceAttributeValue(resource.getId(), attrToFetch); + } + + @Override + public PerunAttributeValue getResourceAttributeValue(Long resourceId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getResourceAttribute(resourceId, attrToFetch).toPerunAttributeValue(); + } + + @Override + public Map<String, PerunAttribute> getFacilityAttributes(Facility facility, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getFacilityAttributes(facility.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttribute> getFacilityAttributes(Long facilityId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getAttributes(PerunEntityType.FACILITY, facilityId, attrsToFetch); + } + + @Override + public PerunAttribute getFacilityAttribute(Facility facility, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getFacilityAttribute(facility.getId(), attrToFetch); + } + + @Override + public PerunAttribute getFacilityAttribute(Long facilityId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getAttribute(PerunEntityType.FACILITY, facilityId, attrToFetch); + } + + @Override + public Map<String, PerunAttribute> getGroupAttributes(Group group, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getGroupAttributes(group.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttribute> getGroupAttributes(Long groupId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getAttributes(PerunEntityType.GROUP, groupId, attrsToFetch); + } + + @Override + public PerunAttribute getGroupAttribute(Group group, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getGroupAttribute(group.getId(), attrToFetch); + } + + @Override + public PerunAttribute getGroupAttribute(Long groupId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getAttribute(PerunEntityType.GROUP, groupId, attrToFetch); + } + + @Override + public Map<String, PerunAttribute> getUserAttributes(PerunUser user, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getUserAttributes(user.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttribute> getUserAttributes(Long userId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getAttributes(PerunEntityType.USER, userId, attrsToFetch); + } + + @Override + public PerunAttribute getUserAttribute(PerunUser user, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getUserAttribute(user.getId(), attrToFetch); + } + + @Override + public PerunAttribute getUserAttribute(Long userId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getAttribute(PerunEntityType.USER, userId, attrToFetch); + } + + @Override + public Map<String, PerunAttribute> getVoAttributes(Vo vo, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getVoAttributes(vo.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttribute> getVoAttributes(Long voId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getAttributes(PerunEntityType.VO, voId, attrsToFetch); + } + + @Override + public PerunAttribute getVoAttribute(Vo vo, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getVoAttribute(vo.getId(), attrToFetch); + } + + @Override + public PerunAttribute getVoAttribute(Long voId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getAttribute(PerunEntityType.VO, voId, attrToFetch); + } + + @Override + public Map<String, PerunAttribute> getResourceAttributes(Resource resource, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getResourceAttributes(resource.getId(), attrsToFetch); + } + + @Override + public Map<String, PerunAttribute> getResourceAttributes(Long resourceId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + return getAttributes(PerunEntityType.RESOURCE, resourceId, attrsToFetch); + } + + @Override + public PerunAttribute getResourceAttribute(Resource resource, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getResourceAttribute(resource.getId(), attrToFetch); + } + + @Override + public PerunAttribute getResourceAttribute(Long resourceId, String attrToFetch) { + if (!connectorRpc.isEnabled()) { + return null; + } + + return getAttribute(PerunEntityType.RESOURCE, resourceId, attrToFetch); + } + + @Override + public Set<String> getCapabilities(Facility facility, Set<String> groupNames, + String facilityCapabilitiesAttrName, + String resourceCapabilitiesAttrName) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + if (facility == null) { + return new HashSet<>(); + } + + Set<String> capabilities = new HashSet<>(); + Set<String> resourceGroupNames = new HashSet<>(); + + if (null != resourceCapabilitiesAttrName) { + List<Resource> resources = getAssignedRichResources(facility); + for (Resource resource : resources) { + PerunAttributeValue attrValue = getResourceAttributeValue(resource.getId(), resourceCapabilitiesAttrName); + + List<String> resourceCapabilities = attrValue.valueAsList(); + if (resourceCapabilities == null || resourceCapabilities.isEmpty()) { + continue; + } + List<Group> groups = getAssignedGroups(resource.getId()); + for (Group group : groups) { + resourceGroupNames.add(group.getName()); + String groupName = group.getName(); + if (resource.getVo() != null) { + groupName = resource.getVo().getShortName() + ':' + groupName; + } + group.setUniqueGroupName(groupName); + + if (groupNames.contains(groupName)) { + log.trace("Group [{}] found in users groups, add capabilities [{}]", groupName, resourceCapabilities); + capabilities.addAll(resourceCapabilities); + } else { + log.trace("Group [{}] not found in users groups, continue to the next one", groupName); + } + } + } + } + + if (null != facilityCapabilitiesAttrName && !Collections.disjoint(groupNames, resourceGroupNames)) { + Set<String> facilityCapabilities = getFacilityCapabilities(facility, facilityCapabilitiesAttrName); + capabilities.addAll(facilityCapabilities); + } + + return capabilities; + } + + @Override + public Set<String> getCapabilities(Facility facility, Map<Long, String> idToGnameMap, + String facilityCapabilitiesAttrName, String resourceCapabilitiesAttrName) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + if (facility == null) { + return new HashSet<>(); + } + + return getCapabilities(facility, new HashSet<>(idToGnameMap.values()), facilityCapabilitiesAttrName, + resourceCapabilitiesAttrName); + } + + @Override + public Set<Group> getGroupsWhereUserIsActiveWithUniqueNames(Long facilityId, + Long userId, + String resourceGroupEntitlementDisabledAttribute) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Set<Group> groups = getGroupsWhereUserIsActive(facilityId, userId, resourceGroupEntitlementDisabledAttribute); + + Map<Long, String> voIdToShortNameMap = new HashMap<>(); + groups.forEach(g -> { + if (!voIdToShortNameMap.containsKey(g.getVoId())) { + Vo vo = getVoById(g.getVoId()); + if (vo != null) { + voIdToShortNameMap.put(vo.getId(), vo.getShortName()); + } + } + g.setUniqueGroupName(voIdToShortNameMap.get(g.getVoId()) + ':' + g.getName()); + }); + + return groups; + } + + @Override + public Set<Long> getUserGroupsIds(Long userId, Long voId) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Member member = getMemberByUser(userId, voId); + Set<Long> groups = new HashSet<>(); + if (member != null) { + groups = getMemberGroups(member.getId()).stream().map(Group::getId).collect(Collectors.toSet()); + } + + return groups; + } + + @Override + public boolean isValidMemberInGroupsAndVos(Long userId, Set<Long> mandatoryVos, Set<Long> mandatoryGroups, + Set<Long> envVos, Set<Long> envGroups) { + if (!connectorRpc.isEnabled()) { + return false; + } + List<Member> members = getMembersByUser(userId); + Set<Long> foundVoIds = new HashSet<>(); + Set<Long> foundGroupIds = new HashSet<>(); + boolean skipGroups = mandatoryGroups.isEmpty() && envGroups.isEmpty(); + for (Member m : members) { + if (MemberStatus.VALID.equals(m.getStatus())) { + foundVoIds.add(m.getVoId()); + } + if (!skipGroups) { + foundGroupIds.addAll(getMemberGroups(m.getId()).stream().map(Model::getId).collect(Collectors.toList())); + } + } + + return PerunAdapter.decideAccess(foundVoIds, foundGroupIds, mandatoryVos, mandatoryGroups, envVos, envGroups); + } + + @Override + public boolean isValidMemberInGroupsAndVos(Long userId, Set<Long> vos, Set<Long> groups) { + if (!connectorRpc.isEnabled()) { + return false; + } + List<Member> members = getMembersByUser(userId); + Set<Long> foundVoIds = new HashSet<>(); + Set<Long> foundGroupIds = new HashSet<>(); + boolean skipGroups = groups.isEmpty(); + + for (Member m : members) { + if (MemberStatus.VALID.equals(m.getStatus())) { + foundVoIds.add(m.getVoId()); + } + if (!skipGroups) { + foundGroupIds.addAll(getMemberGroups(m.getId()).stream().map(Model::getId).collect(Collectors.toList())); + } + } + + return PerunAdapter.decideAccess(foundVoIds, foundGroupIds, vos, groups); + } + + @Override + public boolean isUserInVo(Long userId, String voShortName) { + if (!connectorRpc.isEnabled()) { + return false; + } + if (userId == null) { + throw new IllegalArgumentException("No userId"); + } else if (!StringUtils.hasText(voShortName)) { + throw new IllegalArgumentException("No voShortName"); + } + + Vo vo = getVoByShortName(voShortName); + if (vo == null || vo.getId() == null) { + log.debug("isUserInVo - No VO found, returning false"); + return false; + } + try { + Member member = getMemberByUser(userId, vo.getId()); + if (member == null) { + log.debug("isUserInVo - No member found, returning false"); + return false; + } + return VALID.equals(member.getStatus()); + } catch (Exception e) { + log.debug("isUserInVo - caught exception, probably user is not a member"); + log.trace("{}", e.getMessage(), e); + return false; + } + } + + @Override + public boolean hasApplicationForm(String voShortName) { + if (!connectorRpc.isEnabled()) { + return false; + } + + Vo vo = getVoByShortName(voShortName); + if (vo == null || vo.getId() == null) { + return false; + } + return hasApplicationForm(vo.getId()); + } + + @Override + public PerunUser getPerunUser(Long userId) { + if (!connectorRpc.isEnabled()) { + return null; + } else if (userId == null) { + throw new IllegalArgumentException("No userId"); + } + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_ID, userId); + + JsonNode response = connectorRpc.post(USERS_MANAGER, METHOD_GET_USER_BY_ID, map); + return RpcMapper.mapPerunUser(response); + } + + @Override + public Set<Long> getUserVoIds(Long userId) { + if (!connectorRpc.isEnabled()) { + return Collections.emptySet(); + } else if (userId == null) { + throw new IllegalArgumentException("No userId"); + } + List<Member> members = getMembersByUser(userId); + Set<Long> voIds = new HashSet<>(); + for (Member member : members) { + if (VALID == member.getStatus()) { + voIds.add(member.getVoId()); + } + } + return voIds; + } + + private Member getMemberByUser(Long userId, Long voId) { + if (!connectorRpc.isEnabled()) { + return null; + } + + Map<String, Object> params = new LinkedHashMap<>(); + params.put(PARAM_USER, userId); + params.put(PARAM_VO, voId); + JsonNode jsonNode = connectorRpc.post(MEMBERS_MANAGER, METHOD_GET_MEMBER_BY_USER, params); + + return RpcMapper.mapMember(jsonNode); + } + + private Set<Group> getGroupsWhereUserIsActive(Long facilityId, Long userId, String ignoreGroupsAttribute) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Set<Group> groups = new HashSet<>(); + if (StringUtils.hasText(ignoreGroupsAttribute)) { + Set<Resource> resources = getResourcesAssignedToFacility(facilityId, userId, ignoreGroupsAttribute); + for (Resource resource : resources) { + groups.addAll( + getGroupsWhereUserIsActiveByResource(resource.getId(), userId) + ); + } + } else { + groups.addAll(getGroupsWhereUserIsActiveByFacility(facilityId, userId)); + } + return groups; + } + + private Set<Group> getGroupsWhereUserIsActiveByFacility(Long facilityId, Long userId) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_FACILITY, facilityId); + map.put(PARAM_USER, userId); + JsonNode jsonNode = connectorRpc.post(USERS_MANAGER, METHOD_GET_GROUPS_WHERE_USER_IS_ACTIVE, map); + + return new HashSet<>(RpcMapper.mapGroups(jsonNode)); + } + + private Set<Resource> getResourcesAssignedToFacility(Long facilityId, Long userId, String ignoreAttribute) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + Set<Resource> resources = getAllowedResources(facilityId, userId); + Set<Resource> result = new HashSet<>(); + for (Resource resource : resources) { + PerunAttributeValue attrValue = getResourceAttributeValue(resource.getId(), ignoreAttribute); + if (attrValue == null || attrValue.isNullValue() || !attrValue.valueAsBoolean()) { + result.add(resource); + } else { + log.debug( + "getResourcesAssignedToFacility - non null attr value for '{}', skipping resource '{}'", + ignoreAttribute, resource + ); + } + } + return result; + } + + private Set<Group> getGroupsWhereUserIsActiveByResource(Long resourceId, Long userId) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_USER, userId); + map.put(PARAM_RESOURCE, resourceId); + + JsonNode res = connectorRpc.post(USERS_MANAGER, METHOD_GET_GROUPS_WHERE_USER_IS_ACTIVE, map); + return new HashSet<>(RpcMapper.mapGroups(res)); + } + + private Set<Resource> getAllowedResources(Long facilityId, Long userId) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_USER, userId); + map.put(PARAM_FACILITY, facilityId); + + JsonNode res = connectorRpc.post(USERS_MANAGER, METHOD_GET_ALLOWED_RESOURCES, map); + return new HashSet<>(RpcMapper.mapResources(res)); + } + + private Vo getVoById(Long voId) { + if (!connectorRpc.isEnabled()) { + return null; + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_ID, voId); + + JsonNode res = connectorRpc.post(VOS_MANAGER, METHOD_GET_VO_BY_ID, map); + return RpcMapper.mapVo(res); + } + + private List<Group> getAssignedGroups(Long resourceId) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> params = new LinkedHashMap<>(); + params.put(PARAM_RESOURCE, resourceId); + + JsonNode response = connectorRpc.post(RESOURCES_MANAGER, METHOD_GET_ASSIGNED_GROUPS, params); + + return RpcMapper.mapGroups(response); + } + + private Map<String, PerunAttributeValue> extractValues(Map<String, PerunAttribute> attributeMap) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, PerunAttributeValue> resultMap = new LinkedHashMap<>(); + for (Map.Entry<String, PerunAttribute> attrPair : attributeMap.entrySet()) { + String attrName = attrPair.getKey(); + PerunAttribute attr = attrPair.getValue(); + if (attr != null) { + resultMap.put(attrName, attr.toPerunAttributeValue()); + } + } + + return resultMap; + } + + private Map<String, PerunAttribute> getAttributes(PerunEntityType entity, Long entityId, Collection<String> attrsToFetch) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } else if (attrsToFetch == null || attrsToFetch.isEmpty()) { + return new HashMap<>(); + } + + Set<AttributeMapping> mappings; + switch (entity) { + case USER: + mappings = getUserAttributesMappingService() + .getMappingsByIdentifiers(attrsToFetch); + break; + case FACILITY: + mappings = getFacilityAttributesMappingService() + .getMappingsByIdentifiers(attrsToFetch); + break; + case VO: + mappings = getVoAttributesMappingService() + .getMappingsByIdentifiers(attrsToFetch); + break; + case GROUP: + mappings = getGroupAttributesMappingService() + .getMappingsByIdentifiers(attrsToFetch); + break; + case RESOURCE: + mappings = getResourceAttributesMappingService() + .getMappingsByIdentifiers(attrsToFetch); + break; + default: + mappings = new HashSet<>(); + break; + } + + List<String> rpcNames = mappings.stream().map(AttributeMapping::getRpcName).collect(Collectors.toList()); + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(entity.toString().toLowerCase(), entityId); + map.put(PARAM_ATTR_NAMES, rpcNames); + + JsonNode res = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_GET_ATTRIBUTES, map); + return RpcMapper.mapAttributes(res, mappings); + } + + private List<Group> getMemberGroups(Long memberId) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_MEMBER, memberId); + + JsonNode response = connectorRpc.post(GROUPS_MANAGER, METHOD_GET_MEMBER_GROUPS, map); + return RpcMapper.mapGroups(response); + } + + private List<Member> getMembersByUser(Long userId) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> params = new LinkedHashMap<>(); + params.put(PARAM_USER, userId); + JsonNode jsonNode = connectorRpc.post(MEMBERS_MANAGER, METHOD_GET_MEMBERS_BY_USER, params); + + return RpcMapper.mapMembers(jsonNode); + } + + private List<Vo> getVosByShortNames(List<String> voShortNames) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + List<Vo> vos = new ArrayList<>(); + for (String shortName : voShortNames) { + Vo vo = getVoByShortName(shortName); + vos.add(vo); + } + + return vos; + } + + private Map<Long, MemberStatus> convertMembersListToStatusesMap(List<Member> userMembers) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<Long, MemberStatus> res = new HashMap<>(); + for (Member m : userMembers) { + res.put(m.getVoId(), m.getStatus()); + } + + return res; + } + + private Map<String, PerunAttributeValue> getUserExtSourceAttributeValues(Long uesId, Set<AttributeMapping> attrMappings) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_USER_EXT_SOURCE, uesId); + map.put(PARAM_ATTR_NAMES, attrMappings.stream().map(AttributeMapping::getRpcName).collect(Collectors.toList())); + + JsonNode response = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_GET_ATTRIBUTES, map); + Map<String, PerunAttribute> attributeMap = RpcMapper.mapAttributes(response, attrMappings); + return extractValues(attributeMap); + } + + private List<Group> getAllowedGroups(Facility facility) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_FACILITY, facility.getId()); + JsonNode jsonNode = connectorRpc.post(FACILITIES_MANAGER, METHOD_GET_ALLOWED_GROUPS, map); + List<Group> result = new ArrayList<>(); + for (int i = 0; i < jsonNode.size(); i++) { + JsonNode groupNode = jsonNode.get(i); + result.add(RpcMapper.mapGroup(groupNode)); + } + + return result; + } + + private boolean hasApplicationForm(Group group) { + if (!connectorRpc.isEnabled()) { + return false; + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_GROUP, group.getId()); + try { + if (group.getName().equalsIgnoreCase("members")) { + log.debug("hasApplicationForm({}) continues to call regForm for VO {}", group, group.getVoId()); + return hasApplicationForm(group.getVoId()); + } else { + connectorRpc.post(REGISTRAR_MANAGER, METHOD_GET_APPLICATION_FORM, map); + } + } catch (Exception e) { + // when group does not have form exception is thrown. Every error thus is supposed as group without form + // this method will be used after calling other RPC methods - if RPC is not available other methods should discover it first + return false; + } + + return true; + } + + private boolean hasApplicationForm(Long voId) { + if (!connectorRpc.isEnabled()) { + return false; + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_VO, voId); + try { + connectorRpc.post(REGISTRAR_MANAGER, METHOD_GET_APPLICATION_FORM, map); + } catch (Exception e) { + // when vo does not have form exception is thrown. Every error thus is supposed as vo without form + // this method will be used after calling other RPC methods - if RPC is not available other methods should discover it first + return false; + } + + return true; + } + + private Map<Long, Vo> convertVoListToMap(List<Vo> vos) { + if (!connectorRpc.isEnabled()) { + return new HashMap<>(); + } + + Map<Long, Vo> map = new HashMap<>(); + for (Vo vo : vos) { + map.put(vo.getId(), vo); + } + + return map; + } + + private List<Resource> getAssignedResources(Facility facility) { + return getAssignedResources(facility.getId()); + } + + private List<Resource> getAssignedResources(Long facilityId) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_FACILITY, facilityId); + + JsonNode res = connectorRpc.post(FACILITIES_MANAGER, METHOD_GET_ASSIGNED_RESOURCES, map); + return RpcMapper.mapResources(res); + } + + private List<Resource> getAssignedRichResources(Facility facility) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_FACILITY, facility.getId()); + + JsonNode res = connectorRpc.post(FACILITIES_MANAGER, METHOD_GET_ASSIGNED_RICH_RESOURCES, map); + return RpcMapper.mapResources(res); + } + + private List<Group> getRichGroupsAssignedToResourceWithAttributesByNames(Resource resource, List<String> attrNames) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + Set<AttributeMapping> mappings = getGroupAttributesMappingService() + .getMappingsByIdentifiers(attrNames); + List<String> rpcNames = mappings.stream().map(AttributeMapping::getRpcName).collect(Collectors.toList()); + map.put(PARAM_RESOURCE, resource.getId()); + map.put(PARAM_ATTR_NAMES, rpcNames); + + JsonNode res = connectorRpc.post(GROUPS_MANAGER, METHOD_GET_RICH_GROUPS_ASSIGNED_TO_RESOURCE_WITH_ATTRIBUTES_BY_NAMES, map); + List<Group> groups = new ArrayList<>(); + + for (int i = 0; i < res.size(); i++) { + JsonNode jsonNode = res.get(i); + Group group = RpcMapper.mapGroup(jsonNode); + + JsonNode groupAttrs = jsonNode.get(FIELD_ATTRIBUTES); + Map<String, JsonNode> attrsMap = new HashMap<>(); + + for (int j = 0; j < groupAttrs.size(); j++) { + JsonNode attr = groupAttrs.get(j); + + String namespace = attr.get(FIELD_NAMESPACE).textValue(); + String friendlyName = attr.get(FIELD_FRIENDLY_NAME).textValue(); + + attrsMap.put(namespace + ":" + friendlyName, attr); + } + + group.setAttributes(attrsMap); + groups.add(group); + } + + return groups; + } + + private PerunAttribute getAttribute(PerunEntityType entity, Long entityId, String attributeName) { + if (!connectorRpc.isEnabled()) { + return null; + } + + AttributeMapping mapping; + switch (entity) { + case USER: + mapping = getUserAttributesMappingService() + .getMappingByIdentifier(attributeName); + break; + case FACILITY: + mapping = getFacilityAttributesMappingService() + .getMappingByIdentifier(attributeName); + break; + case VO: + mapping = getVoAttributesMappingService() + .getMappingByIdentifier(attributeName); + break; + case GROUP: + mapping = getGroupAttributesMappingService() + .getMappingByIdentifier(attributeName); + break; + case RESOURCE: + mapping = getResourceAttributesMappingService() + .getMappingByIdentifier(attributeName); + break; + default: + throw new IllegalArgumentException("Unrecognized entity"); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(entity.toString().toLowerCase(), entityId); + map.put(PARAM_ATTRIBUTE_NAME, mapping.getRpcName()); + + JsonNode res = connectorRpc.post(ATTRIBUTES_MANAGER, METHOD_GET_ATTRIBUTE, map); + return RpcMapper.mapAttribute(res); + } + + private List<UserExtSource> getUserExtSources(Long userId) { + if (!connectorRpc.isEnabled()) { + return new ArrayList<>(); + } + + Map<String, Object> map = new LinkedHashMap<>(); + map.put(PARAM_USER, userId); + + JsonNode response = connectorRpc.post(USERS_MANAGER, METHOD_GET_USER_EXT_SOURCES, map); + return RpcMapper.mapUserExtSources(response); + } + + private Set<String> getFacilityCapabilities(Facility facility, String capabilitiesAttrName) { + if (!connectorRpc.isEnabled()) { + return new HashSet<>(); + } + + Set<String> capabilities = new HashSet<>(); + if (facility != null) { + PerunAttributeValue attr = getFacilityAttributeValue(facility, capabilitiesAttrName); + if (attr != null && attr.valueAsList() != null) { + capabilities = new HashSet<>(attr.valueAsList()); + } + } + + return capabilities; + } } diff --git a/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/connectors/PerunConnectorRpc.java b/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/connectors/PerunConnectorRpc.java index 4a5e1ce6bb12a2dec2b9679232743d0db7e666eb..e590c9acb2421143067dc23699bfc1d0baf44619 100644 --- a/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/connectors/PerunConnectorRpc.java +++ b/perun-oidc-server/src/main/java/cz/muni/ics/oidc/server/connectors/PerunConnectorRpc.java @@ -37,182 +37,232 @@ import java.util.Map; @Slf4j public class PerunConnectorRpc implements InitializingBean { - public static final String ATTRIBUTES_MANAGER = "attributesManager"; - public static final String FACILITIES_MANAGER = "facilitiesManager"; - public static final String GROUPS_MANAGER = "groupsManager"; - public static final String MEMBERS_MANAGER = "membersManager"; - public static final String REGISTRAR_MANAGER = "registrarManager"; - public static final String SEARCHER = "searcher"; - public static final String USERS_MANAGER = "usersManager"; - public static final String VOS_MANAGER = "vosManager"; - public static final String RESOURCES_MANAGER = "resourcesManager"; - - private String perunUrl; - private String perunUser; - private String perunPassword; - private boolean isEnabled; - private String serializer; - - private int connectionRequestTimeout = 30000; - private int connectionTimeout = 30000; - private int responseTimeout = 60000; - private RestTemplate restTemplate; - - public PerunConnectorRpc(String url, - String username, - String password, - String enabled, - String serializer, - int connectionRequestTimeout, - int connectionTimeout, - int responseTimeout) - { - this.isEnabled = Boolean.parseBoolean(enabled); - this.setPerunUrl(url); - this.setPerunUser(username); - this.setPerunPassword(password); - this.setSerializer(serializer); - this.setConnectionRequestTimeout(connectionRequestTimeout); - this.setConnectionTimeout(connectionTimeout); - this.setResponseTimeout(responseTimeout); - } - - private void setEnabled(String enabled) { - this.isEnabled = Boolean.parseBoolean(enabled); - } - - public boolean isEnabled() { - return isEnabled; - } - - private void setPerunUrl(String perunUrl) { - if (!StringUtils.hasText(perunUrl)) { - throw new IllegalArgumentException("Perun URL cannot be null or empty"); - } else if (perunUrl.endsWith("/")) { - perunUrl = perunUrl.substring(0, perunUrl.length() - 1); - } - - this.perunUrl = perunUrl; - } - - private void setPerunUser(String perunUser) { - if (!StringUtils.hasText(perunUser)) { - throw new IllegalArgumentException("Perun USER cannot be null or empty"); - } - - this.perunUser = perunUser; - } - - private void setPerunPassword(String perunPassword) { - if (!StringUtils.hasText(perunPassword)) { - throw new IllegalArgumentException("Perun PASSWORD cannot be null or empty"); - } - - this.perunPassword = perunPassword; - } - - private void setSerializer(String serializer) { - if (!StringUtils.hasText(serializer)) { - serializer = "json"; - } - - this.serializer = serializer; - } - - private void setConnectionRequestTimeout(int connectionRequestTimeout) { - if (0 >= connectionRequestTimeout) { - throw new IllegalArgumentException("Connection request timeout must be greater than 0ms"); - } - this.connectionRequestTimeout = connectionRequestTimeout; - } - - private void setConnectionTimeout(int connectionTimeout) { - if (0 >= connectionTimeout) { - throw new IllegalArgumentException("Connection timeout must be greater than 0ms"); - } - this.connectionTimeout = connectionTimeout; - } - - private void setResponseTimeout(int responseTimeout) { - if (0 >= responseTimeout) { - throw new IllegalArgumentException("Response timeout must be greater than 0ms"); - } - this.responseTimeout = responseTimeout; - } - - @Override - public void afterPropertiesSet() { - restTemplate = new RestTemplate(); - //HTTP connection pooling, see https://howtodoinjava.com/spring-restful/resttemplate-httpclient-java-config/ - RequestConfig requestConfig = RequestConfig.custom() - .setConnectionRequestTimeout(this.connectionRequestTimeout) // The timeout when requesting a connection from the connection manager - .setConnectTimeout(this.connectionTimeout) // Determines the timeout in milliseconds until a connection is established - .setSocketTimeout(this.responseTimeout) // The timeout for waiting for data - .build(); - PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(); - poolingConnectionManager.setMaxTotal(20); // maximum connections total - poolingConnectionManager.setDefaultMaxPerRoute(18); - ConnectionKeepAliveStrategy connectionKeepAliveStrategy = (response, context) -> { - HeaderElementIterator it = new BasicHeaderElementIterator - (response.headerIterator(HTTP.CONN_KEEP_ALIVE)); - while (it.hasNext()) { - HeaderElement he = it.nextElement(); - String param = he.getName(); - String value = he.getValue(); - - if (value != null && param.equalsIgnoreCase("timeout")) { - return Long.parseLong(value) * 1000; - } - } - return 20000L; - }; - CloseableHttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(requestConfig) - .setConnectionManager(poolingConnectionManager) - .setKeepAliveStrategy(connectionKeepAliveStrategy) - .build(); - HttpComponentsClientHttpRequestFactory poolingRequestFactory = new HttpComponentsClientHttpRequestFactory(); - poolingRequestFactory.setHttpClient(httpClient); - //basic authentication - List<ClientHttpRequestInterceptor> interceptors = - Collections.singletonList(new BasicAuthorizationInterceptor(perunUser, perunPassword)); - InterceptingClientHttpRequestFactory authenticatingRequestFactory = new InterceptingClientHttpRequestFactory(poolingRequestFactory, interceptors); - restTemplate.setRequestFactory(authenticatingRequestFactory); - } - - /** - * Make post call to Perun RPC - * @param manager String value representing manager to be called. Use constants from this class. - * @param method Method to be called (i.e. getUserById) - * @param map Map of parameters to be passed as request body - * @return Response from Perun - */ - @LogTimes - public JsonNode post(String manager, String method, Map<String, Object> map) { - if (!this.isEnabled) { - return JsonNodeFactory.instance.nullNode(); - } - - String actionUrl = perunUrl + '/' + serializer + '/' + manager + '/' + method; - //make the call - try { - log.debug("calling {} with {}", actionUrl, map); - return restTemplate.postForObject(actionUrl, map, JsonNode.class); - } catch (HttpClientErrorException ex) { - MediaType contentType = ex.getResponseHeaders().getContentType(); - String body = ex.getResponseBodyAsString(); - log.error("HTTP ERROR " + ex.getRawStatusCode() + " URL " + actionUrl + " Content-Type: " + contentType); - if ("json".equals(contentType.getSubtype())) { - try { - log.error(new ObjectMapper().readValue(body, JsonNode.class).path("message").asText()); - } catch (IOException e) { - log.error("cannot parse error message from JSON", e); - } - } else { - log.error(ex.getMessage()); - } - throw new RuntimeException("cannot connect to Perun RPC", ex); - } - } + public static final String ATTRIBUTES_MANAGER = "attributesManager"; + public static final String FACILITIES_MANAGER = "facilitiesManager"; + public static final String GROUPS_MANAGER = "groupsManager"; + public static final String MEMBERS_MANAGER = "membersManager"; + public static final String REGISTRAR_MANAGER = "registrarManager"; + public static final String SEARCHER = "searcher"; + public static final String USERS_MANAGER = "usersManager"; + public static final String VOS_MANAGER = "vosManager"; + public static final String RESOURCES_MANAGER = "resourcesManager"; + + public static final String PARAM_ID = "id"; + public static final String PARAM_RESOURCE = "resource"; + public static final String PARAM_FACILITY = "facility"; + public static final String PARAM_GROUP = "group"; + public static final String PARAM_VO = "vo"; + public static final String PARAM_USER = "user"; + public static final String PARAM_MEMBER = "member"; + public static final String PARAM_USER_EXT_SOURCE = "userExtSource"; + public static final String PARAM_ATTRIBUTE = "attribute"; + public static final String PARAM_ATTRIBUTE_NAME = "attributeName"; + public static final String PARAM_ATTRIBUTE_VALUE = "attributeValue"; + public static final String PARAM_ATTRIBUTE_DEFINITION = "attributeDefinition"; + public static final String PARAM_ATTR_NAMES = "attrNames"; + public static final String PARAM_ATTR_NAME = "attrName"; + public static final String PARAM_EXT_LOGIN = "extLogin"; + public static final String PARAM_EXT_SOURCE_NAME = "extSourceName"; + public static final String PARAM_SHORT_NAME = "shortName"; + + // METHODS + + public static final String METHOD_GET_USER_BY_EXT_SOURCE_NAME_AND_EXT_LOGIN = + "getUserByExtSourceNameAndExtLogin"; + public static final String METHOD_GET_FACILITIES_BY_ATTRIBUTE = "getFacilitiesByAttribute"; + public static final String METHOD_GET_ATTRIBUTE = "getAttribute"; + public static final String METHOD_GET_GROUP_BY_ID = "getGroupById"; + public static final String METHOD_GET_MEMBER_BY_USER = "getMemberByUser"; + public static final String METHOD_IS_GROUP_MEMBER = "isGroupMember"; + public static final String METHOD_SET_ATTRIBUTE = "setAttribute"; + public static final String EXT_SOURCE_IDP = "cz.metacentrum.perun.core.impl.ExtSourceIdp"; + public static final String METHOD_GET_ENTITYLESS_ATTRIBUTES = "getEntitylessAttributes"; + public static final String METHOD_GET_ENTITYLESS_KEYS = "getEntitylessKeys"; + public static final String METHOD_GET_VO_BY_SHORT_NAME = "getVoByShortName"; + public static final String METHOD_GET_USER_BY_ID = "getUserById"; + public static final String METHOD_GET_GROUPS_WHERE_USER_IS_ACTIVE = "getGroupsWhereUserIsActive"; + public static final String METHOD_GET_ALLOWED_RESOURCES = "getAllowedResources"; + public static final String METHOD_GET_VO_BY_ID = "getVoById"; + public static final String METHOD_GET_ASSIGNED_GROUPS = "getAssignedGroups"; + public static final String METHOD_GET_ATTRIBUTES = "getAttributes"; + public static final String METHOD_GET_MEMBER_GROUPS = "getMemberGroups"; + public static final String METHOD_GET_MEMBERS_BY_USER = "getMembersByUser"; + public static final String METHOD_GET_ALLOWED_GROUPS = "getAllowedGroups"; + public static final String METHOD_GET_APPLICATION_FORM = "getApplicationForm"; + public static final String METHOD_GET_ASSIGNED_RESOURCES = "getAssignedResources"; + public static final String METHOD_GET_ASSIGNED_RICH_RESOURCES = "getAssignedRichResources"; + public static final String METHOD_GET_RICH_GROUPS_ASSIGNED_TO_RESOURCE_WITH_ATTRIBUTES_BY_NAMES = + "getRichGroupsAssignedToResourceWithAttributesByNames"; + public static final String METHOD_GET_USER_EXT_SOURCES = "getUserExtSources"; + + // VARIABLES + + private String perunUrl; + private String perunUser; + private String perunPassword; + private boolean isEnabled; + private String serializer; + + private int connectionRequestTimeout = 30000; + private int connectionTimeout = 30000; + private int responseTimeout = 60000; + private RestTemplate restTemplate; + + public PerunConnectorRpc(String url, + String username, + String password, + String enabled, + String serializer, + int connectionRequestTimeout, + int connectionTimeout, + int responseTimeout) { + this.isEnabled = Boolean.parseBoolean(enabled); + this.setPerunUrl(url); + this.setPerunUser(username); + this.setPerunPassword(password); + this.setSerializer(serializer); + this.setConnectionRequestTimeout(connectionRequestTimeout); + this.setConnectionTimeout(connectionTimeout); + this.setResponseTimeout(responseTimeout); + } + + private void setEnabled(String enabled) { + this.isEnabled = Boolean.parseBoolean(enabled); + } + + public boolean isEnabled() { + return isEnabled; + } + + private void setPerunUrl(String perunUrl) { + if (!StringUtils.hasText(perunUrl)) { + throw new IllegalArgumentException("Perun URL cannot be null or empty"); + } else if (perunUrl.endsWith("/")) { + perunUrl = perunUrl.substring(0, perunUrl.length() - 1); + } + + this.perunUrl = perunUrl; + } + + private void setPerunUser(String perunUser) { + if (!StringUtils.hasText(perunUser)) { + throw new IllegalArgumentException("Perun USER cannot be null or empty"); + } + + this.perunUser = perunUser; + } + + private void setPerunPassword(String perunPassword) { + if (!StringUtils.hasText(perunPassword)) { + throw new IllegalArgumentException("Perun PASSWORD cannot be null or empty"); + } + + this.perunPassword = perunPassword; + } + + private void setSerializer(String serializer) { + if (!StringUtils.hasText(serializer)) { + serializer = "json"; + } + + this.serializer = serializer; + } + + private void setConnectionRequestTimeout(int connectionRequestTimeout) { + if (0 >= connectionRequestTimeout) { + throw new IllegalArgumentException("Connection request timeout must be greater than 0ms"); + } + this.connectionRequestTimeout = connectionRequestTimeout; + } + + private void setConnectionTimeout(int connectionTimeout) { + if (0 >= connectionTimeout) { + throw new IllegalArgumentException("Connection timeout must be greater than 0ms"); + } + this.connectionTimeout = connectionTimeout; + } + + private void setResponseTimeout(int responseTimeout) { + if (0 >= responseTimeout) { + throw new IllegalArgumentException("Response timeout must be greater than 0ms"); + } + this.responseTimeout = responseTimeout; + } + + @Override + public void afterPropertiesSet() { + restTemplate = new RestTemplate(); + //HTTP connection pooling, see https://howtodoinjava.com/spring-restful/resttemplate-httpclient-java-config/ + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(this.connectionRequestTimeout) // The timeout when requesting a connection from the connection manager + .setConnectTimeout(this.connectionTimeout) // Determines the timeout in milliseconds until a connection is established + .setSocketTimeout(this.responseTimeout) // The timeout for waiting for data + .build(); + PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(); + poolingConnectionManager.setMaxTotal(20); // maximum connections total + poolingConnectionManager.setDefaultMaxPerRoute(18); + ConnectionKeepAliveStrategy connectionKeepAliveStrategy = (response, context) -> { + HeaderElementIterator it = new BasicHeaderElementIterator + (response.headerIterator(HTTP.CONN_KEEP_ALIVE)); + while (it.hasNext()) { + HeaderElement he = it.nextElement(); + String param = he.getName(); + String value = he.getValue(); + + if (value != null && param.equalsIgnoreCase("timeout")) { + return Long.parseLong(value) * 1000; + } + } + return 20000L; + }; + CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) + .setConnectionManager(poolingConnectionManager) + .setKeepAliveStrategy(connectionKeepAliveStrategy) + .build(); + HttpComponentsClientHttpRequestFactory poolingRequestFactory = new HttpComponentsClientHttpRequestFactory(); + poolingRequestFactory.setHttpClient(httpClient); + //basic authentication + List<ClientHttpRequestInterceptor> interceptors = + Collections.singletonList(new BasicAuthorizationInterceptor(perunUser, perunPassword)); + InterceptingClientHttpRequestFactory authenticatingRequestFactory = new InterceptingClientHttpRequestFactory(poolingRequestFactory, interceptors); + restTemplate.setRequestFactory(authenticatingRequestFactory); + } + + /** + * Make post call to Perun RPC + * + * @param manager String value representing manager to be called. Use constants from this class. + * @param method Method to be called (i.e. getUserById) + * @param map Map of parameters to be passed as request body + * @return Response from Perun + */ + @LogTimes + public JsonNode post(String manager, String method, Map<String, Object> map) { + if (!this.isEnabled) { + return JsonNodeFactory.instance.nullNode(); + } + + String actionUrl = perunUrl + '/' + serializer + '/' + manager + '/' + method; + //make the call + try { + log.debug("calling {} with {}", actionUrl, map); + return restTemplate.postForObject(actionUrl, map, JsonNode.class); + } catch (HttpClientErrorException ex) { + MediaType contentType = ex.getResponseHeaders().getContentType(); + String body = ex.getResponseBodyAsString(); + log.error("HTTP ERROR " + ex.getRawStatusCode() + " URL " + actionUrl + " Content-Type: " + contentType); + if ("json".equals(contentType.getSubtype())) { + try { + log.error(new ObjectMapper().readValue(body, JsonNode.class).path("message").asText()); + } catch (IOException e) { + log.error("cannot parse error message from JSON", e); + } + } else { + log.error(ex.getMessage()); + } + throw new RuntimeException("cannot connect to Perun RPC", ex); + } + } }