From 7faaffef30b7e76ea18e237714ea8ea104f5a083 Mon Sep 17 00:00:00 2001 From: Michael Edgar Date: Fri, 20 Dec 2024 10:00:54 -0500 Subject: [PATCH] refactor: rename Audit to Decision, add KafkaSecurityConfig type (#1315) Signed-off-by: Michael Edgar --- .../ConsoleAuthenticationMechanism.java | 10 +++++----- .../api/KafkaRebalancesResourceOidcIT.java | 10 +++++----- .../console/api/TopicsResourceIT.java | 8 ++++---- .../console/api/TopicsResourceOidcIT.java | 18 +++++++++--------- .../console/config/ConsoleConfig.java | 4 ++-- .../console/config/KafkaClusterConfig.java | 8 ++++---- .../console/config/security/AuditConfig.java | 6 +++--- .../security/{Audit.java => Decision.java} | 4 ++-- .../config/security/KafkaSecurityConfig.java | 7 +++++++ .../config/security/SecurityConfig.java | 2 +- .../console/config/ConsoleConfigTest.java | 14 +++++++------- 11 files changed, 49 insertions(+), 42 deletions(-) rename common/src/main/java/com/github/streamshub/console/config/security/{Audit.java => Decision.java} (90%) create mode 100644 common/src/main/java/com/github/streamshub/console/config/security/KafkaSecurityConfig.java diff --git a/api/src/main/java/com/github/streamshub/console/api/security/ConsoleAuthenticationMechanism.java b/api/src/main/java/com/github/streamshub/console/api/security/ConsoleAuthenticationMechanism.java index 853c2b76b..b28d4f089 100644 --- a/api/src/main/java/com/github/streamshub/console/api/security/ConsoleAuthenticationMechanism.java +++ b/api/src/main/java/com/github/streamshub/console/api/security/ConsoleAuthenticationMechanism.java @@ -39,7 +39,7 @@ import com.github.streamshub.console.api.support.ErrorCategory; import com.github.streamshub.console.api.support.KafkaContext; import com.github.streamshub.console.config.ConsoleConfig; -import com.github.streamshub.console.config.security.Audit; +import com.github.streamshub.console.config.security.Decision; import com.github.streamshub.console.config.security.AuditConfig; import com.github.streamshub.console.config.security.Privilege; import com.github.streamshub.console.config.security.SecurityConfig; @@ -358,7 +358,7 @@ private void addRoleChecker(KafkaContext ctx, QuarkusSecurityIdentity.Builder bu }); } - private void auditLog(Principal principal, Permission required, boolean allowed, Audit audit) { + private void auditLog(Principal principal, Permission required, boolean allowed, Decision audit) { if (audit != null && audit.logResult(allowed)) { log.infof("%s %s %s", principal.getName(), allowed ? "allowed" : "denied", required); } else { @@ -419,14 +419,14 @@ private Stream getPermissions(SecurityConfig security, Collection mergeAuditRules(Map global, Map cluster) { + private Map mergeAuditRules(Map global, Map cluster) { return Stream.concat(global.entrySet().stream(), cluster.entrySet().stream()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } - private Map getAuditRules(List audits, String resourcePrefix) { + private Map getAuditRules(List audits, String resourcePrefix) { return audits.stream().flatMap(rule -> { - Map auditRules = new HashMap<>(); + Map auditRules = new HashMap<>(); Set actions = rule.getPrivileges().stream().flatMap(p -> p.expand().stream()).collect(Collectors.toSet()); for (var action : actions) { diff --git a/api/src/test/java/com/github/streamshub/console/api/KafkaRebalancesResourceOidcIT.java b/api/src/test/java/com/github/streamshub/console/api/KafkaRebalancesResourceOidcIT.java index 87604d2ad..892aac124 100644 --- a/api/src/test/java/com/github/streamshub/console/api/KafkaRebalancesResourceOidcIT.java +++ b/api/src/test/java/com/github/streamshub/console/api/KafkaRebalancesResourceOidcIT.java @@ -15,8 +15,8 @@ import org.junit.jupiter.params.provider.CsvSource; import com.github.streamshub.console.config.ConsoleConfig; +import com.github.streamshub.console.config.security.KafkaSecurityConfigBuilder; import com.github.streamshub.console.config.security.Privilege; -import com.github.streamshub.console.config.security.SecurityConfigBuilder; import com.github.streamshub.console.kafka.systemtest.TestPlainProfile; import com.github.streamshub.console.kafka.systemtest.deployment.DeploymentManager; import com.github.streamshub.console.kafka.systemtest.utils.TokenUtils; @@ -173,7 +173,7 @@ void testListRebalancesWithPerTeamKafkaClusterAccess(String username, String tea .build()); consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-a") .addNewRule() @@ -185,7 +185,7 @@ void testListRebalancesWithPerTeamKafkaClusterAccess(String username, String tea }); consoleConfig.getKafka().getClusterById(clusterId2).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-b") .addNewRule() @@ -228,7 +228,7 @@ void testListRebalancesWithUnrelatedRoleAccess() { .build()); consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("developer") .addNewRule() @@ -259,7 +259,7 @@ void testListRebalancesWithMissingPrivilege() { .build()); consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("developer") .addNewRule() diff --git a/api/src/test/java/com/github/streamshub/console/api/TopicsResourceIT.java b/api/src/test/java/com/github/streamshub/console/api/TopicsResourceIT.java index 6cf4aacdf..a6f4cf1b4 100644 --- a/api/src/test/java/com/github/streamshub/console/api/TopicsResourceIT.java +++ b/api/src/test/java/com/github/streamshub/console/api/TopicsResourceIT.java @@ -71,10 +71,10 @@ import com.github.streamshub.console.api.security.ConsoleAuthenticationMechanism; import com.github.streamshub.console.api.support.Holder; import com.github.streamshub.console.config.ConsoleConfig; -import com.github.streamshub.console.config.security.Audit; +import com.github.streamshub.console.config.security.Decision; +import com.github.streamshub.console.config.security.KafkaSecurityConfigBuilder; import com.github.streamshub.console.config.security.Privilege; import com.github.streamshub.console.config.security.ResourceTypes; -import com.github.streamshub.console.config.security.SecurityConfigBuilder; import com.github.streamshub.console.kafka.systemtest.TestPlainProfile; import com.github.streamshub.console.kafka.systemtest.deployment.DeploymentManager; import com.github.streamshub.console.kafka.systemtest.utils.ConsumerUtils; @@ -770,9 +770,9 @@ void testListTopicsWithAuditLogging(String fields, @AggregateWith(VarargsAggrega topicUtils.createTopics(clusterId1, List.of(topicName), 1); consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(clusterConfig -> { - clusterConfig.setSecurity(new SecurityConfigBuilder() + clusterConfig.setSecurity(new KafkaSecurityConfigBuilder() .addNewAudit() - .withDecision(Audit.ALL) + .withDecision(Decision.ALL) .withResources(ResourceTypes.Kafka.TOPICS.value()) .withPrivileges(privilegesAudited) .endAudit() diff --git a/api/src/test/java/com/github/streamshub/console/api/TopicsResourceOidcIT.java b/api/src/test/java/com/github/streamshub/console/api/TopicsResourceOidcIT.java index 0905a61df..471808cde 100644 --- a/api/src/test/java/com/github/streamshub/console/api/TopicsResourceOidcIT.java +++ b/api/src/test/java/com/github/streamshub/console/api/TopicsResourceOidcIT.java @@ -27,10 +27,10 @@ import com.github.streamshub.console.api.support.KafkaContext; import com.github.streamshub.console.config.ConsoleConfig; import com.github.streamshub.console.config.KafkaClusterConfig; -import com.github.streamshub.console.config.security.Audit; +import com.github.streamshub.console.config.security.Decision; +import com.github.streamshub.console.config.security.KafkaSecurityConfigBuilder; import com.github.streamshub.console.config.security.Privilege; import com.github.streamshub.console.config.security.ResourceTypes; -import com.github.streamshub.console.config.security.SecurityConfigBuilder; import com.github.streamshub.console.kafka.systemtest.TestPlainProfile; import com.github.streamshub.console.kafka.systemtest.deployment.DeploymentManager; import com.github.streamshub.console.kafka.systemtest.utils.ConsumerUtils; @@ -174,7 +174,7 @@ void testListTopicsWithForbiddenFieldsNull(String username, String team) { * and may only list/get their own groups. */ consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-a") .addNewRule() @@ -293,9 +293,9 @@ void testListTopicsWithAuditLogging(String fields, @AggregateWith(VarargsAggrega .build()); consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(clusterConfig -> { - clusterConfig.setSecurity(new SecurityConfigBuilder() + clusterConfig.setSecurity(new KafkaSecurityConfigBuilder() .addNewAudit() - .withDecision(Audit.ALL) + .withDecision(Decision.ALL) .withResources(ResourceTypes.Kafka.TOPICS.value()) .withPrivileges(privilegesAudited) .endAudit() @@ -359,7 +359,7 @@ void testDescribeTopicWithForbiddenFieldsNull(String username, String team) { * Both teams may only describe their own topics. */ consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-a") .addNewRule() @@ -432,7 +432,7 @@ void testCreateTopicWithAuthorization(String topicPrefix, Status expectedStatus) // alice's team may only create topics starting with `a-` consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-a") .addNewRule() @@ -480,7 +480,7 @@ void testDeleteTopicWithAuthorization(String topicPrefix, Status expectedStatus) // alice's team may only delete topics starting with `a-` consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-a") .addNewRule() @@ -520,7 +520,7 @@ void testPatchTopicWithAuthorization(String topicPrefix, Status expectedStatus) // alice's team may only update topics starting with `a-` // UPDATE requires GET: old version of topic required for validations consoleConfig.getKafka().getClusterById(clusterId1).ifPresent(cfg -> { - cfg.setSecurity(new SecurityConfigBuilder() + cfg.setSecurity(new KafkaSecurityConfigBuilder() .addNewRole() .withName("dev-a") .addNewRule() diff --git a/common/src/main/java/com/github/streamshub/console/config/ConsoleConfig.java b/common/src/main/java/com/github/streamshub/console/config/ConsoleConfig.java index fb28ea99a..0e2ae47ab 100644 --- a/common/src/main/java/com/github/streamshub/console/config/ConsoleConfig.java +++ b/common/src/main/java/com/github/streamshub/console/config/ConsoleConfig.java @@ -10,9 +10,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.github.streamshub.console.config.security.GlobalSecurityConfig; +import com.github.streamshub.console.config.security.KafkaSecurityConfig; import com.github.streamshub.console.config.security.ResourceTypes; import com.github.streamshub.console.config.security.ResourceTypes.ValidResourceTypes; -import com.github.streamshub.console.config.security.SecurityConfig; import io.sundr.builder.annotations.Buildable; import io.xlate.validation.constraints.Expression; @@ -88,7 +88,7 @@ public boolean isWithoutOidcOrKafkaClusterSubjectsEmpty() { @JsonIgnore public void clearSecurity() { security = new GlobalSecurityConfig(); - kafka.getClusters().forEach(k -> k.setSecurity(new SecurityConfig())); + kafka.getClusters().forEach(k -> k.setSecurity(new KafkaSecurityConfig())); } public KubernetesConfig getKubernetes() { diff --git a/common/src/main/java/com/github/streamshub/console/config/KafkaClusterConfig.java b/common/src/main/java/com/github/streamshub/console/config/KafkaClusterConfig.java index a51dfb20e..b95c432d7 100644 --- a/common/src/main/java/com/github/streamshub/console/config/KafkaClusterConfig.java +++ b/common/src/main/java/com/github/streamshub/console/config/KafkaClusterConfig.java @@ -9,8 +9,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.github.streamshub.console.config.security.KafkaSecurityConfig; import com.github.streamshub.console.config.security.ResourceTypes; -import com.github.streamshub.console.config.security.SecurityConfig; import com.github.streamshub.console.config.security.ResourceTypes.ValidResourceTypes; import io.sundr.builder.annotations.Buildable; @@ -26,7 +26,7 @@ public class KafkaClusterConfig implements Named { private String listener; @Valid @ValidResourceTypes(type = ResourceTypes.Kafka.class) - private SecurityConfig security = new SecurityConfig(); + private KafkaSecurityConfig security = new KafkaSecurityConfig(); /** * Name of a configured metrics source used by this Kafka cluster */ @@ -76,11 +76,11 @@ public void setNamespace(String namespace) { this.namespace = namespace; } - public SecurityConfig getSecurity() { + public KafkaSecurityConfig getSecurity() { return security; } - public void setSecurity(SecurityConfig security) { + public void setSecurity(KafkaSecurityConfig security) { this.security = security; } diff --git a/common/src/main/java/com/github/streamshub/console/config/security/AuditConfig.java b/common/src/main/java/com/github/streamshub/console/config/security/AuditConfig.java index a7f3758ec..229bf88f8 100644 --- a/common/src/main/java/com/github/streamshub/console/config/security/AuditConfig.java +++ b/common/src/main/java/com/github/streamshub/console/config/security/AuditConfig.java @@ -5,13 +5,13 @@ @Buildable(editableEnabled = false) public class AuditConfig extends RuleConfig { - Audit decision; + Decision decision; - public Audit getDecision() { + public Decision getDecision() { return decision; } - public void setDecision(Audit decision) { + public void setDecision(Decision decision) { this.decision = decision; } } diff --git a/common/src/main/java/com/github/streamshub/console/config/security/Audit.java b/common/src/main/java/com/github/streamshub/console/config/security/Decision.java similarity index 90% rename from common/src/main/java/com/github/streamshub/console/config/security/Audit.java rename to common/src/main/java/com/github/streamshub/console/config/security/Decision.java index e682374ab..5f140a0d0 100644 --- a/common/src/main/java/com/github/streamshub/console/config/security/Audit.java +++ b/common/src/main/java/com/github/streamshub/console/config/security/Decision.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; -public enum Audit { +public enum Decision { ALLOWED { @Override @@ -30,7 +30,7 @@ public boolean logResult(boolean allowed) { public abstract boolean logResult(boolean allowed); @JsonCreator - public static Audit forValue(String value) { + public static Decision forValue(String value) { if ("*".equals(value)) { return ALL; } diff --git a/common/src/main/java/com/github/streamshub/console/config/security/KafkaSecurityConfig.java b/common/src/main/java/com/github/streamshub/console/config/security/KafkaSecurityConfig.java new file mode 100644 index 000000000..ef4dd49bc --- /dev/null +++ b/common/src/main/java/com/github/streamshub/console/config/security/KafkaSecurityConfig.java @@ -0,0 +1,7 @@ +package com.github.streamshub.console.config.security; + +import io.sundr.builder.annotations.Buildable; + +@Buildable(editableEnabled = false) +public class KafkaSecurityConfig extends SecurityConfig { +} diff --git a/common/src/main/java/com/github/streamshub/console/config/security/SecurityConfig.java b/common/src/main/java/com/github/streamshub/console/config/security/SecurityConfig.java index bb60fc311..716f78cc4 100644 --- a/common/src/main/java/com/github/streamshub/console/config/security/SecurityConfig.java +++ b/common/src/main/java/com/github/streamshub/console/config/security/SecurityConfig.java @@ -8,7 +8,7 @@ import io.sundr.builder.annotations.Buildable; @Buildable(editableEnabled = false) -public class SecurityConfig { +public abstract class SecurityConfig { @Valid private List subjects = new ArrayList<>(); diff --git a/common/src/test/java/com/github/streamshub/console/config/ConsoleConfigTest.java b/common/src/test/java/com/github/streamshub/console/config/ConsoleConfigTest.java index 82f6e73f1..34144e9c5 100644 --- a/common/src/test/java/com/github/streamshub/console/config/ConsoleConfigTest.java +++ b/common/src/test/java/com/github/streamshub/console/config/ConsoleConfigTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.github.streamshub.console.config.security.Audit; +import com.github.streamshub.console.config.security.Decision; import com.github.streamshub.console.config.security.GlobalSecurityConfigBuilder; import com.github.streamshub.console.config.security.Privilege; import com.github.streamshub.console.config.security.ResourceTypes; @@ -174,7 +174,7 @@ void testMetricsSourceNamesUniquePassesValidation() { void testKnownResourceTypesPassValidation() { config.setSecurity(new GlobalSecurityConfigBuilder() .addNewAudit() - .withDecision(Audit.ALLOWED) + .withDecision(Decision.ALLOWED) .withResources(ResourceTypes.Global.KAFKAS.value()) .withPrivileges(Privilege.forValue("*")) .endAudit() @@ -191,7 +191,7 @@ void testKnownResourceTypesPassValidation() { .withName("kafka1") .withNewSecurity() .addNewAudit() - .withDecision(Audit.ALLOWED) + .withDecision(Decision.ALLOWED) .withResources(ResourceTypes.Kafka.ALL.value()) .withPrivileges(Privilege.forValue("*")) .endAudit() @@ -215,7 +215,7 @@ void testKnownResourceTypesFailValidation() { config.setSecurity(new GlobalSecurityConfigBuilder() .addNewAudit() - .withDecision(Audit.ALLOWED) + .withDecision(Decision.ALLOWED) .withResources( ResourceTypes.Global.KAFKAS.value(), unknownResource) @@ -240,17 +240,17 @@ void testKnownResourceTypesFailValidation() { .withName("kafka1") .withNewSecurity() .addNewAudit() - .withDecision(Audit.ALLOWED) + .withDecision(Decision.ALLOWED) .withResources(ResourceTypes.Kafka.ALL.value()) .withPrivileges(Privilege.forValue("CREATE")) .endAudit() .addNewAudit() - .withDecision(Audit.DENIED) + .withDecision(Decision.DENIED) .withResources(unknownResource) .withPrivileges(Privilege.forValue("DELETE")) .endAudit() .addNewAudit() - .withDecision(Audit.ALL) + .withDecision(Decision.ALL) .withResources(ResourceTypes.Kafka.CONSUMER_GROUPS.value(), unknownResource) .withPrivileges(Privilege.forValue("UPDATE")) .endAudit()