Skip to content

Commit e9738a4

Browse files
authored
Merge pull request #107 from xenit-eu/ACC-2351
ACC-2351 Update OPA version and add test for abac policy
2 parents 8e3f031 + 807b94b commit e9738a4

File tree

10 files changed

+2619
-10
lines changed

10 files changed

+2619
-10
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33

44
# Ignore Gradle build output directory
55
build
6+
7+
8+
.idea

opa-async-java-client/src/test/java/com/contentgrid/opa/client/OpaClientIntegrationTests.java

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66

77
import com.contentgrid.opa.client.api.CompileApi;
88
import com.contentgrid.opa.client.api.CompileApi.PartialEvaluationRequest;
9-
import com.contentgrid.opa.rego.ast.Query;
9+
import com.contentgrid.opa.client.api.DataApi;
10+
import com.contentgrid.opa.client.api.DataApi.GetDataResponse;
11+
import com.contentgrid.opa.client.api.PolicyApi.ListPoliciesResponse;
1012
import com.contentgrid.opa.client.rest.http.HttpStatusException;
1113
import com.contentgrid.opa.rego.ast.Expression;
14+
import com.contentgrid.opa.rego.ast.Query;
1215
import com.contentgrid.opa.rego.ast.Term;
1316
import com.contentgrid.opa.rego.ast.Term.Ref;
14-
import com.contentgrid.opa.client.api.DataApi;
15-
import com.contentgrid.opa.client.api.DataApi.GetDataResponse;
16-
import com.contentgrid.opa.client.api.PolicyApi.ListPoliciesResponse;
17+
import com.contentgrid.opa.rego.ast.Term.Text;
18+
import com.contentgrid.opa.rego.ast.Term.Var;
1719
import java.io.IOException;
1820
import java.io.UncheckedIOException;
1921
import java.nio.charset.StandardCharsets;
@@ -40,12 +42,12 @@
4042
@Testcontainers
4143
class OpaClientIntegrationTests {
4244

43-
private static final DockerImageName OPA_IMAGE = DockerImageName.parse("openpolicyagent/opa:0.70.0");
45+
private static final DockerImageName OPA_IMAGE = DockerImageName.parse("openpolicyagent/opa:1.9.0");
4446
private static final int OPA_EXPOSED_PORT = 8181;
4547

4648
@Container
4749
private static final GenericContainer<?> opaContainer = new GenericContainer<>(OPA_IMAGE)
48-
.withCommand(String.format("run --server --addr :%d", OPA_EXPOSED_PORT))
50+
.withCommand(String.format("run --server --addr :%d --v0-compatible", OPA_EXPOSED_PORT))
4951
.withExposedPorts(OPA_EXPOSED_PORT)
5052
.waitingFor(Wait.forHttp("/"));
5153

@@ -68,8 +70,8 @@ void opaIsRunningInDocker() {
6870
@Nested
6971
class PolicyApiTests {
7072

71-
private static final String PATH_EXAMPLE_1 = "fixtures/openpolicyagent.org/docs/policy/policies-example-1.txt";
72-
private static final String PATH_EXAMPLE_2 = "fixtures/openpolicyagent.org/docs/policy/policies-example-2.txt";
73+
private static final String PATH_EXAMPLE_1 = "fixtures/openpolicyagent.org/docs/policy/policies-example-1.rego";
74+
private static final String PATH_EXAMPLE_2 = "fixtures/openpolicyagent.org/docs/policy/policies-example-2.rego";
7375

7476
@Test
7577
@Order(1)
@@ -195,7 +197,7 @@ void adhocQuery() throws IOException {
195197
@Nested
196198
class CompileApiTests {
197199

198-
public static final String POLICY_PATH = "fixtures/openpolicyagent.org/docs/compile/compile-api-policy.txt";
200+
public static final String POLICY_PATH = "fixtures/openpolicyagent.org/docs/compile/compile-api-policy.rego";
199201

200202
@Test
201203
void unknownInputX_largerThan0() {
@@ -284,6 +286,76 @@ void compileExample() {
284286
})));
285287
}
286288

289+
@Test
290+
void abacExample() {
291+
opaClient.upsertPolicy("abac-example", loadResourceAsString(
292+
"fixtures/openpolicyagent.org/docs/compile/abac-policy.rego")).join();
293+
294+
var request = new PartialEvaluationRequest(
295+
"data.abac.example.allow == true",
296+
Map.of("request",
297+
Map.of("headers", Map.of("content-type", "application/json"),
298+
"method", "GET",
299+
"path", List.of("tests")
300+
),
301+
"auth", Map.of(
302+
"authenticated", true,
303+
"principal", Map.of(
304+
"kind", "user",
305+
"contentgrid:att1", List.of("att1v1", "att1v2"),
306+
"contentgrid:att2", List.of("att2v1", "att2v2")
307+
)
308+
)
309+
), List.of("input.entity"));
310+
311+
var result = opaClient.compile(request).join();
312+
assertThat(result).isNotNull();
313+
assertThat(result.getResult()).isNotNull();
314+
315+
assertThat(result.getResult().getQueries())
316+
.isNotNull()
317+
// 4 queries are generated, because there are 4 combinations of the 2 attributes in the policy
318+
.hasSize(4)
319+
.allSatisfy(
320+
query -> assertThat(query)
321+
// There are 2 expressions per query, one for every user attribute in the policy
322+
.hasSize(2)
323+
.allSatisfy(expr -> {
324+
// each expression has 3 terms (the 'eq' operator, the attribute value and the input value)
325+
assertThat(expr.getTerms())
326+
.hasSize(3)
327+
.anySatisfy(
328+
term -> {
329+
assertThat(term).isInstanceOfSatisfying(Ref.class, ref -> {
330+
assertThat(ref.getValue()).singleElement().satisfies(
331+
t -> assertThat(t).hasToString("eq")
332+
);
333+
});
334+
}
335+
);
336+
})
337+
)
338+
.anySatisfy(query -> {
339+
assertThat(query).anySatisfy(
340+
expr -> assertThat(expr.getTerms())
341+
.isEqualTo(List.of(
342+
new Ref(List.of(new Var("eq"))),
343+
new Text("att1v1"),
344+
new Ref(List.of(
345+
new Var("input"),
346+
new Text("entity"),
347+
new Text("a")
348+
)
349+
)
350+
)
351+
352+
)
353+
);
354+
355+
})
356+
;
357+
}
358+
287359
@Test
288360
void example_alwaysTrue() {
289361
opaClient.upsertPolicy("compile-example", loadResourceAsString(POLICY_PATH)).join();
@@ -343,7 +415,7 @@ class Scenarios {
343415
*/
344416
@Test
345417
void partialEval_getApiDocuments() {
346-
final String POLICY_PATH = "fixtures/scenarios/api-documents-policy.txt";
418+
final String POLICY_PATH = "fixtures/scenarios/api-documents-policy.rego";
347419
opaClient.upsertPolicy("test", loadResourceAsString(POLICY_PATH)).join();
348420

349421
var result = opaClient.compile(
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.contentgrid.opa.client.api;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.junit.jupiter.api.Assertions.*;
5+
6+
import com.contentgrid.opa.client.api.PolicyApi.ListPoliciesResponse;
7+
import com.contentgrid.opa.rego.ast.Term;
8+
import com.fasterxml.jackson.databind.DeserializationFeature;
9+
import com.fasterxml.jackson.databind.json.JsonMapper;
10+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
11+
import org.junit.jupiter.api.Test;
12+
13+
class PolicyApiTest {
14+
15+
@Test
16+
void testPoliciesResponseObjectMapping() {
17+
var objectMapper = JsonMapper.builder()
18+
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
19+
.build()
20+
.registerModule(new JavaTimeModule());
21+
22+
// read listpoliciesresponse.json into ListPoliciesResponse
23+
try (var is = getClass().getClassLoader().getResourceAsStream(
24+
"com/contentgrid/opa/client/api/policyapi/listpoliciesresponse.json")) {
25+
var response = objectMapper.readValue(is, ListPoliciesResponse.class);
26+
assertNotNull(response);
27+
assertThat(response.getResult().get(2).getAst().getRules().get(1).getBody()).singleElement().satisfies(expression -> {
28+
assertThat(expression.getTerms()).singleElement().isInstanceOfSatisfying(Term.Bool.class, boolTerm -> {
29+
assertThat(boolTerm.getValue()).isTrue();
30+
});
31+
});
32+
} catch (Exception e) {
33+
fail("Failed to deserialize ListPoliciesResponse", e);
34+
}
35+
}
36+
37+
}

0 commit comments

Comments
 (0)