From 12d8c8c24e1aefc02c35f88f1dadff0039a3106b Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Mon, 12 Aug 2024 16:43:22 -0400 Subject: [PATCH] Expand RoleV7 to include Resources Signed-off-by: Stephen Crawford --- .../privileges/ResourceAccessEvaluator.java | 33 +++++++++++-------- .../security/securityconf/ConfigModelV7.java | 12 ++++--- .../security/securityconf/SecurityRoles.java | 3 +- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/opensearch/security/privileges/ResourceAccessEvaluator.java b/src/main/java/org/opensearch/security/privileges/ResourceAccessEvaluator.java index e9cc958a91..8f6e8ad59b 100644 --- a/src/main/java/org/opensearch/security/privileges/ResourceAccessEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/ResourceAccessEvaluator.java @@ -11,19 +11,24 @@ package org.opensearch.security.privileges; +import java.util.List; import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.OpenSearchSecurityException; +import org.opensearch.action.ActionRequest; +import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.transport.TransportAddress; +import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.securityconf.ConfigModel; import org.opensearch.security.securityconf.SecurityRoles; import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.user.User; +import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.greenrobot.eventbus.Subscribe; @@ -52,7 +57,11 @@ boolean isInitialized() { return configModel != null && configModel.getSecurityRoles() != null; } - public PrivilegesEvaluatorResponse evaluate(final User user, final Set actions) { + public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, + final String action, + final SecurityRoles securityRoles, + final User user, + final ClusterService clusterService) { if (!isInitialized()) { throw new OpenSearchSecurityException("OpenSearch Security is not initialized."); } @@ -64,17 +73,22 @@ public PrivilegesEvaluatorResponse evaluate(final User user, final Set a final Set mappedRoles = mapRoles(user, caller); presponse.resolvedSecurityRoles.addAll(mappedRoles); - final SecurityRoles securityRoles = getSecurityRoles(mappedRoles); final boolean isDebugEnabled = log.isDebugEnabled(); if (isDebugEnabled) { log.debug("Evaluate permissions for {} on {}", user, clusterService.localNode().getName()); - log.debug("Action: {}", actions); + log.debug("Action: {}", action); log.debug("Mapped roles: {}", mappedRoles.toString()); } - for (final String action : actions) { - if (!securityRoles.impliesResourcePermission(action)) { + List resourcesRequested = action.getRequestedResources(); + if (resourcesRequested == null || resourcesRequested.isEmpty()) { + presponse.allowed = true; + return presponse; + } + presponse.allowed = true; + for (String resource : resourcesRequested) { + if (!securityRoles.impliesResourcePermission(resource)) { presponse.missingPrivileges.add(action); presponse.allowed = false; log.info( @@ -84,17 +98,8 @@ public PrivilegesEvaluatorResponse evaluate(final User user, final Set a securityRoles.getRoleNames(), presponse.missingPrivileges ); - } else { - if (isDebugEnabled) { - log.debug("Allowed because we have permissions for {}", actions); - } - presponse.allowed = true; - - // break the loop as we found the matching permission - break; } } - return presponse; } diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java index 0e6143187f..8c833adc1d 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java @@ -506,8 +506,8 @@ public boolean isPermittedOnSystemIndex(String indexName) { } @Override - public boolean impliesResourcePermission(String action0) { - return roles.stream().filter(r -> r.impliesClusterPermission(action0)).count() > 0; + public boolean impliesResourcePermission(String resource) { + return roles.stream().filter(r -> r.impliesClusterPermission(resource)).count() > 0; } } @@ -515,11 +515,13 @@ public static class SecurityRole { private final String name; private final Set ipatterns; private final WildcardMatcher clusterPerms; + private final WildcardMatcher resourcePerms; public static final class Builder { private final String name; private final Set clusterPerms = new HashSet<>(); private final Set ipatterns = new HashSet<>(); + private final Set resourcePerms = new HashSet<>(); public Builder(String name) { this.name = Objects.requireNonNull(name); @@ -538,20 +540,22 @@ public Builder addClusterPerms(Collection clusterPerms) { } public SecurityRole build() { - return new SecurityRole(name, ipatterns, WildcardMatcher.from(clusterPerms)); + return new SecurityRole(name, ipatterns, WildcardMatcher.from(clusterPerms), WildcardMatcher.from(resourcePerms)); } } - private SecurityRole(String name, Set ipatterns, WildcardMatcher clusterPerms) { + private SecurityRole(String name, Set ipatterns, WildcardMatcher clusterPerms, WildcardMatcher resourcePerms) { this.name = Objects.requireNonNull(name); this.ipatterns = ipatterns; this.clusterPerms = clusterPerms; + this.resourcePerms = resourcePerms; } private boolean impliesClusterPermission(String action) { return clusterPerms.test(action); } + // get indices which are permitted for the given types and actions // dnfof + opensearchDashboards special only private Set getAllResolvedPermittedIndices( diff --git a/src/main/java/org/opensearch/security/securityconf/SecurityRoles.java b/src/main/java/org/opensearch/security/securityconf/SecurityRoles.java index 0e1070c6bd..16ae95e9a8 100644 --- a/src/main/java/org/opensearch/security/securityconf/SecurityRoles.java +++ b/src/main/java/org/opensearch/security/securityconf/SecurityRoles.java @@ -29,6 +29,7 @@ import java.util.Set; +import org.opensearch.action.ActionRequest; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.service.ClusterService; import org.opensearch.core.xcontent.NamedXContentRegistry; @@ -99,5 +100,5 @@ Set getAllPermittedIndicesForDashboards( boolean isPermittedOnSystemIndex(String indexName); - boolean impliesResourcePermission(String action0); + boolean impliesResourcePermission(String resource); }