/** * Convert RichUsers to Identity objects with obfuscated email address and limited set of ext * sources. Service users are removed from the list. * * @param list RichUsers to convert * @return list of Identities without service ones * @throws PerunException */ private List<Identity> convertToIdentities(List<RichUser> list) throws PerunException { List<Identity> result = new ArrayList<Identity>(); if (list != null && !list.isEmpty()) { for (RichUser u : list) { // skip service users if (u.isServiceUser()) continue; Identity identity = new Identity(); identity.setName(u.getDisplayName()); identity.setId(u.getId()); for (Attribute a : u.getUserAttributes()) { if (MailManagerImpl.URN_USER_PREFERRED_MAIL.equals(a.getName())) { if (a.getValue() != null && !((String) a.getValue()).isEmpty()) { String safeMail = ((String) a.getValue()).split("@")[0]; if (safeMail.length() > 2) { safeMail = safeMail.substring(0, 1) + "****" + safeMail.substring(safeMail.length() - 1, safeMail.length()); } safeMail += "@" + ((String) a.getValue()).split("@")[1]; identity.setEmail(safeMail); } } else if ("urn:perun:user:attribute-def:def:organization".equals(a.getName())) { if (a.getValue() != null) { identity.setOrganization((String) a.getValue()); } } } List<ExtSource> es = new ArrayList<ExtSource>(); for (UserExtSource ues : u.getUserExtSources()) { if (ues.getExtSource().getType().equals(ExtSourcesManagerEntry.EXTSOURCE_X509)) { es.add(ues.getExtSource()); } else if (ues.getExtSource().getType().equals(ExtSourcesManagerEntry.EXTSOURCE_IDP)) { if (ues.getExtSource().getName().equals("https://extidp.cesnet.cz/idp/shibboleth")) { // FIXME - hack Social IdP to let us know proper identity source String type = ues.getLogin().split("@")[1].split("\\.")[0]; ues.getExtSource() .setName( "https://extidp.cesnet.cz/idp/shibboleth&authnContextClassRef=urn:cesnet:extidp:authn:" + type); } else if (ues.getExtSource().getName().equals("https://login.elixir-czech.org/idp/")) { // FIXME - hack Elixir proxy IdP to let us know proper identity source String type = ues.getLogin().split("@")[1]; ues.getExtSource().setName("https://login.elixir-czech.org/idp/@" + type); } es.add(ues.getExtSource()); } else if (ues.getExtSource() .getType() .equals(ExtSourcesManagerEntry.EXTSOURCE_KERBEROS)) { es.add(ues.getExtSource()); } } identity.setIdentities(es); result.add(identity); } } return result; }
@Override public List<Identity> checkForSimilarUsers(PerunSession sess, int appId) throws PerunException { String email = ""; String name = ""; List<RichUser> result = new ArrayList<RichUser>(); List<String> attrNames = new ArrayList<String>(); attrNames.add("urn:perun:user:attribute-def:def:preferredMail"); attrNames.add("urn:perun:user:attribute-def:def:organization"); Application app = registrarManager.getApplicationById(registrarSession, appId); if (app.getGroup() == null) { if (!AuthzResolver.isAuthorized(sess, Role.VOADMIN, app.getVo())) { if (sess.getPerunPrincipal().getUser() != null) { // check if application to find similar users by belongs to user if (!sess.getPerunPrincipal().getUser().equals(app.getUser())) throw new PrivilegeException("checkForSimilarUsers"); } else { if (!sess.getPerunPrincipal().getExtSourceName().equals(app.getExtSourceName()) && !sess.getPerunPrincipal().getActor().equals(app.getCreatedBy())) throw new PrivilegeException("checkForSimilarUsers"); } } } else { if (!AuthzResolver.isAuthorized(sess, Role.VOADMIN, app.getVo()) && !AuthzResolver.isAuthorized(sess, Role.GROUPADMIN, app.getGroup())) { if (sess.getPerunPrincipal().getUser() != null) { // check if application to find similar users by belongs to user if (!sess.getPerunPrincipal().getUser().equals(app.getUser())) throw new PrivilegeException("checkForSimilarUsers"); } else { if (!sess.getPerunPrincipal().getExtSourceName().equals(app.getExtSourceName()) && !sess.getPerunPrincipal().getActor().equals(app.getCreatedBy())) throw new PrivilegeException("checkForSimilarUsers"); } } } // only for initial VO applications if user==null if (app.getType().equals(Application.AppType.INITIAL) && app.getGroup() == null && app.getUser() == null) { try { User u = perun .getUsersManager() .getUserByExtSourceNameAndExtLogin( registrarSession, app.getExtSourceName(), app.getCreatedBy()); if (u != null) { // user connected his identity after app creation and before it's approval. // do not show error message in GUI by returning an empty array. return convertToIdentities(result); } } catch (Exception ex) { // we don't care, let's try to search by name } List<ApplicationFormItemData> data = registrarManager.getApplicationDataById(sess, appId); // search by email, which should be unique (check is more precise) for (ApplicationFormItemData item : data) { if ("urn:perun:user:attribute-def:def:preferredMail" .equals(item.getFormItem().getPerunDestinationAttribute())) { email = item.getValue(); } if (email != null && !email.isEmpty()) break; } List<RichUser> users = (email != null && !email.isEmpty()) ? perun .getUsersManager() .findRichUsersWithAttributesByExactMatch(registrarSession, email, attrNames) : new ArrayList<RichUser>(); if (users != null && !users.isEmpty()) { // found by preferredMail return convertToIdentities(users); } // search by different mail email = ""; // clear previous value for (ApplicationFormItemData item : data) { if ("urn:perun:member:attribute-def:def:mail" .equals(item.getFormItem().getPerunDestinationAttribute())) { email = item.getValue(); } if (email != null && !email.isEmpty()) break; } users = (email != null && !email.isEmpty()) ? perun .getUsersManager() .findRichUsersWithAttributesByExactMatch(registrarSession, email, attrNames) : new ArrayList<RichUser>(); if (users != null && !users.isEmpty()) { // found by member mail return convertToIdentities(users); } // continue to search by display name for (ApplicationFormItemData item : data) { if (RegistrarManagerImpl.URN_USER_DISPLAY_NAME.equals( item.getFormItem().getPerunDestinationAttribute())) { name = item.getValue(); // use parsed name to drop mistakes on IDP side try { if (name != null && !name.isEmpty()) { Map<String, String> nameMap = Utils.parseCommonName(name); // drop name titles to spread search String newName = ""; if (nameMap.get("firstName") != null && !nameMap.get("firstName").isEmpty()) { newName += nameMap.get("firstName") + " "; } if (nameMap.get("lastName") != null && !nameMap.get("lastName").isEmpty()) { newName += nameMap.get("lastName"); } // fill parsed name instead of input if (newName != null && !newName.isEmpty()) { name = newName; } } } catch (Exception ex) { log.error( "[REGISTRAR] Unable to parse new user's display/common name when searching for similar users. Exception: {}", ex); } if (name != null && !name.isEmpty()) break; } } users = (name != null && !name.isEmpty()) ? perun .getUsersManager() .findRichUsersWithAttributesByExactMatch(registrarSession, name, attrNames) : new ArrayList<RichUser>(); if (users != null && !users.isEmpty()) { // found by member display name return convertToIdentities(users); } // continue to search by last name name = ""; // clear previous value for (ApplicationFormItemData item : data) { if (RegistrarManagerImpl.URN_USER_LAST_NAME.equals( item.getFormItem().getPerunDestinationAttribute())) { name = item.getValue(); if (name != null && !name.isEmpty()) break; } } if (name != null && !name.isEmpty()) { // what was found by name return convertToIdentities( perun .getUsersManager() .findRichUsersWithAttributesByExactMatch(registrarSession, name, attrNames)); } else { // not found by name return convertToIdentities(result); } } else { // not found, since not proper type of application to check users for return convertToIdentities(result); } }