浏览代码

Service Accounts - ensure SetSecurityUserProcessTests work for service accounts (#71669)

This PR ensures the tests for SetSecurityUserProcessor work for service accounts. 
Note it only makes sure existing tags work. Any new tags, e.g. token name, necessary 
for service accounts will be handled in a separate PR.
Yang Wang 4 年之前
父节点
当前提交
a642cb3945

+ 107 - 43
x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java

@@ -7,6 +7,7 @@
 package org.elasticsearch.xpack.security.ingest;
 package org.elasticsearch.xpack.security.ingest;
 
 
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
+import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
 import org.elasticsearch.ingest.IngestDocument;
 import org.elasticsearch.ingest.IngestDocument;
@@ -16,6 +17,7 @@ import org.elasticsearch.xpack.core.security.SecurityContext;
 import org.elasticsearch.xpack.core.security.authc.Authentication;
 import org.elasticsearch.xpack.core.security.authc.Authentication;
 import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
 import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
 import org.elasticsearch.xpack.core.security.authc.support.AuthenticationContextSerializer;
 import org.elasticsearch.xpack.core.security.authc.support.AuthenticationContextSerializer;
+import org.elasticsearch.xpack.core.security.support.ValidationTests;
 import org.elasticsearch.xpack.core.security.user.User;
 import org.elasticsearch.xpack.core.security.user.User;
 import org.elasticsearch.xpack.security.authc.ApiKeyService;
 import org.elasticsearch.xpack.security.authc.ApiKeyService;
 import org.elasticsearch.xpack.security.ingest.SetSecurityUserProcessor.Property;
 import org.elasticsearch.xpack.security.ingest.SetSecurityUserProcessor.Property;
@@ -29,6 +31,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 
 
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.not;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.when;
 
 
 public class SetSecurityUserProcessorTests extends ESTestCase {
 public class SetSecurityUserProcessorTests extends ESTestCase {
@@ -46,10 +50,8 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
     }
     }
 
 
     public void testProcessorWithData() throws Exception {
     public void testProcessorWithData() throws Exception {
-        User user = new User("_username", new String[] { "role1", "role2" }, "firstname lastname", "_email",
-            Map.of("key", "value"), true);
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null, Version.CURRENT).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
@@ -57,16 +59,27 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
         processor.execute(ingestDocument);
         processor.execute(ingestDocument);
 
 
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
-        assertThat(result.size(), equalTo(7));
-        assertThat(result.get("username"), equalTo("_username"));
-        assertThat(result.get("roles"), equalTo(Arrays.asList("role1", "role2")));
-        assertThat(result.get("full_name"), equalTo("firstname lastname"));
-        assertThat(result.get("email"), equalTo("_email"));
-        assertThat(((Map) result.get("metadata")).size(), equalTo(1));
-        assertThat(((Map) result.get("metadata")).get("key"), equalTo("value"));
-        assertThat(((Map) result.get("realm")).get("name"), equalTo("_name"));
-        assertThat(((Map) result.get("realm")).get("type"), equalTo("_type"));
-        assertThat(result.get("authentication_type"), equalTo("REALM"));
+        if (authentication.getUser().fullName().startsWith("Service account - ")) {
+            assertThat(result, not(hasKey("roles")));
+            assertThat(result, not(hasKey("email")));
+        } else {
+            assertThat(result.get("email"), equalTo(authentication.getUser().email()));
+            if (authentication.getUser().roles().length == 0) {
+                assertThat(result, not(hasKey("roles")));
+            } else {
+                assertThat(result.get("roles"), equalTo(Arrays.asList(authentication.getUser().roles())));
+            }
+        }
+        if (authentication.getUser().metadata().isEmpty()) {
+            assertThat(result, not(hasKey("metadata")));
+        } else {
+            assertThat(result.get("metadata"), equalTo(authentication.getUser().metadata()));
+        }
+        assertThat(result.get("username"), equalTo(authentication.getUser().principal()));
+        assertThat(result.get("full_name"), equalTo(authentication.getUser().fullName()));
+        assertThat(((Map) result.get("realm")).get("name"), equalTo(authentication.getSourceRealm().getName()));
+        assertThat(((Map) result.get("realm")).get("type"), equalTo(authentication.getSourceRealm().getType()));
+        assertThat(result.get("authentication_type"), equalTo(authentication.getAuthenticationType().toString()));
     }
     }
 
 
     public void testProcessorWithEmptyUserData() throws Exception {
     public void testProcessorWithEmptyUserData() throws Exception {
@@ -113,9 +126,8 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
     }
     }
 
 
     public void testUsernameProperties() throws Exception {
     public void testUsernameProperties() throws Exception {
-        User user = new User("_username", null, null);
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
@@ -125,13 +137,12 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         assertThat(result.size(), equalTo(1));
         assertThat(result.size(), equalTo(1));
-        assertThat(result.get("username"), equalTo("_username"));
+        assertThat(result.get("username"), equalTo(authentication.getUser().principal()));
     }
     }
 
 
     public void testRolesProperties() throws Exception {
     public void testRolesProperties() throws Exception {
-        User user = new User(randomAlphaOfLengthBetween(4, 12), "role1", "role2");
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
@@ -140,14 +151,17 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
 
 
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
-        assertThat(result.size(), equalTo(1));
-        assertThat(result.get("roles"), equalTo(Arrays.asList("role1", "role2")));
+        if (authentication.getUser().roles().length == 0) {
+            assertThat(result, not(hasKey("roles")));
+        } else {
+            assertThat(result.size(), equalTo(1));
+            assertThat(result.get("roles"), equalTo(Arrays.asList(authentication.getUser().roles())));
+        }
     }
     }
 
 
     public void testFullNameProperties() throws Exception {
     public void testFullNameProperties() throws Exception {
-        User user = new User(randomAlphaOfLengthBetween(4, 12), null, "_full_name", null, Map.of(), true);
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         SetSecurityUserProcessor processor
         SetSecurityUserProcessor processor
@@ -157,13 +171,12 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         assertThat(result.size(), equalTo(1));
         assertThat(result.size(), equalTo(1));
-        assertThat(result.get("full_name"), equalTo("_full_name"));
+        assertThat(result.get("full_name"), equalTo(authentication.getUser().fullName()));
     }
     }
 
 
     public void testEmailProperties() throws Exception {
     public void testEmailProperties() throws Exception {
-        User user = new User(randomAlphaOfLengthBetween(4, 12), null, null, "_email", Map.of(), true);
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
@@ -172,14 +185,17 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
 
 
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
-        assertThat(result.size(), equalTo(1));
-        assertThat(result.get("email"), equalTo("_email"));
+        if (authentication.getUser().email() != null) {
+            assertThat(result.size(), equalTo(1));
+            assertThat(result.get("email"), equalTo(authentication.getUser().email()));
+        } else {
+            assertThat(result, not(hasKey("email")));
+        }
     }
     }
 
 
     public void testMetadataProperties() throws Exception {
     public void testMetadataProperties() throws Exception {
-        User user = new User(randomAlphaOfLengthBetween(4, 12), null, null, null, Map.of("key", "value"), true);
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         IngestDocument ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
@@ -188,15 +204,17 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
 
 
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
-        assertThat(result.size(), equalTo(1));
-        assertThat(((Map) result.get("metadata")).size(), equalTo(1));
-        assertThat(((Map) result.get("metadata")).get("key"), equalTo("value"));
+        if (authentication.getUser().metadata().isEmpty()) {
+            assertThat(result, not(hasKey("metadata")));
+        } else {
+            assertThat(result.size(), equalTo(1));
+            assertThat(result.get("metadata"), equalTo(authentication.getUser().metadata()));
+        }
     }
     }
 
 
     public void testOverwriteExistingField() throws Exception {
     public void testOverwriteExistingField() throws Exception {
-        User user = new User("_username", null, null);
-        Authentication.RealmRef realmRef = new Authentication.RealmRef("_name", "_type", "_node_name");
-        new Authentication(user, realmRef, null).writeToContext(threadContext);
+        final Authentication authentication = randomAuthentication();
+        authentication.writeToContext(threadContext);
 
 
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
         SetSecurityUserProcessor processor = new SetSecurityUserProcessor(
             "_tag", null, securityContext, licenseState, "_field", EnumSet.of(Property.USERNAME));
             "_tag", null, securityContext, licenseState, "_field", EnumSet.of(Property.USERNAME));
@@ -208,7 +226,7 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result = ingestDocument.getFieldValue("_field", Map.class);
         assertThat(result.size(), equalTo(1));
         assertThat(result.size(), equalTo(1));
-        assertThat(result.get("username"), equalTo("_username"));
+        assertThat(result.get("username"), equalTo(authentication.getUser().principal()));
 
 
         ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         ingestDocument = new IngestDocument(new HashMap<>(), new HashMap<>());
         ingestDocument.setFieldValue("_field.other", "test");
         ingestDocument.setFieldValue("_field.other", "test");
@@ -218,7 +236,7 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         Map<String, Object> result2 = ingestDocument.getFieldValue("_field", Map.class);
         Map<String, Object> result2 = ingestDocument.getFieldValue("_field", Map.class);
         assertThat(result2.size(), equalTo(2));
         assertThat(result2.size(), equalTo(2));
-        assertThat(result2.get("username"), equalTo("_username"));
+        assertThat(result2.get("username"), equalTo(authentication.getUser().principal()));
         assertThat(result2.get("other"), equalTo("test"));
         assertThat(result2.get("other"), equalTo("test"));
     }
     }
 
 
