Skip to content
Snippets Groups Projects
Verified Commit f2b295e8 authored by Dominik Frantisek Bucik's avatar Dominik Frantisek Bucik
Browse files

refactor: :bulb: RPC Adapter

parent 76ce6903
Branches
Tags
1 merge request!396feat+refactor: filtering of assigned resource groups in entitlements, filtering of groups in access control filter, refactor PerunRPC Adapter
Pipeline #444661 passed
......@@ -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;
}
}
......@@ -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);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment