Search in sources :

Example 1 with Strings

use of org.ocpsoft.common.util.Strings in project dataverse by IQSS.

the class UserServiceBean method retrieveRolesForUsers.

/**
 * Attempt to retrieve all the user roles in 1 query
 * Consider putting limits on this -- e.g. no more than 1,000 user identifiers or something similar
 *
 * @param userIdentifierList
 * @return
 */
private HashMap<String, List<String>> retrieveRolesForUsers(List<Object[]> userObjectList) {
    // Iterate through results, retrieving only the assignee identifiers
    // Note: userInfo[1], the assigneeIdentifier, cannot be null in the database
    // 
    List<String> userIdentifierList = userObjectList.stream().map(userInfo -> (String) userInfo[1]).collect(Collectors.toList());
    List<Integer> databaseIds = userObjectList.stream().map(userInfo -> (Integer) userInfo[0]).collect(Collectors.toList());
    if ((userIdentifierList == null) || (userIdentifierList.isEmpty())) {
        return null;
    }
    // -------------------------------------------------
    // Prepare a string to use within the SQL "a.assigneeidentifier IN (....)" clause
    // 
    // Note: This is not ideal but .setParameter was failing with attempts using:
    // 
    // Collection<String>, List<String>, String[]
    // 
    // This appears to be due to the JDBC driver or Postgres.  In this case SQL
    // injection isn't possible b/c the list of assigneeidentifier strings comes
    // from a previous query
    // 
    // Add '@' to each identifier and delimit the list by ","
    // -------------------------------------------------
    String identifierListString = userIdentifierList.stream().filter(x -> !Strings.isNullOrEmpty(x)).map(x -> "'@" + x + "'").collect(Collectors.joining(", "));
    // -------------------------------------------------
    // Create/Run the query to find directly assigned roles
    // -------------------------------------------------
    String qstr = "SELECT distinct a.assigneeidentifier,";
    qstr += " d.name";
    qstr += " FROM roleassignment a,";
    qstr += " dataverserole d";
    qstr += " WHERE d.id = a.role_id";
    qstr += " AND a.assigneeidentifier IN (" + identifierListString + ")";
    qstr += " ORDER by a.assigneeidentifier, d.name;";
    Query nativeQuery = em.createNativeQuery(qstr);
    List<Object[]> dbRoleResults = nativeQuery.getResultList();
    if (dbRoleResults == null) {
        return null;
    }
    HashMap<String, List<String>> userRoleLookup = new HashMap<>();
    String userIdentifier;
    String userRole;
    for (Object[] dbResultRow : dbRoleResults) {
        userIdentifier = UserUtil.getStringOrNull(dbResultRow[0]);
        userRole = UserUtil.getStringOrNull(dbResultRow[1]);
        if ((userIdentifier != null) && (userRole != null)) {
            // should never be null
            List<String> userRoleList = userRoleLookup.getOrDefault(userIdentifier, new ArrayList<String>());
            if (!userRoleList.contains(userRole)) {
                userRoleList.add(userRole);
                userRoleLookup.put(userIdentifier, userRoleList);
            }
        }
    }
    // And now the roles assigned via groups:
    // 1. One query for selecting all the groups to which these users may belong:
    HashMap<String, List<String>> groupsLookup = new HashMap<>();
    String idListString = StringUtils.join(databaseIds, ",");
    // A *RECURSIVE* native query, that finds all the groups that the specified
    // users are part of, BOTH by direct inclusion, AND via parent groups:
    qstr = "WITH RECURSIVE group_user AS ((" + " SELECT distinct g.groupalias, g.id, u.useridentifier" + "  FROM explicitgroup g, explicitgroup_authenticateduser e, authenticateduser u" + "  WHERE e.explicitgroup_id = g.id " + "   AND u.id IN (" + idListString + ")" + "   AND u.id = e.containedauthenticatedusers_id)" + "  UNION\n" + "   SELECT p.groupalias, p.id, c.useridentifier" + "    FROM group_user c, explicitgroup p, explicitgroup_explicitgroup e" + "    WHERE e.explicitgroup_id = p.id" + "     AND e.containedexplicitgroups_id = c.id)" + "SELECT distinct groupalias, useridentifier FROM group_user;";
    // System.out.println("qstr: " + qstr);
    nativeQuery = em.createNativeQuery(qstr);
    List<Object[]> groupResults = nativeQuery.getResultList();
    if (groupResults == null) {
        return userRoleLookup;
    }
    String groupIdentifiers = null;
    for (Object[] group : groupResults) {
        String alias = UserUtil.getStringOrNull(group[0]);
        String user = UserUtil.getStringOrNull(group[1]);
        if (alias != null) {
            alias = "&explicit/" + alias;
            if (groupIdentifiers == null) {
                groupIdentifiers = "'" + alias + "'";
            } else {
                groupIdentifiers += ", '" + alias + "'";
            }
            List<String> groupUserList = groupsLookup.getOrDefault(alias, new ArrayList<String>());
            if (!groupUserList.contains(user)) {
                groupUserList.add(user);
                groupsLookup.put(alias, groupUserList);
            }
        }
    }
    if (groupIdentifiers == null) {
        return userRoleLookup;
    }
    qstr = "SELECT distinct a.assigneeidentifier,";
    qstr += " d.name";
    qstr += " FROM roleassignment a,";
    qstr += " dataverserole d";
    qstr += " WHERE d.id = a.role_id";
    qstr += " AND a.assigneeidentifier IN (";
    qstr += groupIdentifiers;
    qstr += ") ORDER by a.assigneeidentifier, d.name;";
    // System.out.println("qstr: " + qstr);
    nativeQuery = em.createNativeQuery(qstr);
    dbRoleResults = nativeQuery.getResultList();
    if (dbRoleResults == null) {
        return userRoleLookup;
    }
    for (Object[] dbResultRow : dbRoleResults) {
        String groupIdentifier = UserUtil.getStringOrNull(dbResultRow[0]);
        String groupRole = UserUtil.getStringOrNull(dbResultRow[1]);
        if ((groupIdentifier != null) && (groupRole != null)) {
            // should never be null
            List<String> groupUserList = groupsLookup.get(groupIdentifier);
            if (groupUserList != null) {
                for (String groupUserIdentifier : groupUserList) {
                    groupUserIdentifier = "@" + groupUserIdentifier;
                    // System.out.println("Group user: "+groupUserIdentifier);
                    List<String> userRoleList = userRoleLookup.getOrDefault(groupUserIdentifier, new ArrayList<String>());
                    if (!userRoleList.contains(groupRole)) {
                        // System.out.println("User Role: "+groupRole);
                        userRoleList.add(groupRole);
                        userRoleLookup.put(groupUserIdentifier, userRoleList);
                    }
                }
            }
        }
    }
    return userRoleLookup;
}
Also used : AuthenticatedUser(edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser) Stateless(javax.ejb.Stateless) UserUtil(edu.harvard.iq.dataverse.userdata.UserUtil) StringUtils(org.apache.commons.lang.StringUtils) Date(java.util.Date) IndexServiceBean(edu.harvard.iq.dataverse.search.IndexServiceBean) Timestamp(java.sql.Timestamp) HashMap(java.util.HashMap) EntityManager(javax.persistence.EntityManager) PersistenceContext(javax.persistence.PersistenceContext) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) List(java.util.List) Query(javax.persistence.Query) Strings(org.ocpsoft.common.util.Strings) Named(javax.inject.Named) EJB(javax.ejb.EJB) Query(javax.persistence.Query) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

AuthenticatedUser (edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser)1 IndexServiceBean (edu.harvard.iq.dataverse.search.IndexServiceBean)1 UserUtil (edu.harvard.iq.dataverse.userdata.UserUtil)1 Timestamp (java.sql.Timestamp)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Level (java.util.logging.Level)1 Logger (java.util.logging.Logger)1 Collectors (java.util.stream.Collectors)1 EJB (javax.ejb.EJB)1 Stateless (javax.ejb.Stateless)1 Named (javax.inject.Named)1 EntityManager (javax.persistence.EntityManager)1 PersistenceContext (javax.persistence.PersistenceContext)1 Query (javax.persistence.Query)1 StringUtils (org.apache.commons.lang.StringUtils)1 Strings (org.ocpsoft.common.util.Strings)1