@@ -302,4 +320,50 @@ public class SetSecurityUserProcessorTests extends ESTestCase {
         assertThat(((Map) result.get("realm")).get("type"), equalTo(lookedUpRealmRef.getType()));
         assertThat(((Map) result.get("realm")).get("type"), equalTo(lookedUpRealmRef.getType()));
     }
     }
 
 
+    private User randomUser() {
+        final User user = doRandomUser();
+        if (false == user.fullName().startsWith("Service account - ") && randomBoolean()) {
+            return new User(user, doRandomUser());
+        } else {
+            return user;
+        }
+    }
+
+    private User doRandomUser() {
+        if (randomIntBetween(0, 2) < 2) {
+            return new User(randomAlphaOfLengthBetween(3, 8),
+                randomArray(1, 3, String[]::new, () -> randomAlphaOfLengthBetween(3, 8)),
+                randomAlphaOfLengthBetween(5, 20), randomAlphaOfLengthBetween(8, 20),
+                randomFrom(Map.of(), Map.of("key", "value")), true);
+        } else {
+            final String principal = randomAlphaOfLengthBetween(3, 8) + "/" + randomAlphaOfLengthBetween(3, 8);
+            return new User(principal, Strings.EMPTY_ARRAY, "Service account - " + principal, null,
+                randomFrom(Map.of(), Map.of("_elastic_service_account", true)), true);
+        }
+    }
+
+    private Authentication randomAuthentication() {
+        final User user = randomUser();
+        if (user.fullName().startsWith("Service account - ")) {
+            assert false == user.isRunAs() : "cannot run-as service account";
+            final Authentication.RealmRef authBy =
+                new Authentication.RealmRef("service_account", "service_account", randomAlphaOfLengthBetween(3, 8));
+            return new Authentication(user, authBy, null, Version.CURRENT, AuthenticationType.TOKEN,
+                Map.of("_token_name", ValidationTests.randomTokenName()));
+        } else {
+            final Authentication.RealmRef lookupBy;
+            final String nodeName = randomAlphaOfLengthBetween(3, 8);
+            if (user.isRunAs()) {
+                lookupBy = new Authentication.RealmRef(randomAlphaOfLengthBetween(3, 8), randomAlphaOfLengthBetween(3, 8), nodeName);
+            } else {
+                lookupBy = null;
+            }
+            final Authentication.RealmRef authBy =
+                new Authentication.RealmRef(randomAlphaOfLengthBetween(3, 8), randomAlphaOfLengthBetween(3, 8), nodeName);
+            final AuthenticationType authenticationType = user.isRunAs() ? AuthenticationType.REALM
+                : randomFrom(AuthenticationType.REALM, AuthenticationType.INTERNAL, AuthenticationType.TOKEN, AuthenticationType.ANONYMOUS);
+            final Map<String, Object> metadata = user.isRunAs() ? Map.of() : randomFrom(Map.of(), Map.of("foo", "bar"));
+            return new Authentication(user, authBy, lookupBy, Version.CURRENT, authenticationType, metadata);
+        }
+    }
 }
 }