-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviews.apache.org/r/75252/#review227013
-----------------------------------------------------------




agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGds.java
Lines 891 (patched)
<https://reviews.apache.org/r/75252/#comment315282>

    This class can be used to update non-GDS policies as well in future. So, 
please rename RangerGdsGrant => RangerGrant; and move this class to its own 
file, RangerGrant.java.



agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGds.java
Lines 894 (patched)
<https://reviews.apache.org/r/75252/#comment315280>

    I suggest replacing principalType and principalName with:
    
      private RangerPrincipal principal;



agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyHeader.java
Lines 39 (patched)
<https://reviews.apache.org/r/75252/#comment315281>

    Following fields should be added as well:
    - zoneName
    - policyType



security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
Lines 1944 (patched)
<https://reviews.apache.org/r/75252/#comment315283>

    Consider moving rangerPolicy insider the 'if' block at #1954, as it is not 
used outside this block.



security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
Lines 1976 (patched)
<https://reviews.apache.org/r/75252/#comment315284>

    Consider having a single return for a method:
    
    {
      List<RangerPolicyItem> ret = rangerPolicy == null ? null : 
rangerPolicy.getPolicyItems();
    
      if (CollectionUtils.isNotEmpty(ret)) {
        String[] principals  = searchUtil.getParamMultiValues(request, 
"principal");
        String[] accessTypes = searchUtil.getParamMultiValues(request, 
"accessType");
    
        if (ArrayUtils.isNotEmpty(principals) || 
ArrayUtils.isNotEmpty(accessTypes)) {
          PolicyItemPredicate pred = new PolicyItemPredicate(principals, 
accessTypes);
        
          ret = ret.streams().filter(pred).collect(Collectors.toList()); 
        }
      }
    
      return ret;
    }
    
    private static class PolicyItemPredicate implements 
Predicate<RangerPolicyItem> {
      private final Set<String> users;
      private final Set<String> groups;
      private final Set<String> roles;
      private final Set<String> accessTypes;
      private final boolean     hasPrincipalFilter;
    
      public PolicyItemPredicate(String[] principals, String[] accessTypes) {
        if (ArrayUtils.isNotEmpty(principals)) {
          this.users  = new HashSet<>();
          this.groups = new HashSet<>();
          this.roles  = new HashSet<>();
    
          for (String principal : principals) {
            if (principal.startsWith("u:")) {
              this.users.add(principal.substring("u:".length()));
            } else if (principal.startsWith("g:")) {
              this.groups.add(principal.substring("g:".length()));
            } else if (principal.startsWith("r:")) {
              this.roles.add(principal.substring("r:".length()));
            } else {
              this.users.add(principal);
            }
          }
        } else {
          this.users  = Collections.emptySet();
          this.groups = Collections.emptySet();
          this.roles  = Collections.emptySet();
        }
    
        this.hasPrincipalFilter = !this.users.isEmpty() || !groups.isEmpty() || 
!roles.isEmpty();
        this.accessTypes        = ArrayUtils.isNotEmpty(accessTypes) ? new 
HashSet<>(Arrays.asList(accessTypes)) : Collections.emptySet();
      }
    
      @Override
      public boolean test(RangerPolicyItem policyItem) {
        boolean ret = accessTypes.isEmpty() || (policyItem.getAccesses() != 
null && policyItem.getAccesses().stream().anyMatch(access -> 
accessTypes.contains(access.getType())));
    
        if (ret) {
          ret = (policyItem.getUsers() != null && 
policyItem.getUsers().stream().anyMatch(this::matchUser)) ||
                (policyItem.getGroups() != null && 
policyItem.getGroups().stream().anyMatch(this::matchGroup)) ||
                (policyItem.getRoles() != null && 
policyItem.getRoles().stream().anyMatch(this::matchRole));
        }
    
        return ret;
      }
    
      public Set<String> getUsers() { return users; }
    
      public Set<String> getGroups() { return groups; }
    
      public Set<String> getRoles() { return roles; }
    
      public Set<String> getAccessTypes() { return accessTypes; }
    
      public boolean hasPrincipalFilter() { return hasPrincipalFilter; }
    
      @Override
      public boolean test(RangerPolicyItem policyItem) {
        boolean ret = accessTypes.isEmpty() || hasAccessType(policyItem);
    
        if (ret && hasPrincipalFilter) {
          ret = (policyItem.getUsers() != null && 
policyItem.getUsers().stream().anyMatch(users::contains)) ||
                (policyItem.getGroups() != null && 
policyItem.getGroups().stream().anyMatch(groups::contains)) ||
                (policyItem.getRoles() != null && 
policyItem.getRoles().stream().anyMatch(roles::contains));
        }
    
        return ret;
      }
    
      public boolean hasAccessType(RangerPolicyItem policyItem) {
        return policyItem.getAccesses() != null && 
policyItem.getAccesses().stream().anyMatch(access -> 
accessTypes.contains(access.getType()));
      }
    }



