From b3249cdcda7ba3ff97ef2c17580dbd4a51a59f57 Mon Sep 17 00:00:00 2001 From: ali-jalaal <4487124+ali-jalaal@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:55:52 +0100 Subject: [PATCH 1/5] Add OPAProperties to structure properties Implements #21 --- .gitignore | 3 + build.gradle | 15 +++++ .../springboot/OPAAuthorizationManager.java | 60 ++++++----------- .../styra/opa/springboot/OpaProperties.java | 66 +++++++++++++++++++ .../properties/DefaultPropertiesTest.java | 33 ++++++++++ .../properties/ModifiedPropertiesTest.java | 38 +++++++++++ .../ModifiedSystemEnvPropertiesTest.java | 25 +++++++ 7 files changed, 200 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/styra/opa/springboot/OpaProperties.java create mode 100644 src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java create mode 100644 src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java create mode 100644 src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java diff --git a/.gitignore b/.gitignore index d144f8c..3281341 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ gradle-app.setting .project # JDT-specific (Eclipse Java Development Tools) .classpath + +# IntelliJ IDEA +.idea/** diff --git a/build.gradle b/build.gradle index ea77946..3dcebff 100644 --- a/build.gradle +++ b/build.gradle @@ -100,11 +100,26 @@ task lint { test { useJUnitPlatform() + exclude 'com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.class' testLogging { // uncomment for more verbose output during development //events "passed", "skipped", "failed", "standard_out", "standard_error" } } +tasks.register("testModifiedSystemEnvProperties", Test) { + useJUnitPlatform() + group = "verification" + include 'com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.class' + doFirst { + systemProperty 'opa.url', 'http://localhost:8183' + environment 'OPA_PATH', '/tickets/main2' + } + doLast { + systemProperties.remove('opa.url') + environment.remove('OPA_PATH') + } +} +test.finalizedBy(testModifiedSystemEnvProperties) gradle.projectsEvaluated { tasks.withType(JavaCompile) { diff --git a/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java b/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java index 2a22642..555a542 100644 --- a/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java +++ b/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java @@ -38,19 +38,12 @@ public class OPAAuthorizationManager OPAAuthorizationManager.class ); - private static final String SubjectType = "java_authentication"; - private static final String RequestResourceType = "endpoint"; - private static final String RequestContextType = "http"; - - // If opaPath is null, then we assume the user wants to use the default path. - private String opaPath; - - private String reasonKey; - private ContextDataProvider ctxProvider; private OPAClient opa; + private OpaProperties opaProperties; + /** * The authorization manager will internally instantiate an OPAClient * instance with default settings. The OPA URL may be overridden using the @@ -58,9 +51,7 @@ public class OPAAuthorizationManager * default path defined by the OPA configuration. */ public OPAAuthorizationManager() { - this.opa = defaultOPAClient(); - this.opaPath = null; - this.reasonKey = "en"; + this(null, null, null); } /** @@ -71,9 +62,7 @@ public OPAAuthorizationManager() { * @param opa */ public OPAAuthorizationManager(OPAClient opa) { - this.opa = opa; - this.opaPath = null; - this.reasonKey = "en"; + this(opa, null, null); } /** @@ -86,9 +75,7 @@ public OPAAuthorizationManager(OPAClient opa) { * @param newOpaPath */ public OPAAuthorizationManager(OPAClient opa, String newOpaPath) { - this.opa = opa; - this.opaPath = newOpaPath; - this.reasonKey = "en"; + this(opa, newOpaPath, null); } /** @@ -99,9 +86,7 @@ public OPAAuthorizationManager(OPAClient opa, String newOpaPath) { * @param newOpaPath */ public OPAAuthorizationManager(String newOpaPath) { - this.opa = defaultOPAClient(); - this.opaPath = newOpaPath; - this.reasonKey = "en"; + this(null, newOpaPath, null); } /** @@ -114,9 +99,7 @@ public OPAAuthorizationManager(String newOpaPath) { * @param newProvider */ public OPAAuthorizationManager(OPAClient opa, ContextDataProvider newProvider) { - this.opa = opa; - this.ctxProvider = newProvider; - this.reasonKey = "en"; + this(opa, null, newProvider); } /** @@ -129,10 +112,10 @@ public OPAAuthorizationManager(OPAClient opa, ContextDataProvider newProvider) { * @param newProvider */ public OPAAuthorizationManager(OPAClient opa, String newOpaPath, ContextDataProvider newProvider) { - this.opa = opa; - this.opaPath = newOpaPath; + // If newOpaPath is null, then we assume the user wants to use the default path. + this.opaProperties = OpaProperties.builder().path(newOpaPath).build(); + this.opa = opa != null ? opa : defaultOPAClient(); this.ctxProvider = newProvider; - this.reasonKey = "en"; } /** @@ -143,10 +126,7 @@ public OPAAuthorizationManager(OPAClient opa, String newOpaPath, ContextDataProv * @param newProvider */ public OPAAuthorizationManager(String newOpaPath, ContextDataProvider newProvider) { - this.opa = defaultOPAClient(); - this.opaPath = newOpaPath; - this.ctxProvider = newProvider; - this.reasonKey = "en"; + this(null, newOpaPath, newProvider); } private static OPAClient defaultOPAClient() { @@ -160,7 +140,7 @@ private static OPAClient defaultOPAClient() { } public String getReasonKey() { - return this.reasonKey; + return opaProperties.getReasonKey(); } /** @@ -172,7 +152,7 @@ public String getReasonKey() { * @param newReasonKey */ public void setReasonKey(String newReasonKey) { - this.reasonKey = newReasonKey; + opaProperties.setReasonKey(newReasonKey); } /** @@ -222,13 +202,13 @@ private Map makeRequestInput( Integer contextRemotePort = request.getRemotePort(); Map ctx = new HashMap(); - nullablePut(ctx, "type", RequestContextType); + nullablePut(ctx, "type", opaProperties.getRequest().getContext().getType()); nullablePut(ctx, "host", contextRemoteHost); nullablePut(ctx, "ip", contextRemoteAddr); nullablePut(ctx, "port", contextRemotePort); Map subjectInfo = new HashMap(); - nullablePut(subjectInfo, "type", SubjectType); + nullablePut(subjectInfo, "type", opaProperties.getRequest().getSubject().getType()); nullablePut(subjectInfo, "id", subjectId); nullablePut(subjectInfo, "details", subjectDetails); nullablePut(subjectInfo, "authorities", subjectAuthorities); @@ -243,7 +223,7 @@ private Map makeRequestInput( entry( "resource", java.util.Map.ofEntries( - entry("type", RequestResourceType), + entry("type", opaProperties.getRequest().getResource().getType()), entry("id", resourceId) ) ), @@ -276,10 +256,10 @@ public OPAResponse opaRequest( logger.trace("OPA input for request: {}", iMap); OPAResponse resp = null; try { - if (this.opaPath != null) { - logger.trace("OPA path is {}", this.opaPath); + if (opaProperties.getPath() != null) { + logger.trace("OPA path is {}", opaProperties.getPath()); resp = opa.evaluate( - this.opaPath, + opaProperties.getPath(), iMap, new TypeReference() {} ); @@ -319,7 +299,7 @@ public void verify( } boolean allow = resp.getDecision(); - String reason = resp.getReasonForDecision(this.reasonKey); + String reason = resp.getReasonForDecision(opaProperties.getReasonKey()); if (reason == null) { reason = "access denied by policy"; } diff --git a/src/main/java/com/styra/opa/springboot/OpaProperties.java b/src/main/java/com/styra/opa/springboot/OpaProperties.java new file mode 100644 index 0000000..d7bbf69 --- /dev/null +++ b/src/main/java/com/styra/opa/springboot/OpaProperties.java @@ -0,0 +1,66 @@ +package com.styra.opa.springboot; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "opa") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class OpaProperties { + public static final String DEFAULT_URL = "http://localhost:8181"; + public static final String DEFAULT_REASON_KEY = "en"; + + private String url = DEFAULT_URL; + private String path; + private String reasonKey = DEFAULT_REASON_KEY; + private Request request = new Request(); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Request { + + private Resource resource = new Resource(); + private Context context = new Context(); + private Subject subject = new Subject(); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Resource { + public static final String DEFAULT_TYPE = "endpoint"; + + @Builder.Default + private String type = DEFAULT_TYPE; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Context { + public static final String DEFAULT_TYPE = "http"; + + @Builder.Default + private String type = DEFAULT_TYPE; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Subject { + public static final String DEFAULT_TYPE = "java_authentication"; + + @Builder.Default + private String type = DEFAULT_TYPE; + } + } +} diff --git a/src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java b/src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java new file mode 100644 index 0000000..dd83f1f --- /dev/null +++ b/src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java @@ -0,0 +1,33 @@ +package com.styra.opa.springboot.properties; + +import com.styra.opa.springboot.OpaProperties; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +@EnableConfigurationProperties(value = OpaProperties.class) +@ExtendWith(SpringExtension.class) +public class DefaultPropertiesTest { + + @Autowired + private OpaProperties opaProperties; + + @Test + public void test() { + assertEquals(OpaProperties.DEFAULT_URL, opaProperties.getUrl()); + assertNull(opaProperties.getPath()); + assertEquals(OpaProperties.DEFAULT_REASON_KEY, opaProperties.getReasonKey()); + assertNotNull(opaProperties.getRequest()); + assertEquals(OpaProperties.Request.Resource.DEFAULT_TYPE, opaProperties.getRequest().getResource().getType()); + assertNotNull(opaProperties.getRequest().getContext()); + assertEquals(OpaProperties.Request.Context.DEFAULT_TYPE, opaProperties.getRequest().getContext().getType()); + assertEquals(OpaProperties.Request.Subject.DEFAULT_TYPE, + opaProperties.getRequest().getSubject().getType()); + } +} diff --git a/src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java b/src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java new file mode 100644 index 0000000..a263b93 --- /dev/null +++ b/src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java @@ -0,0 +1,38 @@ +package com.styra.opa.springboot.properties; + +import com.styra.opa.springboot.OpaProperties; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestPropertySource(properties = { + "opa.url=http://localhost:8182", + "opa.path=/tickets/main", + "opa.reason-key=de", + "opa.request.resource.type=stomp_endpoint", + "opa.request.context.type=websocket", + "opa.request.subject.type=oauth2_resource_owner" +}) +@EnableConfigurationProperties(value = OpaProperties.class) +@ExtendWith(SpringExtension.class) +public class ModifiedPropertiesTest { + + @Autowired + private OpaProperties opaProperties; + + @Test + public void test() { + assertEquals("http://localhost:8182", opaProperties.getUrl()); + assertEquals("/tickets/main", opaProperties.getPath()); + assertEquals("de", opaProperties.getReasonKey()); + assertEquals("stomp_endpoint", opaProperties.getRequest().getResource().getType()); + assertEquals("websocket", opaProperties.getRequest().getContext().getType()); + assertEquals("oauth2_resource_owner", opaProperties.getRequest().getSubject().getType()); + } +} + diff --git a/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java b/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java new file mode 100644 index 0000000..9f724e3 --- /dev/null +++ b/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java @@ -0,0 +1,25 @@ +package com.styra.opa.springboot.properties; + +import com.styra.opa.springboot.OpaProperties; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +// Run using: ./gradlew testModifiedSystemEnvProperties +@EnableConfigurationProperties(value = OpaProperties.class) +@ExtendWith(SpringExtension.class) +public class ModifiedSystemEnvPropertiesTest { + + @Autowired + private OpaProperties opaProperties; + + @Test + public void test() { + assertEquals("http://localhost:8183", opaProperties.getUrl()); + assertEquals("/tickets/main2", opaProperties.getPath()); + } +} From d9719f30ec0a966e8aad59cb4ca6c71af4635d91 Mon Sep 17 00:00:00 2001 From: ali-jalaal <4487124+ali-jalaal@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:28:42 +0100 Subject: [PATCH 2/5] Add OPAProperties to structure properties - improve tests & code style --- build.gradle | 6 ++--- .../springboot/OPAAuthorizationManager.java | 11 +++++----- ...{OpaProperties.java => OPAProperties.java} | 11 +--------- ...est.java => DefaultOPAPropertiesTest.java} | 18 +++++++-------- ...st.java => ModifiedOPAPropertiesTest.java} | 22 +++++++++---------- ...> ModifiedSystemEnvOPAPropertiesTest.java} | 10 ++++----- 6 files changed, 35 insertions(+), 43 deletions(-) rename src/main/java/com/styra/opa/springboot/{OpaProperties.java => OPAProperties.java} (84%) rename src/test/java/com/styra/opa/springboot/properties/{DefaultPropertiesTest.java => DefaultOPAPropertiesTest.java} (64%) rename src/test/java/com/styra/opa/springboot/properties/{ModifiedPropertiesTest.java => ModifiedOPAPropertiesTest.java} (64%) rename src/test/java/com/styra/opa/springboot/properties/{ModifiedSystemEnvPropertiesTest.java => ModifiedSystemEnvOPAPropertiesTest.java} (68%) diff --git a/build.gradle b/build.gradle index 3dcebff..137f1aa 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,7 @@ task lint { test { useJUnitPlatform() - exclude 'com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.class' + exclude 'com/styra/opa/springboot/properties/ModifiedSystemEnvOPAPropertiesTest.class' testLogging { // uncomment for more verbose output during development //events "passed", "skipped", "failed", "standard_out", "standard_error" @@ -109,10 +109,10 @@ test { tasks.register("testModifiedSystemEnvProperties", Test) { useJUnitPlatform() group = "verification" - include 'com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.class' + include 'com/styra/opa/springboot/properties/ModifiedSystemEnvOPAPropertiesTest.class' doFirst { systemProperty 'opa.url', 'http://localhost:8183' - environment 'OPA_PATH', '/tickets/main2' + environment 'OPA_PATH', 'tickets/main2' } doLast { systemProperties.remove('opa.url') diff --git a/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java b/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java index 555a542..b37fa78 100644 --- a/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java +++ b/src/main/java/com/styra/opa/springboot/OPAAuthorizationManager.java @@ -42,7 +42,7 @@ public class OPAAuthorizationManager private OPAClient opa; - private OpaProperties opaProperties; + private OPAProperties opaProperties; /** * The authorization manager will internally instantiate an OPAClient @@ -113,8 +113,9 @@ public OPAAuthorizationManager(OPAClient opa, ContextDataProvider newProvider) { */ public OPAAuthorizationManager(OPAClient opa, String newOpaPath, ContextDataProvider newProvider) { // If newOpaPath is null, then we assume the user wants to use the default path. - this.opaProperties = OpaProperties.builder().path(newOpaPath).build(); - this.opa = opa != null ? opa : defaultOPAClient(); + opaProperties = new OPAProperties(); + opaProperties.setPath(newOpaPath); + this.opa = opa != null ? opa : defaultOPAClient(opaProperties); this.ctxProvider = newProvider; } @@ -129,8 +130,8 @@ public OPAAuthorizationManager(String newOpaPath, ContextDataProvider newProvide this(null, newOpaPath, newProvider); } - private static OPAClient defaultOPAClient() { - String opaURL = "http://localhost:8181"; + private static OPAClient defaultOPAClient(OPAProperties opaProperties) { + String opaURL = opaProperties.getUrl(); String opaURLEnv = System.getenv("OPA_URL"); if (opaURLEnv != null) { opaURL = opaURLEnv; diff --git a/src/main/java/com/styra/opa/springboot/OpaProperties.java b/src/main/java/com/styra/opa/springboot/OPAProperties.java similarity index 84% rename from src/main/java/com/styra/opa/springboot/OpaProperties.java rename to src/main/java/com/styra/opa/springboot/OPAProperties.java index d7bbf69..4647a68 100644 --- a/src/main/java/com/styra/opa/springboot/OpaProperties.java +++ b/src/main/java/com/styra/opa/springboot/OPAProperties.java @@ -1,17 +1,15 @@ package com.styra.opa.springboot; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "opa") @Data -@Builder @NoArgsConstructor @AllArgsConstructor -public class OpaProperties { +public class OPAProperties { public static final String DEFAULT_URL = "http://localhost:8181"; public static final String DEFAULT_REASON_KEY = "en"; @@ -21,7 +19,6 @@ public class OpaProperties { private Request request = new Request(); @Data - @Builder @NoArgsConstructor @AllArgsConstructor public static class Request { @@ -31,35 +28,29 @@ public static class Request { private Subject subject = new Subject(); @Data - @Builder @NoArgsConstructor @AllArgsConstructor public static class Resource { public static final String DEFAULT_TYPE = "endpoint"; - @Builder.Default private String type = DEFAULT_TYPE; } @Data - @Builder @NoArgsConstructor @AllArgsConstructor public static class Context { public static final String DEFAULT_TYPE = "http"; - @Builder.Default private String type = DEFAULT_TYPE; } @Data - @Builder @NoArgsConstructor @AllArgsConstructor public static class Subject { public static final String DEFAULT_TYPE = "java_authentication"; - @Builder.Default private String type = DEFAULT_TYPE; } } diff --git a/src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java b/src/test/java/com/styra/opa/springboot/properties/DefaultOPAPropertiesTest.java similarity index 64% rename from src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java rename to src/test/java/com/styra/opa/springboot/properties/DefaultOPAPropertiesTest.java index dd83f1f..ce7a1c7 100644 --- a/src/test/java/com/styra/opa/springboot/properties/DefaultPropertiesTest.java +++ b/src/test/java/com/styra/opa/springboot/properties/DefaultOPAPropertiesTest.java @@ -1,6 +1,6 @@ package com.styra.opa.springboot.properties; -import com.styra.opa.springboot.OpaProperties; +import com.styra.opa.springboot.OPAProperties; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -11,23 +11,23 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -@EnableConfigurationProperties(value = OpaProperties.class) +@EnableConfigurationProperties(value = OPAProperties.class) @ExtendWith(SpringExtension.class) -public class DefaultPropertiesTest { +public class DefaultOPAPropertiesTest { @Autowired - private OpaProperties opaProperties; + private OPAProperties opaProperties; @Test public void test() { - assertEquals(OpaProperties.DEFAULT_URL, opaProperties.getUrl()); + assertEquals(OPAProperties.DEFAULT_URL, opaProperties.getUrl()); assertNull(opaProperties.getPath()); - assertEquals(OpaProperties.DEFAULT_REASON_KEY, opaProperties.getReasonKey()); + assertEquals(OPAProperties.DEFAULT_REASON_KEY, opaProperties.getReasonKey()); assertNotNull(opaProperties.getRequest()); - assertEquals(OpaProperties.Request.Resource.DEFAULT_TYPE, opaProperties.getRequest().getResource().getType()); + assertEquals(OPAProperties.Request.Resource.DEFAULT_TYPE, opaProperties.getRequest().getResource().getType()); assertNotNull(opaProperties.getRequest().getContext()); - assertEquals(OpaProperties.Request.Context.DEFAULT_TYPE, opaProperties.getRequest().getContext().getType()); - assertEquals(OpaProperties.Request.Subject.DEFAULT_TYPE, + assertEquals(OPAProperties.Request.Context.DEFAULT_TYPE, opaProperties.getRequest().getContext().getType()); + assertEquals(OPAProperties.Request.Subject.DEFAULT_TYPE, opaProperties.getRequest().getSubject().getType()); } } diff --git a/src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java b/src/test/java/com/styra/opa/springboot/properties/ModifiedOPAPropertiesTest.java similarity index 64% rename from src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java rename to src/test/java/com/styra/opa/springboot/properties/ModifiedOPAPropertiesTest.java index a263b93..c5deb74 100644 --- a/src/test/java/com/styra/opa/springboot/properties/ModifiedPropertiesTest.java +++ b/src/test/java/com/styra/opa/springboot/properties/ModifiedOPAPropertiesTest.java @@ -1,6 +1,6 @@ package com.styra.opa.springboot.properties; -import com.styra.opa.springboot.OpaProperties; +import com.styra.opa.springboot.OPAProperties; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -11,24 +11,24 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @TestPropertySource(properties = { - "opa.url=http://localhost:8182", - "opa.path=/tickets/main", - "opa.reason-key=de", - "opa.request.resource.type=stomp_endpoint", - "opa.request.context.type=websocket", - "opa.request.subject.type=oauth2_resource_owner" + "opa.url=http://localhost:8182", + "opa.path=tickets/main", + "opa.reason-key=de", + "opa.request.resource.type=stomp_endpoint", + "opa.request.context.type=websocket", + "opa.request.subject.type=oauth2_resource_owner" }) -@EnableConfigurationProperties(value = OpaProperties.class) +@EnableConfigurationProperties(value = OPAProperties.class) @ExtendWith(SpringExtension.class) -public class ModifiedPropertiesTest { +public class ModifiedOPAPropertiesTest { @Autowired - private OpaProperties opaProperties; + private OPAProperties opaProperties; @Test public void test() { assertEquals("http://localhost:8182", opaProperties.getUrl()); - assertEquals("/tickets/main", opaProperties.getPath()); + assertEquals("tickets/main", opaProperties.getPath()); assertEquals("de", opaProperties.getReasonKey()); assertEquals("stomp_endpoint", opaProperties.getRequest().getResource().getType()); assertEquals("websocket", opaProperties.getRequest().getContext().getType()); diff --git a/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java b/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvOPAPropertiesTest.java similarity index 68% rename from src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java rename to src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvOPAPropertiesTest.java index 9f724e3..6361384 100644 --- a/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvPropertiesTest.java +++ b/src/test/java/com/styra/opa/springboot/properties/ModifiedSystemEnvOPAPropertiesTest.java @@ -1,6 +1,6 @@ package com.styra.opa.springboot.properties; -import com.styra.opa.springboot.OpaProperties; +import com.styra.opa.springboot.OPAProperties; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,16 +10,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; // Run using: ./gradlew testModifiedSystemEnvProperties -@EnableConfigurationProperties(value = OpaProperties.class) +@EnableConfigurationProperties(value = OPAProperties.class) @ExtendWith(SpringExtension.class) -public class ModifiedSystemEnvPropertiesTest { +public class ModifiedSystemEnvOPAPropertiesTest { @Autowired - private OpaProperties opaProperties; + private OPAProperties opaProperties; @Test public void test() { assertEquals("http://localhost:8183", opaProperties.getUrl()); - assertEquals("/tickets/main2", opaProperties.getPath()); + assertEquals("tickets/main2", opaProperties.getPath()); } } From 70d97ecbc192409adef02011f29ff22ad6ecc0ad Mon Sep 17 00:00:00 2001 From: ali-jalaal <4487124+ali-jalaal@users.noreply.github.com> Date: Sat, 1 Feb 2025 00:12:01 +0100 Subject: [PATCH 3/5] Add OPAProperties to structure properties - fix failed tests (use opa-0.70.0) --- build.gradle | 10 +++------- .../opa/springboot/OPAAuthorizationManagerTest.java | 5 ++++- src/test/resources/opa.Dockerfile | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 137f1aa..d492d7d 100644 --- a/build.gradle +++ b/build.gradle @@ -52,14 +52,10 @@ dependencies { implementation 'org.springframework:spring-context' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - testImplementation 'org.junit.jupiter:junit-jupiter-api:+' - testImplementation 'org.testcontainers:testcontainers-bom:+' - testImplementation 'org.testcontainers:testcontainers:+' - testImplementation 'org.testcontainers:junit-jupiter:+' - - testImplementation 'org.mockito:mockito-core:+' - testImplementation 'org.mockito:mockito-junit-jupiter:+' + testImplementation 'org.testcontainers:testcontainers-bom:1.19.8' + testImplementation 'org.testcontainers:testcontainers:1.19.8' + testImplementation 'org.testcontainers:junit-jupiter:1.19.8' api group: 'com.styra', name: 'opa', version: '1.8.0' diff --git a/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java b/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java index 80565a0..6dc648e 100644 --- a/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java +++ b/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; @@ -19,6 +20,7 @@ import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -93,7 +95,8 @@ class OPAAuthorizationManagerTest { ) .withExposedPorts(opaPort, altPort) .withFileSystemBind("./testdata/simple", "/policy", BindMode.READ_ONLY) - .withCommand("run -s --authentication=token --authorization=basic --bundle /policy"); + .withCommand("run -s --authentication=token --authorization=basic --bundle /policy") + .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(OPAAuthorizationManagerTest.class))); //CHECKSTYLE:ON private Authentication createMockAuthentication() { diff --git a/src/test/resources/opa.Dockerfile b/src/test/resources/opa.Dockerfile index ff1270d..5721d98 100644 --- a/src/test/resources/opa.Dockerfile +++ b/src/test/resources/opa.Dockerfile @@ -8,7 +8,7 @@ ADD entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh -COPY --from=openpolicyagent/opa:latest-static /opa /usr/bin/opa +COPY --from=openpolicyagent/opa:0.70.0-static /opa /usr/bin/opa ENTRYPOINT ["/entrypoint.sh"] From bcd6fd215e747fd14eaeb6cbac90d6c636f1dde8 Mon Sep 17 00:00:00 2001 From: ali-jalaal <4487124+ali-jalaal@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:32:56 +0100 Subject: [PATCH 4/5] Add OPAProperties to structure properties - fix tests with the latest OPA version --- .../styra/opa/springboot/OPAAuthorizationManagerTest.java | 2 +- src/test/resources/opa.Dockerfile | 2 +- testdata/simple/policy.rego | 2 ++ testdata/simple/system.rego | 6 ++++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java b/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java index 6dc648e..249f7ce 100644 --- a/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java +++ b/src/test/java/com/styra/opa/springboot/OPAAuthorizationManagerTest.java @@ -95,7 +95,7 @@ class OPAAuthorizationManagerTest { ) .withExposedPorts(opaPort, altPort) .withFileSystemBind("./testdata/simple", "/policy", BindMode.READ_ONLY) - .withCommand("run -s --authentication=token --authorization=basic --bundle /policy") + .withCommand("run -s --authentication=token --authorization=basic --bundle /policy --addr=0.0.0.0:" + opaPort) .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(OPAAuthorizationManagerTest.class))); //CHECKSTYLE:ON diff --git a/src/test/resources/opa.Dockerfile b/src/test/resources/opa.Dockerfile index 5721d98..ff1270d 100644 --- a/src/test/resources/opa.Dockerfile +++ b/src/test/resources/opa.Dockerfile @@ -8,7 +8,7 @@ ADD entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh -COPY --from=openpolicyagent/opa:0.70.0-static /opa /usr/bin/opa +COPY --from=openpolicyagent/opa:latest-static /opa /usr/bin/opa ENTRYPOINT ["/entrypoint.sh"] diff --git a/testdata/simple/policy.rego b/testdata/simple/policy.rego index 0846e39..b4cce25 100644 --- a/testdata/simple/policy.rego +++ b/testdata/simple/policy.rego @@ -1,5 +1,7 @@ package policy +import rego.v1 + echo := { "decision": true, "context": { diff --git a/testdata/simple/system.rego b/testdata/simple/system.rego index 82f43fb..b2f826b 100644 --- a/testdata/simple/system.rego +++ b/testdata/simple/system.rego @@ -1,11 +1,13 @@ package system +import rego.v1 + # This is used to exercise the default query functionality. msg := "this is the default path" -main := x { +main := x if { x := {"msg": msg, "echo": input} -} else { +} else if { x := {"msg": msg} } From 224e27df25f59516ff7ff185ee37bf16928f300f Mon Sep 17 00:00:00 2001 From: ali-jalaal <4487124+ali-jalaal@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:41:00 +0100 Subject: [PATCH 5/5] Add OPAProperties to structure properties - remove `import rego.v1` in policies --- testdata/simple/auth.rego | 2 -- testdata/simple/policy.rego | 2 -- testdata/simple/system.rego | 2 -- 3 files changed, 6 deletions(-) diff --git a/testdata/simple/auth.rego b/testdata/simple/auth.rego index 2257183..676acf8 100644 --- a/testdata/simple/auth.rego +++ b/testdata/simple/auth.rego @@ -1,7 +1,5 @@ package system.authz -import rego.v1 - default allow := false allow if { diff --git a/testdata/simple/policy.rego b/testdata/simple/policy.rego index b4cce25..0846e39 100644 --- a/testdata/simple/policy.rego +++ b/testdata/simple/policy.rego @@ -1,7 +1,5 @@ package policy -import rego.v1 - echo := { "decision": true, "context": { diff --git a/testdata/simple/system.rego b/testdata/simple/system.rego index b2f826b..f269463 100644 --- a/testdata/simple/system.rego +++ b/testdata/simple/system.rego @@ -1,7 +1,5 @@ package system -import rego.v1 - # This is used to exercise the default query functionality. msg := "this is the default path"