From 988b707055c97f36fb10471d2f085e0520549921 Mon Sep 17 00:00:00 2001
From: "opensearch-trigger-bot[bot]"
 <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com>
Date: Tue, 14 Nov 2023 08:18:06 -0800
Subject: [PATCH] Add User.isAdminDn to User class (#547) (#562)

* Add User.isSuperUser to User class



* Add null check



* Add another test



* Make method non-static and require a user to exist to call method



* Change to isAdminDn



---------



(cherry picked from commit 107be59161db84cf22d4478586d3008eab4cdfb3)

Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <craig5008@gmail.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Signed-off-by: AWSHurneyt <hurneyt@amazon.com>
---
 .../opensearch/commons/ConfigConstants.java   |  2 +
 .../org/opensearch/commons/authuser/User.java | 11 +++++
 .../opensearch/commons/authuser/UserTest.java | 44 +++++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/src/main/java/org/opensearch/commons/ConfigConstants.java b/src/main/java/org/opensearch/commons/ConfigConstants.java
index 6fc6e362..a34f7e2f 100644
--- a/src/main/java/org/opensearch/commons/ConfigConstants.java
+++ b/src/main/java/org/opensearch/commons/ConfigConstants.java
@@ -25,5 +25,7 @@ public class ConfigConstants {
     public static final String INJECTED_USER = "injected_user";
     public static final String OPENSEARCH_SECURITY_USE_INJECTED_USER_FOR_PLUGINS = "plugins.security_use_injected_user_for_plugins";
     public static final String OPENSEARCH_SECURITY_SSL_HTTP_ENABLED = "plugins.security.ssl.http.enabled";
+    public static final String OPENSEARCH_SECURITY_AUTHCZ_ADMIN_DN = "plugins.security.authcz.admin_dn";
     public static final String OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT = "_opendistro_security_user_info";
+
 }
diff --git a/src/main/java/org/opensearch/commons/authuser/User.java b/src/main/java/org/opensearch/commons/authuser/User.java
index ff40e243..a203b33d 100644
--- a/src/main/java/org/opensearch/commons/authuser/User.java
+++ b/src/main/java/org/opensearch/commons/authuser/User.java
@@ -10,6 +10,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -18,8 +19,10 @@
 import org.opensearch.client.Response;
 import org.opensearch.common.Nullable;
 import org.opensearch.common.inject.internal.ToStringBuilder;
+import org.opensearch.common.settings.Settings;
 import org.opensearch.common.xcontent.XContentHelper;
 import org.opensearch.common.xcontent.json.JsonXContent;
+import org.opensearch.commons.ConfigConstants;
 import org.opensearch.core.common.Strings;
 import org.opensearch.core.common.io.stream.StreamInput;
 import org.opensearch.core.common.io.stream.StreamOutput;
@@ -249,4 +252,12 @@ public List<String> getCustomAttNames() {
     public String getRequestedTenant() {
         return requestedTenant;
     }
+
+    public boolean isAdminDn(Settings settings) {
+        if (settings == null) {
+            return false;
+        }
+        List<String> adminDns = settings.getAsList(ConfigConstants.OPENSEARCH_SECURITY_AUTHCZ_ADMIN_DN, Collections.emptyList());
+        return adminDns.contains(this.name);
+    }
 }
diff --git a/src/test/java/org/opensearch/commons/authuser/UserTest.java b/src/test/java/org/opensearch/commons/authuser/UserTest.java
index 56152477..df4e6602 100644
--- a/src/test/java/org/opensearch/commons/authuser/UserTest.java
+++ b/src/test/java/org/opensearch/commons/authuser/UserTest.java
@@ -13,11 +13,13 @@
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.List;
 
 import org.junit.jupiter.api.Test;
 import org.opensearch.common.io.stream.BytesStreamOutput;
 import org.opensearch.common.settings.Settings;
 import org.opensearch.common.util.concurrent.ThreadContext;
+import org.opensearch.commons.ConfigConstants;
 import org.opensearch.core.common.Strings;
 import org.opensearch.core.common.io.stream.StreamInput;
 
@@ -202,4 +204,46 @@ public void testParseUserStringMalformed() {
         User user = User.parse(str);
         assertNull(user);
     }
+
+    @Test
+    public void testUserIsAdminDnTrue() {
+        Settings settings = Settings
+            .builder()
+            .putList(ConfigConstants.OPENSEARCH_SECURITY_AUTHCZ_ADMIN_DN, List.of("CN=kirk,OU=client,O=client,L=test, C=de"))
+            .build();
+        ThreadContext tc = new ThreadContext(Settings.EMPTY);
+        tc
+            .putTransient(
+                OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT,
+                "CN=kirk,OU=client,O=client,L=test, C=de|backendrole1,backendrole2|role1,role2"
+            );
+        String str = tc.getTransient(OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT);
+        User user = User.parse(str);
+        assertTrue(user.isAdminDn(settings));
+    }
+
+    @Test
+    public void testUserIsAdminDnFalse() {
+        Settings settings = Settings
+            .builder()
+            .putList(ConfigConstants.OPENSEARCH_SECURITY_AUTHCZ_ADMIN_DN, List.of("CN=spock,OU=client,O=client,L=test, C=de"))
+            .build();
+        ThreadContext tc = new ThreadContext(Settings.EMPTY);
+        tc
+            .putTransient(
+                OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT,
+                "CN=kirk,OU=client,O=client,L=test, C=de|backendrole1,backendrole2|role1,role2"
+            );
+        String str = tc.getTransient(OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT);
+        User user = User.parse(str);
+        assertFalse(user.isAdminDn(settings));
+    }
+
+    @Test
+    public void testUserOrSettingsAreNullOrEmpty() {
+        Settings settings = Settings.EMPTY;
+        User user = User.parse("username|backend_role1|role1");
+        assertFalse(user.isAdminDn(null));
+        assertFalse(user.isAdminDn(settings));
+    }
 }