security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
Lines 2054 (patched)
<https://reviews.apache.org/r/75252/#comment315285>

    Consider leveraging PolicyItemPredicate suggested earlier to simplify this 
method, along the following lines:
    
    private List<RangerGdsGrant> 
transformPolicyItemsToGdsGrants(List<RangerPolicyItem> policyItems, 
PolicyItemPredicate pred) {
      List<RangerGrant> ret = new ArrayList<RangerGrant>();
    
      for (RangerPolicyItem policyItem : policyItems) {
        if (!pred.getAccessTypes().isEmpty() && 
!pred.hasAccessType(policyItem)) {
          continue;
        }
    
        if (policyItem.getUsers() != null) {
          policyItem.getUsers().stream().filter(user -> 
!pred.hasPrincipalFilter() || pred.getUsers().contains(user)).forEach(user -> 
ret.add(new RangerGrant(PrincipalType.USER, user, policyItem.getAccesses(), 
policyItem.getConditions())));
        }
    
        if (policyItem.getGroups() != null) {
          policyItem.getGroups().stream().filter(group -> 
!pred.hasPrincipalFilter() || pred.getGroups().contains(group)).forEach(group 
-> ret.add(new RangerGrant(PrincipalType.GROUP, group, 
policyItem.getAccesses(), policyItem.getConditions())));
        }
    
        if (policyItem.getRoles() != null) {
          policyItem.getRoles().stream().filter(role -> 
!pred.hasPrincipalFilter() || pred.getRoles().contains(role)).forEach(role -> 
ret.add(new RangerGrant(PrincipalType.ROLE, role, policyItem.getAccesses(), 
policyItem.getConditions())));
        }
      }
       
      return ret;
    }


- Madhan Neethiraj


On Oct. 31, 2024, 7:36 p.m., Radhika Kundam wrote:
> 
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://reviews.apache.org/r/75252/
> -----------------------------------------------------------
> 
> (Updated Oct. 31, 2024, 7:36 p.m.)
> 
> 
> Review request for ranger, Madhan Neethiraj and Ramesh Mani.
> 
> 
> Bugs: RANGER-4960
>     https://issues.apache.org/jira/browse/RANGER-4960
> 
> 
> Repository: ranger
> 
> 
> Description
> -------
> 
> This Grant API introduces functionality to grant or revoke specific 
> permissions on datasets to external users, groups, or roles. It includes 
> support for defining access validity based on policy item conditions. 
> 
> Key features include:
> 1. Permission Management: Enables granting and revoking access to datasets 
> for designated users, groups, or roles.
> 2. Policy-Based Validity: Allows setting validity periods and conditions 
> within policy items, defining the scope and duration of access for each user, 
> group, or role.
> 
> This API enhancement provides flexibility in managing dataset permissions, 
> improving security and control over data access.
> 
> Attached file for Grant API UseCases.
> 
> Detailed information about Grant API request and response attached to Jira.
> 
> 
> Diffs
> -----
> 
>   agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGds.java 
> 68216fd45 
>   
> agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyHeader.java
>  PRE-CREATION 
>   security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java 
> a6c6746b3 
>   security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java c66429834 
>   
> security-admin/src/main/java/org/apache/ranger/security/context/RangerAPIList.java
>  acfce5f0a 
> 
> 
> Diff: https://reviews.apache.org/r/75252/diff/1/
> 
> 
> Testing
> -------
> 
> Tested locally.
> 
> 
> File Attachments
> ----------------
> 
> Grant API UseCases
>   
> https://reviews.apache.org/media/uploaded/files/2024/10/31/9e0f7209-36b8-4779-9336-63052015a117__Grant_API_UseCases.pdf
> 
> 
> Thanks,
> 
> Radhika Kundam
> 
>

Reply via email to