Skip to content

Commit

Permalink
Expand RoleV7 to include Resources
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Crawford <[email protected]>
  • Loading branch information
stephen-crawford committed Aug 12, 2024
1 parent 59df3df commit 12d8c8c
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -52,7 +57,11 @@ boolean isInitialized() {
return configModel != null && configModel.getSecurityRoles() != null;
}

public PrivilegesEvaluatorResponse evaluate(final User user, final Set<String> 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.");
}
Expand All @@ -64,17 +73,22 @@ public PrivilegesEvaluatorResponse evaluate(final User user, final Set<String> a
final Set<String> 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<String> 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(
Expand All @@ -84,17 +98,8 @@ public PrivilegesEvaluatorResponse evaluate(final User user, final Set<String> 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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,20 +506,22 @@ 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;
}
}

public static class SecurityRole {
private final String name;
private final Set<IndexPattern> ipatterns;
private final WildcardMatcher clusterPerms;
private final WildcardMatcher resourcePerms;

public static final class Builder {
private final String name;
private final Set<String> clusterPerms = new HashSet<>();
private final Set<IndexPattern> ipatterns = new HashSet<>();
private final Set<String> resourcePerms = new HashSet<>();

public Builder(String name) {
this.name = Objects.requireNonNull(name);
Expand All @@ -538,20 +540,22 @@ public Builder addClusterPerms(Collection<String> 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<IndexPattern> ipatterns, WildcardMatcher clusterPerms) {
private SecurityRole(String name, Set<IndexPattern> 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<String> getAllResolvedPermittedIndices(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -99,5 +100,5 @@ Set<String> getAllPermittedIndicesForDashboards(

boolean isPermittedOnSystemIndex(String indexName);

boolean impliesResourcePermission(String action0);
boolean impliesResourcePermission(String resource);
}

0 comments on commit 12d8c8c

Please sign in to comment.