diff --git a/CHANGELOG.md b/CHANGELOG.md index b12f9c7a32..1dca842baf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Refactor JWT Vender to take a claims builder and rename oboEnabled to enabled ([#5436](https://github.com/opensearch-project/security/pull/5436)) * Remove ASN1 reflection methods ([#5454](https://github.com/opensearch-project/security/pull/5454)) * Remove provider reflection code ([#5457](https://github.com/opensearch-project/security/pull/5457)) +* Add tenancy access info to serialized user in threadcontext ([#5519](https://github.com/opensearch-project/security/pull/5519)) ### Maintenance - Bump `org.eclipse.platform:org.eclipse.core.runtime` from 3.33.0 to 3.33.100 ([#5400](https://github.com/opensearch-project/security/pull/5400)) diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java index af5c3c3124..fb94e0900e 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java @@ -117,6 +117,12 @@ public class PrivilegesEvaluator { + private static final String USER_TENANT = "__user__"; + private static final String GLOBAL_TENANT = "global_tenant"; + private static final String READ_ACCESS = "READ"; + private static final String WRITE_ACCESS = "WRITE"; + private static final String NO_ACCESS = "NONE"; + static final WildcardMatcher DNFOF_MATCHER = WildcardMatcher.from( ImmutableList.of( "indices:data/read/*", @@ -278,18 +284,19 @@ public boolean isInitialized() { return configModel != null && dcm != null && actionPrivileges.get() != null; } - private void setUserInfoInThreadContext(User user, Set mappedRoles) { + private void setUserInfoInThreadContext(PrivilegesEvaluationContext context) { if (threadContext.getTransient(OPENDISTRO_SECURITY_USER_INFO_THREAD_CONTEXT) == null) { StringJoiner joiner = new StringJoiner("|"); // Escape any pipe characters in the values before joining - joiner.add(escapePipe(user.getName())); - joiner.add(escapePipe(String.join(",", user.getRoles()))); - joiner.add(escapePipe(String.join(",", mappedRoles))); - - String requestedTenant = user.getRequestedTenant(); - if (!Strings.isNullOrEmpty(requestedTenant)) { - joiner.add(escapePipe(requestedTenant)); - } + joiner.add(escapePipe(context.getUser().getName())); + joiner.add(escapePipe(String.join(",", context.getUser().getRoles()))); + joiner.add(escapePipe(String.join(",", context.getMappedRoles()))); + + String requestedTenant = context.getUser().getRequestedTenant(); + joiner.add(requestedTenant); + String tenantAccessToCheck = getTenancyAccess(context); + joiner.add(tenantAccessToCheck); + log.debug(joiner); threadContext.putTransient(OPENDISTRO_SECURITY_USER_INFO_THREAD_CONTEXT, joiner.toString()); } } @@ -298,6 +305,18 @@ public PrivilegesEvaluationContext createContext(User user, String action) { return createContext(user, action, null, null, null); } + private String getTenancyAccess(PrivilegesEvaluationContext context) { + String requestedTenant = context.getUser().getRequestedTenant(); + final String tenant = Strings.isNullOrEmpty(requestedTenant) ? GLOBAL_TENANT : requestedTenant; + if (tenantPrivileges.get().hasTenantPrivilege(context, tenant, TenantPrivileges.ActionType.WRITE)) { + return WRITE_ACCESS; + } else if (tenantPrivileges.get().hasTenantPrivilege(context, tenant, TenantPrivileges.ActionType.READ)) { + return READ_ACCESS; + } else { + return NO_ACCESS; + } + } + public PrivilegesEvaluationContext createContext( User user, String action0, @@ -387,7 +406,7 @@ public PrivilegesEvaluatorResponse evaluate(PrivilegesEvaluationContext context) context.setMappedRoles(mappedRoles); } - setUserInfoInThreadContext(user, mappedRoles); + setUserInfoInThreadContext(context); final boolean isDebugEnabled = log.isDebugEnabled(); if (isDebugEnabled) {