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 9e62096 commit 13262cd
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 0 deletions.
130 changes: 130 additions & 0 deletions src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.opensearch.security.securityconf.impl.v7.RoleMappingsV7;
import org.opensearch.security.securityconf.impl.v7.RoleV7;
import org.opensearch.security.securityconf.impl.v7.RoleV7.Index;
import org.opensearch.security.securityconf.impl.v7.RoleV7.Resource;
import org.opensearch.security.securityconf.impl.v7.TenantV7;
import org.opensearch.security.support.ConfigConstants;
import org.opensearch.security.support.WildcardMatcher;
Expand Down Expand Up @@ -179,6 +180,16 @@ public SecurityRole call() throws Exception {

}

for (final Resource permittedResourceAliases : securityRole.getValue().getResource_permissions()) {

for (String resourcePattern : permittedResourceAliases.getResource_patterns()) {
ResourcePattern _resourcePattern = new ResourcePattern(resourcePattern);
_resourcePattern.addPerm(actionGroups.resolve(permittedResourceAliases.getAllowed_actions()));

_securityRole.addResourcePattern(_resourcePattern);
}
}

return _securityRole.build();
}
});
Expand Down Expand Up @@ -912,6 +923,125 @@ public Set<String> getPerms() {
}*/

public static class ResourcePattern {
private final String resourcePattern;
private final Set<String> perms = new HashSet<>();

public ResourcePattern(String resourcePattern) {
super();
this.resourcePattern = Objects.requireNonNull(resourcePattern);
}

public ResourcePattern addPerm(Set<String> perms) {
if (perms != null) {
this.perms.addAll(perms);
}
return this;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((resourcePattern == null) ? 0 : resourcePattern.hashCode());
result = prime * result + ((perms == null) ? 0 : perms.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ResourcePattern other = (ResourcePattern) obj;
if (resourcePattern == null) {
if (other.resourcePattern != null) return false;
} else if (!resourcePattern.equals(other.resourcePattern)) return false;
if (perms == null) {
if (other.perms != null) return false;
} else if (!perms.equals(other.perms)) return false;
return true;
}

@Override
public String toString() {
return System.lineSeparator()
+ " resourcePattern="
+ resourcePattern
+ System.lineSeparator()
+ " perms="
+ perms;
}

public String getUnresolvedResourcePattern(User user) {
return UserAttributes.replaceProperties(resourcePattern, user);
}

/** Finds the resources accessible to the user and resolves them to concrete names */
public Set<String> concreteResourceNames(final User user, final ResourceNameExpressionResolver resolver, final ClusterService cs) {
return getResolvedResourcePattern(user, resolver, cs, false);
}

/** Finds the resources accessible to the user and attempts to resolve them to names, also includes any unresolved names */
public Set<String> attemptResolveIndexNames(final User user, final ResourceNameExpressionResolver resolver, final ClusterService cs) {
return getResolvedResourcePattern(user, resolver, cs, true);
}


public Set<String> getResolvedResourcePattern(
final User user,
final ResourceNameExpressionResolver resolver,
final ClusterService cs,
final boolean appendUnresolved
) {
final String unresolved = getUnresolvedResourcePattern(user);
final ImmutableSet.Builder<String> resolvedResources = new ImmutableSet.Builder<>();

final WildcardMatcher matcher = WildcardMatcher.from(unresolved);
boolean includeDataStreams = true;
if (!(matcher instanceof WildcardMatcher.Exact)) {
final String[] aliasesAndDataStreamsForPermittedPattern = cs.state()
.getMetadata()
.getResourcesLookup()
.entrySet()
.stream()
.filter(e -> (e.getValue().getType() == ALIAS) || (e.getValue().getType() == DATA_STREAM))
.filter(e -> matcher.test(e.getKey()))
.map(e -> e.getKey())
.toArray(String[]::new);
if (aliasesAndDataStreamsForPermittedPattern.length > 0) {
final String[] resolvedAliasesAndDataStreamResources = resolver.concreteResourceNames(
cs.state(),
ResourceOptions.lenientExpandOpen(),
includeDataStreams,
aliasesAndDataStreamsForPermittedPattern
);
resolvedResources.addAll(Arrays.asList(resolvedAliasesAndDataStreamResources));
}
}

if (Strings.isNotBlank(unresolved)) {
final String[] resolvedResourcesFromPattern = resolver.concreteResourceNames(
cs.state(),
ResourceOptions.lenientExpandOpen(),
includeDataStreams,
unresolved
);
resolvedResources.addAll(Arrays.asList(resolvedResourcesFromPattern));
}

if (appendUnresolved || resolvedResources.build().isEmpty()) {
resolvedResources.add(unresolved);
}
return resolvedResources.build();
}

public WildcardMatcher getPerms() {
return WildcardMatcher.from(perms);
}

}

public static class Tenant {
private final String tenant;
private final boolean readWrite;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
Expand All @@ -51,6 +52,7 @@ public class RoleV7 implements Hideable, StaticDefinable {
private List<String> cluster_permissions = Collections.emptyList();
private List<Index> index_permissions = Collections.emptyList();
private List<Tenant> tenant_permissions = Collections.emptyList();
private List<Resource> resource_permissions = Collections.emptyList();

public RoleV7() {

Expand All @@ -63,6 +65,7 @@ public RoleV7(RoleV6 roleV6) {
this.cluster_permissions = roleV6.getCluster();
index_permissions = new ArrayList<>();
tenant_permissions = new ArrayList<>();
resource_permissions = new ArrayList<>();

for (Entry<String, RoleV6.Index> v6i : roleV6.getIndices().entrySet()) {
index_permissions.add(new Index(v6i.getKey(), v6i.getValue()));
Expand Down Expand Up @@ -225,6 +228,57 @@ public String toString() {

}

public static class Resource {

private String uniqueId;
private List<String> resource_patterns;
private Date lastModifiedAt;
private List<String> allowed_actions = Collections.emptyList();

public Resource(String resourceName, List<String> resourcePattern) {
super();
uniqueId = resourceName;
lastModifiedAt = new Date();
Set<String> tmpActions = new HashSet<>();
resource_patterns = resourcePattern;
allowed_actions = new ArrayList<>(tmpActions);
}

public Resource() {
super();
}

public List<String> getAllowed_actions() {
return allowed_actions;
}

public void setAllowed_actions(List<String> allowed_actions) {
lastModifiedAt = new Date();
this.allowed_actions = allowed_actions;
}

public List<String> getResource_patterns() {
return resource_patterns;
}

public void setResource_patterns(List<String> resource_patterns) {
this.resource_patterns = resource_patterns;
}

@Override
public String toString() {
return "Resource [uniqueId="
+ uniqueId
+ ", lastModifiedAt="
+ lastModifiedAt
+ ", resource_patterns="
+ resource_patterns
+ ", allowed_actions="
+ allowed_actions
+ "]";
}
}

public boolean isHidden() {
return hidden;
}
Expand Down Expand Up @@ -265,6 +319,14 @@ public void setTenant_permissions(List<Tenant> tenant_permissions) {
this.tenant_permissions = tenant_permissions;
}

public List<Resource> getResource_permissions() {
return resource_permissions;
}

public void setResource_permissions(List<Resource> resource_permissions) {
this.resource_permissions = resource_permissions;
}

public boolean isReserved() {
return reserved;
}
Expand Down

0 comments on commit 13262cd

Please sign in to comment.