|
2 | 2 |
|
3 | 3 | import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
|
4 | 4 | import edu.harvard.iq.dataverse.authorization.DataverseRole;
|
| 5 | +import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.ip.IPv4Address; |
| 6 | +import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.ip.IPv6Address; |
| 7 | +import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.ip.IpAddress; |
5 | 8 | import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean;
|
6 | 9 | import edu.harvard.iq.dataverse.authorization.users.GuestUser;
|
7 | 10 | import edu.harvard.iq.dataverse.authorization.Permission;
|
8 | 11 | import edu.harvard.iq.dataverse.authorization.RoleAssignee;
|
9 |
| -import edu.harvard.iq.dataverse.authorization.groups.Group; |
10 | 12 | import edu.harvard.iq.dataverse.authorization.groups.GroupServiceBean;
|
11 |
| -import edu.harvard.iq.dataverse.authorization.groups.GroupUtil; |
12 | 13 | import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
|
13 | 14 | import edu.harvard.iq.dataverse.authorization.users.User;
|
14 | 15 | import edu.harvard.iq.dataverse.engine.command.Command;
|
|
37 | 38 | import java.util.Collections;
|
38 | 39 | import java.util.HashMap;
|
39 | 40 | import java.util.LinkedList;
|
40 |
| -import java.util.logging.Level; |
41 | 41 | import java.util.stream.Collectors;
|
42 | 42 | import static java.util.stream.Collectors.toList;
|
43 | 43 | import jakarta.persistence.Query;
|
@@ -100,6 +100,70 @@ public class PermissionServiceBean {
|
100 | 100 | @Inject
|
101 | 101 | DatasetVersionFilesServiceBean datasetVersionFilesServiceBean;
|
102 | 102 |
|
| 103 | + private static final String LIST_ALL_DATAVERSES_USER_HAS_PERMISSION = """ |
| 104 | + WITH grouplist AS ( |
| 105 | + SELECT explicitgroup_authenticateduser.explicitgroup_id as id FROM explicitgroup_authenticateduser |
| 106 | + WHERE explicitgroup_authenticateduser.containedauthenticatedusers_id = @USERID |
| 107 | + ) |
| 108 | + |
| 109 | + SELECT * FROM DATAVERSE WHERE id IN ( |
| 110 | + SELECT definitionpoint_id |
| 111 | + FROM roleassignment |
| 112 | + WHERE roleassignment.assigneeidentifier IN ( |
| 113 | + SELECT CONCAT('&explicit/', explicitgroup.groupalias) as assignee |
| 114 | + FROM explicitgroup |
| 115 | + WHERE explicitgroup.id IN ( |
| 116 | + ( |
| 117 | + SELECT explicitgroup.id id |
| 118 | + FROM explicitgroup |
| 119 | + WHERE EXISTS (SELECT id FROM grouplist WHERE id = explicitgroup.id) |
| 120 | + ) UNION ( |
| 121 | + SELECT explicitgroup_explicitgroup.containedexplicitgroups_id id |
| 122 | + FROM explicitgroup_explicitgroup |
| 123 | + WHERE EXISTS (SELECT id FROM grouplist WHERE id = explicitgroup_explicitgroup.explicitgroup_id) |
| 124 | + AND EXISTS (SELECT id FROM dataverserole |
| 125 | + WHERE dataverserole.id = roleassignment.role_id AND (dataverserole.permissionbits & @PERMISSIONBIT !=0)) |
| 126 | + ) |
| 127 | + ) |
| 128 | + ) UNION ( |
| 129 | + SELECT definitionpoint_id |
| 130 | + FROM roleassignment |
| 131 | + WHERE roleassignment.assigneeidentifier = ( |
| 132 | + SELECT CONCAT('@', authenticateduser.useridentifier) |
| 133 | + FROM authenticateduser |
| 134 | + WHERE authenticateduser.id = @USERID) |
| 135 | + AND EXISTS (SELECT id FROM dataverserole |
| 136 | + WHERE dataverserole.id = roleassignment.role_id AND (dataverserole.permissionbits & @PERMISSIONBIT !=0)) |
| 137 | + ) UNION ( |
| 138 | + SELECT definitionpoint_id |
| 139 | + FROM roleassignment |
| 140 | + WHERE roleassignment.assigneeidentifier = ':authenticated-users' |
| 141 | + AND EXISTS (SELECT id FROM dataverserole |
| 142 | + WHERE dataverserole.id = roleassignment.role_id AND (dataverserole.permissionbits & @PERMISSIONBIT !=0)) |
| 143 | + ) UNION ( |
| 144 | + SELECT definitionpoint_id |
| 145 | + FROM roleassignment |
| 146 | + WHERE roleassignment.assigneeidentifier IN ( |
| 147 | + SELECT CONCAT('&shib/', persistedglobalgroup.persistedgroupalias) as assignee |
| 148 | + FROM persistedglobalgroup |
| 149 | + WHERE dtype = 'ShibGroup' |
| 150 | + AND EXISTS (SELECT id FROM dataverserole WHERE dataverserole.id = roleassignment.role_id AND (dataverserole.permissionbits & @PERMISSIONBIT !=0)) |
| 151 | + ) |
| 152 | + ) UNION ( |
| 153 | + SELECT definitionpoint_id |
| 154 | + FROM roleassignment |
| 155 | + WHERE roleassignment.assigneeidentifier IN ( |
| 156 | + SELECT CONCAT('&ip/', persistedglobalgroup.persistedgroupalias) as assignee |
| 157 | + FROM persistedglobalgroup |
| 158 | + LEFT OUTER JOIN ipv4range ON persistedglobalgroup.id = ipv4range.owner_id |
| 159 | + LEFT OUTER JOIN ipv6range ON persistedglobalgroup.id = ipv6range.owner_id |
| 160 | + WHERE dtype = 'IpGroup' |
| 161 | + AND EXISTS (SELECT id FROM dataverserole WHERE dataverserole.id = roleassignment.role_id AND (dataverserole.permissionbits & @PERMISSIONBIT !=0)) |
| 162 | + AND @IPRANGESQL |
| 163 | + ) |
| 164 | + ) |
| 165 | + ) |
| 166 | + """; |
103 | 167 | /**
|
104 | 168 | * A request-level permission query (e.g includes IP ras).
|
105 | 169 | */
|
@@ -553,36 +617,6 @@ public RequestPermissionQuery request(DataverseRequest req) {
|
553 | 617 | return new RequestPermissionQuery(null, req);
|
554 | 618 | }
|
555 | 619 |
|
556 |
| - /** |
557 |
| - * Go from (User, Permission) to a list of Dataverse objects that the user |
558 |
| - has the permission on. |
559 |
| - * |
560 |
| - * @param user |
561 |
| - * @param permission |
562 |
| - * @return The list of dataverses {@code user} has permission |
563 |
| - {@code permission} on. |
564 |
| - */ |
565 |
| - public List<Dataverse> getDataversesUserHasPermissionOn(AuthenticatedUser user, Permission permission) { |
566 |
| - Set<Group> groups = groupService.groupsFor(user); |
567 |
| - String identifiers = GroupUtil.getAllIdentifiersForUser(user, groups); |
568 |
| - /** |
569 |
| - * @todo Are there any strings in identifiers that would break this SQL |
570 |
| - * query? |
571 |
| - */ |
572 |
| - String query = "SELECT id FROM dvobject WHERE dtype = 'Dataverse' and id in (select definitionpoint_id from roleassignment where assigneeidentifier in (" + identifiers + "));"; |
573 |
| - logger.log(Level.FINE, "query: {0}", query); |
574 |
| - Query nativeQuery = em.createNativeQuery(query); |
575 |
| - List<Integer> dataverseIdsToCheck = nativeQuery.getResultList(); |
576 |
| - List<Dataverse> dataversesUserHasPermissionOn = new LinkedList<>(); |
577 |
| - for (int dvIdAsInt : dataverseIdsToCheck) { |
578 |
| - Dataverse dataverse = dataverseService.find(Long.valueOf(dvIdAsInt)); |
579 |
| - if (userOn(user, dataverse).has(permission)) { |
580 |
| - dataversesUserHasPermissionOn.add(dataverse); |
581 |
| - } |
582 |
| - } |
583 |
| - return dataversesUserHasPermissionOn; |
584 |
| - } |
585 |
| - |
586 | 620 | public List<AuthenticatedUser> getUsersWithPermissionOn(Permission permission, DvObject dvo) {
|
587 | 621 | List<AuthenticatedUser> usersHasPermissionOn = new LinkedList<>();
|
588 | 622 | Set<RoleAssignment> ras = roleService.rolesAssignments(dvo);
|
@@ -888,4 +922,46 @@ private boolean hasUnrestrictedReleasedFiles(DatasetVersion targetDatasetVersion
|
888 | 922 | Long result = em.createQuery(criteriaQuery).getSingleResult();
|
889 | 923 | return result > 0;
|
890 | 924 | }
|
| 925 | + |
| 926 | + public List<Dataverse> findPermittedCollections(DataverseRequest request, AuthenticatedUser user, Permission permission) { |
| 927 | + return findPermittedCollections(request, user, 1 << permission.ordinal()); |
| 928 | + } |
| 929 | + public List<Dataverse> findPermittedCollections(DataverseRequest request, AuthenticatedUser user, int permissionBit) { |
| 930 | + if (user != null) { |
| 931 | + // IP Group - Only check IP if a User is calling for themself |
| 932 | + String ipRangeSQL = "FALSE"; |
| 933 | + if (request != null |
| 934 | + && request.getAuthenticatedUser() != null |
| 935 | + && request.getSourceAddress() != null |
| 936 | + && request.getAuthenticatedUser().getUserIdentifier().equalsIgnoreCase(user.getUserIdentifier())) { |
| 937 | + IpAddress ip = request.getSourceAddress(); |
| 938 | + if (ip instanceof IPv4Address) { |
| 939 | + IPv4Address ipv4 = (IPv4Address) ip; |
| 940 | + ipRangeSQL = ipv4.toBigInteger() + " BETWEEN ipv4range.bottomaslong AND ipv4range.topaslong"; |
| 941 | + } else if (ip instanceof IPv6Address) { |
| 942 | + IPv6Address ipv6 = (IPv6Address) ip; |
| 943 | + long[] vals = ipv6.toLongArray(); |
| 944 | + if (vals.length == 4) { |
| 945 | + ipRangeSQL = """ |
| 946 | + (@0 BETWEEN ipv6range.bottoma AND ipv6range.topa |
| 947 | + AND @1 BETWEEN ipv6range.bottomb AND ipv6range.topb |
| 948 | + AND @2 BETWEEN ipv6range.bottomc AND ipv6range.topc |
| 949 | + AND @3 BETWEEN ipv6range.bottomd AND ipv6range.topd) |
| 950 | + """; |
| 951 | + for (int i = 0; i < vals.length; i++) { |
| 952 | + ipRangeSQL = ipRangeSQL.replace("@" + i, String.valueOf(vals[i])); |
| 953 | + } |
| 954 | + } |
| 955 | + } |
| 956 | + } |
| 957 | + |
| 958 | + String sqlCode = LIST_ALL_DATAVERSES_USER_HAS_PERMISSION |
| 959 | + .replace("@USERID", String.valueOf(user.getId())) |
| 960 | + .replace("@PERMISSIONBIT", String.valueOf(permissionBit)) |
| 961 | + .replace("@IPRANGESQL", ipRangeSQL); |
| 962 | + return em.createNativeQuery(sqlCode, Dataverse.class).getResultList(); |
| 963 | + } |
| 964 | + return null; |
| 965 | + } |
891 | 966 | }
|
| 967 | + |
0 commit comments