package eu.dnetlib.repo.manager.service.aai.registry; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.nimbusds.jose.util.StandardCharset; import eu.dnetlib.repo.manager.domain.dto.Role; import eu.dnetlib.repo.manager.domain.dto.User; import eu.dnetlib.repo.manager.service.aai.registry.utils.HttpUtils; import eu.dnetlib.repo.manager.service.aai.registry.utils.RegistryUtils; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.*; @Service public class RegistryCalls implements AaiRegistryService { private static final Logger logger = LoggerFactory.getLogger(RegistryCalls.class); public final HttpUtils httpUtils; public final RegistryUtils jsonUtils; private final String coid; @Autowired RegistryCalls(HttpUtils httpUtils, RegistryUtils registryUtils, @Value("${services.provide.aai.registry.coid}") String coid) { this.httpUtils = httpUtils; this.jsonUtils = registryUtils; this.coid = coid; } private String mapType(String type, boolean communityMap) { if (type.equals("organization")) { type = "institution"; } else if (type.equals("ri") && communityMap) { type = "community"; } return type; } @Override public List getUserIdentifiersByEmail(String email) { List ids = new ArrayList<>(); for (Integer coPersonId : getCoPersonIdsByEmail(email)) { ids.addAll(getUserIdentifiersByCoPersonId(coPersonId)); } return ids; } @Override public List getUserIdentifiersByCoPersonId(Integer coPersonId) { List ids = new ArrayList<>(); Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("identifiers.json", params); if (response != null) { JsonArray infos = response.getAsJsonObject().get("Identifiers").getAsJsonArray(); infos.forEach(info -> { JsonObject jsonInfo = info.getAsJsonObject(); if (!jsonInfo.get("Deleted").getAsBoolean()) { ids.add(jsonInfo.get("Identifier").getAsString()); } }); } return ids; } @Override public List getCoPersonIdsByEmail() { try { OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); String email = authentication.getUserInfo().getEmail(); return getCoPersonIdsByEmail(email); } catch (Exception e) { logger.error("Get User info: An error occurred ", e); return null; } } @Override public List getCoPersonIdsByEmail(String email) { List coPersonIds = new ArrayList<>(); Map params = new HashMap<>(); params.put("mail", email); params.put("coid", coid); JsonElement response = httpUtils.get("co_people.json", params); if (response != null) { JsonArray coPeople = response.getAsJsonObject().get("CoPeople").getAsJsonArray(); for (int i = 0; i < coPeople.size(); i++) { coPersonIds.add(coPeople.get(i).getAsJsonObject().get("Id").getAsInt()); } } return coPersonIds; } @Override public Integer getCoPersonIdByIdentifier() { try { OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); String sub = authentication.getUserInfo().getSub(); return getCoPersonIdByIdentifier(sub); } catch (Exception e) { logger.error("Get User info: An error occurred ", e); return null; } } public Integer getCoPersonIdByIdentifier(String sub) { Map params = new HashMap<>(); params.put("search.identifier", sub); params.put("coid", coid); JsonElement response = httpUtils.get("co_people.json", params); return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null; } @Override public JsonArray getCous(String name) { Map params = new HashMap<>(); if (name != null) { try { params.put("name", URLEncoder.encode(name, StandardCharset.UTF_8.name()).toLowerCase()); } catch (UnsupportedEncodingException uee) { logger.error(uee.getMessage()); return new JsonArray(); } } JsonElement response = httpUtils.get("cous.json", params); return (response != null) ? response.getAsJsonObject().get("Cous").getAsJsonArray() : new JsonArray(); } @Override public JsonArray getCous() { return getCous(null); } @Override public Integer getCouId(String name) { JsonArray cous = getCous(name); for (JsonElement cou : cous) { if (cou.getAsJsonObject().get("Name").getAsString().equalsIgnoreCase(name)) { return cou.getAsJsonObject().get("Id").getAsInt(); } } return null; } @Override public Integer getCouId(String type, String id, boolean communityMap) { return getCouId(mapType(type, communityMap) + "." + id); } @Override public Integer getCouId(String type, String id) { return getCouId(type, id, true); } @Override public JsonArray getRoles(Integer coPersonId) { Map params = new HashMap<>(); params.put("coid", coid); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("co_person_roles.json", params); return (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray(); } @Override public JsonArray getRolesWithStatus(Integer coPersonId, RoleStatus status) { return getRolesWithStatus(Collections.singletonList(coPersonId), status); } @Override public JsonArray getRolesWithStatus(List coPersonIds, RoleStatus status) { JsonArray roles = new JsonArray(); coPersonIds.parallelStream().forEach(coPersonId -> roles.addAll(getRoles(coPersonId))); JsonArray activeRoles = new JsonArray(); if (status != null) { for (JsonElement role : roles) { if (role.getAsJsonObject().get("Status").getAsString().equalsIgnoreCase(status.toString())) { activeRoles.add(role); } } } return activeRoles; } @Override public Integer getRoleId(Integer coPersonId, Integer couId) { JsonArray roles = getRoles(coPersonId); for (JsonElement role : roles) { JsonObject object = role.getAsJsonObject(); if (object.get("CouId").getAsInt() == couId && !object.get("Status").getAsString().equals("Deleted")) { return object.get("Id").getAsInt(); } } return null; } @Override public JsonArray getUserGroups(Integer coPersonId) { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("co_groups.json", params); return (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray(); } @Override public JsonObject getUserAdminGroup(Integer coPersonId, Integer couId) { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("co_groups.json", params); JsonArray roles = (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray(); for (JsonElement role : roles) { JsonObject object = role.getAsJsonObject(); if (object.get("CouId") != null && object.get("CouId").getAsInt() == couId) { if (object.get("Name").getAsString().contains("admins")) { return object; } } } return null; } @Override public JsonArray getCouGroups(Integer couId) { Map params = new HashMap<>(); params.put("couid", couId.toString()); JsonElement response = httpUtils.get("co_groups.json", params); return (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray(); } @Override public JsonObject getCouAdminGroup(Integer couId) { JsonArray groups = getCouGroups(couId); for (JsonElement group : groups) { if (group.getAsJsonObject().get("Name").getAsString().contains("admins")) { return group.getAsJsonObject(); } } return null; } @Override public JsonArray getGroupMembers(Integer coGroupId) { Map params = new HashMap<>(); params.put("cogroupid", coGroupId.toString()); JsonElement response = httpUtils.get("co_group_members.json", params); return (response != null) ? response.getAsJsonObject().get("CoGroupMembers").getAsJsonArray() : new JsonArray(); } @Override public JsonArray getUserEmailByCouId(Integer couId, boolean admin) { Map params = new HashMap<>(); if (couId == null) { throw new IllegalArgumentException("Provided 'couId' is null"); } params.put("couid", couId.toString()); if (admin) { params.put("admin", "true"); } JsonElement response = httpUtils.get("email_addresses.json", params); JsonArray infos = (response != null) ? response.getAsJsonObject().get("EmailAddresses").getAsJsonArray() : new JsonArray(); JsonArray emails = new JsonArray(); infos.forEach(info -> { JsonObject user = new JsonObject(); boolean add = true; String email = info.getAsJsonObject().get("Mail").getAsString(); for (JsonElement element : emails) { if (element.getAsJsonObject().get("email").getAsString().equals(email)) { add = false; } } if (add) { user.addProperty("email", email); user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString()); emails.add(user); } }); return emails; } @Override public JsonArray getUsersByCouId(Integer couId) { Map params = new HashMap<>(); params.put("couid", couId.toString()); JsonElement response = httpUtils.get("co_person_roles.json", params); JsonArray infos = (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray(); // JsonArray users = new JsonArray(); // infos.forEach(info -> { // JsonObject user = new JsonObject(); // user.addProperty("email", info.getAsJsonObject().get("Mail").getAsString()); // user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString()); // emails.add(user); // }); return infos; } @Override public List getUsers(Integer couId) { List users = new ArrayList<>(); JsonArray infos = getUserEmailByCouId(couId, false); infos.forEach(info -> { JsonObject jsonInfo = info.getAsJsonObject(); User user = new User(); user.setEmail(jsonInfo.get("email").getAsString()); // TODO: should add firstname and lastname and sub of user users.add(user); }); return users; } @Override public JsonArray getUserNamesByCouId(Integer couId, boolean admin) { Map params = new HashMap<>(); params.put("couid", couId.toString()); if (admin) { params.put("admin", "true"); } JsonElement response = httpUtils.get("names.json", params); JsonArray infos = (response != null) ? response.getAsJsonObject().get("Names").getAsJsonArray() : new JsonArray(); JsonArray names = new JsonArray(); infos.forEach(info -> { JsonObject jsonInfo = info.getAsJsonObject(); JsonObject user = new JsonObject(); user.addProperty("name", jsonInfo.get("Given").getAsString() + " " + jsonInfo.get("Family").getAsString()); user.addProperty("memberSince", jsonInfo.get("Created").getAsString()); names.add(user); }); return names; } @Override public JsonArray getUserIdByCouId(Integer couId, boolean admin) { Map params = new HashMap<>(); params.put("couid", couId.toString()); if (admin) { params.put("admin", "true"); } JsonElement response = httpUtils.get("identifiers.json", params); JsonArray infos = (response != null) ? response.getAsJsonObject().get("Identifiers").getAsJsonArray() : new JsonArray(); JsonArray emails = new JsonArray(); infos.forEach(info -> { JsonObject jsonInfo = info.getAsJsonObject(); JsonObject user = new JsonObject(); user.addProperty("id", jsonInfo.get("Identifier").getAsString()); user.addProperty("memberSince", jsonInfo.get("Created").getAsString()); emails.add(user); }); return emails; } @Override public void assignMemberRole(Integer coPersonId, Integer couId) { httpUtils.post("co_person_roles.json", jsonUtils.coPersonRoles(coPersonId, couId, "Active")); } @Override public void removeMemberRole(Integer coPersonId, Integer couId, Integer id) { if (id != null) { httpUtils.put("co_person_roles/" + id + ".json", jsonUtils.coPersonRoles(coPersonId, couId, "Deleted")); } } @Override public Integer createRole(Role role) { JsonElement element = httpUtils.post("cous.json", jsonUtils.createNewCou(role)); return element.getAsJsonObject().get("Id").getAsInt(); } @Override public String getUserEmail(Integer coPersonId) { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("email_addresses.json", params); JsonObject info = (response != null) ? response.getAsJsonObject().get("EmailAddresses").getAsJsonArray().get(0).getAsJsonObject() : null; return (info != null) ? info.getAsJsonObject().get("Mail").getAsString() : null; } @Override public String getUserNames(Integer coPersonId) { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("names.json", params); JsonObject info = (response != null) ? response.getAsJsonObject().get("Names").getAsJsonArray().get(0).getAsJsonObject() : null; if (info != null) { JsonObject jsonInfo = info.getAsJsonObject(); return jsonInfo.get("Given").getAsString() + " " + jsonInfo.get("Family").getAsString(); } else return null; } @Override public String getUserId(Integer coPersonId) { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("identifiers.json", params); JsonObject info = (response != null) ? response.getAsJsonObject().get("Identifiers").getAsJsonArray().get(0).getAsJsonObject() : null; return (info != null) ? info.getAsJsonObject().get("Identifier").getAsString() : null; } @Override public void assignAdminRole(Integer coPersonId, Integer couId) { JsonObject group = getCouAdminGroup(couId); if (group != null) { httpUtils.post("co_group_members.json", jsonUtils.coGroupMembers(group.get("Id").getAsInt(), coPersonId, true)); } } @Override public void removeAdminRole(Integer coPersonId, Integer couId) { JsonObject adminGroup = this.getCouAdminGroup(couId); JsonArray admins = this.getGroupMembers(adminGroup.get("Id").getAsInt()); Integer id = null; for (JsonElement admin : admins) { if (admin.getAsJsonObject().get("Person").getAsJsonObject().get("Id").getAsInt() == coPersonId) { id = admin.getAsJsonObject().get("Id").getAsInt(); } } if (id != null) { httpUtils.delete("co_group_members/" + id + ".json"); } } @Override public Map getCouNames(List couIds) { Map idNameMap = new HashMap<>(); for (Integer id : couIds) { idNameMap.put(id, null); } JsonArray cous = getCous(); int count = 0; int total = couIds.size(); for (JsonElement cou : cous) { if (count < total) { JsonObject jsonCou = cou.getAsJsonObject(); if (idNameMap.containsKey(jsonCou.get("Id").getAsInt())) { idNameMap.put(jsonCou.get("Id").getAsInt(), jsonCou.get("Name").getAsString()); count++; } } else { break; } } return idNameMap; } }