diff --git a/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt b/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt index ecfd3f26..2490dd0c 100644 --- a/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt +++ b/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt @@ -54,7 +54,14 @@ class SecurityContext { UpdateAutoFollowPatternAction.NAME) fun fromSecurityThreadContext(threadContext: ThreadContext): User? { - val userInfo = threadContext.getTransient(ConfigConstants.OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT) + var userInfo = threadContext.getTransient(ConfigConstants.OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT) + val userObj = threadContext.getTransient(OPENDISTRO_SECURITY_USER) + if(userInfo == null && userObj != null) { + // Case: When admin certs are used, security plugin skips populating the user info in thread context. + // If userObj(obj) is present and userInfo(String) is not populated, assuming admin role for the user and + // only passed role(use_roles) in the request is stored after checks (as admin should have access to all roles) + userInfo = "adminDN|" + } return User.parse(userInfo) } diff --git a/src/test/kotlin/org/opensearch/replication/util/SecurityContextTests.kt b/src/test/kotlin/org/opensearch/replication/util/SecurityContextTests.kt new file mode 100644 index 00000000..aa12840b --- /dev/null +++ b/src/test/kotlin/org/opensearch/replication/util/SecurityContextTests.kt @@ -0,0 +1,40 @@ +package org.opensearch.replication.util + +import org.junit.Assert +import org.junit.Before +import org.opensearch.common.settings.Settings +import org.opensearch.common.util.concurrent.ThreadContext +import org.opensearch.commons.authuser.User +import org.opensearch.test.OpenSearchTestCase + +class SecurityContextTests: OpenSearchTestCase() { + + companion object { + var threadContext: ThreadContext? = null + } + + @Before + fun setupContext() { + threadContext = ThreadContext(Settings.EMPTY) + } + + fun `test security context from ThreadContext with user Info`() { + threadContext!!.putTransient("_opendistro_security_user_info", "admin||all_access") + val expectedUser = User("admin", emptyList(), listOf("all_access"), emptyList()) + val returnedUser = SecurityContext.fromSecurityThreadContext(threadContext!!) + Assert.assertEquals(expectedUser, returnedUser) + } + + fun `test security context from ThreadContext with user Info not present and user obj present`() { + threadContext!!.putTransient("_opendistro_security_user_info", null) + threadContext!!.putTransient("_opendistro_security_user", "") + val expectedUser = User("adminDN", emptyList(), emptyList(), emptyList()) + val returnedUser = SecurityContext.fromSecurityThreadContext(threadContext!!) + Assert.assertEquals(expectedUser, returnedUser) + } + + fun `test security context from ThreadContext with user Info and user obj not present`() { + val returnedUser = SecurityContext.fromSecurityThreadContext(threadContext!!) + Assert.assertNull(returnedUser) + } +}