diff --git a/deployment/src/main/java/io/quarkiverse/openfga/deployment/DevServicesOpenFGAProcessor.java b/deployment/src/main/java/io/quarkiverse/openfga/deployment/DevServicesOpenFGAProcessor.java index 6436a38..13875e2 100644 --- a/deployment/src/main/java/io/quarkiverse/openfga/deployment/DevServicesOpenFGAProcessor.java +++ b/deployment/src/main/java/io/quarkiverse/openfga/deployment/DevServicesOpenFGAProcessor.java @@ -49,7 +49,7 @@ public class DevServicesOpenFGAProcessor { private static final Logger log = Logger.getLogger(DevServicesOpenFGAProcessor.class); - static final String OPEN_FGA_VERSION = "v1.0.1"; + static final String OPEN_FGA_VERSION = "v1.4.3"; static final String OPEN_FGA_IMAGE = "openfga/openfga:" + OPEN_FGA_VERSION; static final int OPEN_FGA_EXPOSED_HTTP_PORT = 8080; static final int OPEN_FGA_EXPOSED_GRPC_PORT = 8081; diff --git a/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelClientTest.java b/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelClientTest.java index 616156b..8dce59b 100644 --- a/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelClientTest.java +++ b/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelClientTest.java @@ -59,7 +59,7 @@ public void createTestStoreAndModel() { Map.of("reader", new RelationMetadata(List.of(new RelationReference("user"))), "writer", new RelationMetadata(List.of(new RelationReference("user")))))); - var typeDefs = new TypeDefinitions(List.of(useTypeDef, documentTypeDef)); + var typeDefs = new TypeDefinitions("1.1", List.of(useTypeDef, documentTypeDef)); var authModelId = storeClient.authorizationModels().create(typeDefs) .subscribe().withSubscriber(UniAssertSubscriber.create()) diff --git a/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelsClientTest.java b/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelsClientTest.java index f6d99d2..cc6f2bb 100644 --- a/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelsClientTest.java +++ b/deployment/src/test/java/io/quarkiverse/openfga/test/AuthorizationModelsClientTest.java @@ -62,7 +62,7 @@ public void canList() { new Metadata( Map.of("reader", new RelationMetadata(List.of(new RelationReference("user")))))); - var typeDefinitions = new TypeDefinitions(List.of(userTypeDef, documentTypeDef)); + var typeDefinitions = new TypeDefinitions("1.1", List.of(userTypeDef, documentTypeDef)); for (int c = 0; c < 4; c++) { authorizationModelsClient.create(typeDefinitions) diff --git a/deployment/src/test/java/io/quarkiverse/openfga/test/DefaultAuthorizationModelClientTest.java b/deployment/src/test/java/io/quarkiverse/openfga/test/DefaultAuthorizationModelClientTest.java index ad1e975..e46faf8 100644 --- a/deployment/src/test/java/io/quarkiverse/openfga/test/DefaultAuthorizationModelClientTest.java +++ b/deployment/src/test/java/io/quarkiverse/openfga/test/DefaultAuthorizationModelClientTest.java @@ -59,7 +59,9 @@ public void createTestStoreAndModel() { Map.of("reader", new RelationMetadata(List.of(new RelationReference("user"))), "writer", new RelationMetadata(List.of(new RelationReference("user")))))); - storeClient.authorizationModels().create(List.of(userTypeDef, documentTypeDef)) + var documentTypeDefs = new TypeDefinitions("1.1", List.of(userTypeDef, documentTypeDef)); + + storeClient.authorizationModels().create(documentTypeDefs) .subscribe().withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); diff --git a/integration-tests/src/test/resources/auth-model.json b/integration-tests/src/test/resources/auth-model.json index 59f875d..48683bd 100644 --- a/integration-tests/src/test/resources/auth-model.json +++ b/integration-tests/src/test/resources/auth-model.json @@ -1,4 +1,5 @@ { + "schema_version": "1.1", "type_definitions": [ { "type": "user" diff --git a/model/src/main/java/io/quarkiverse/openfga/client/model/AuthorizationModel.java b/model/src/main/java/io/quarkiverse/openfga/client/model/AuthorizationModel.java index d9142a4..68b837d 100644 --- a/model/src/main/java/io/quarkiverse/openfga/client/model/AuthorizationModel.java +++ b/model/src/main/java/io/quarkiverse/openfga/client/model/AuthorizationModel.java @@ -1,6 +1,7 @@ package io.quarkiverse.openfga.client.model; import java.util.List; +import java.util.Map; import java.util.Objects; import javax.annotation.Nullable; @@ -13,12 +14,16 @@ public final class AuthorizationModel { private final String id; private final String schemaVersion; private final List typeDefinitions; + @Nullable + private final Map conditions; public AuthorizationModel(String id, @JsonProperty("schema_version") String schemaVersion, - @JsonProperty("type_definitions") List typeDefinitions) { + @JsonProperty("type_definitions") List typeDefinitions, + @JsonProperty("conditions") @Nullable Map conditions) { this.id = Preconditions.parameterNonNull(id, "id"); this.schemaVersion = Preconditions.parameterNonNull(schemaVersion, "schemaVersion"); this.typeDefinitions = Preconditions.parameterNonNull(typeDefinitions, "typeDefinitions"); + this.conditions = conditions; } public String getId() { @@ -35,6 +40,12 @@ public List getTypeDefinitions() { return typeDefinitions; } + @JsonProperty("conditions") + @Nullable + public Map getConditions() { + return conditions; + } + @Override public boolean equals(@Nullable Object obj) { if (obj == this) @@ -43,19 +54,21 @@ public boolean equals(@Nullable Object obj) { return false; var that = (AuthorizationModel) obj; return Objects.equals(this.id, that.id) && - Objects.equals(this.typeDefinitions, that.typeDefinitions); + Objects.equals(this.typeDefinitions, that.typeDefinitions) && + Objects.equals(this.conditions, that.conditions); } @Override public int hashCode() { - return Objects.hash(id, typeDefinitions); + return Objects.hash(id, typeDefinitions, conditions); } @Override public String toString() { return "AuthorizationModel[" + "id=" + id + ", " + - "typeDefinitions=" + typeDefinitions + ']'; + "typeDefinitions=" + typeDefinitions + ", " + + "conditions=" + conditions + ']'; } } diff --git a/model/src/main/java/io/quarkiverse/openfga/client/model/Condition.java b/model/src/main/java/io/quarkiverse/openfga/client/model/Condition.java new file mode 100644 index 0000000..8aaa5ab --- /dev/null +++ b/model/src/main/java/io/quarkiverse/openfga/client/model/Condition.java @@ -0,0 +1,78 @@ +package io.quarkiverse.openfga.client.model; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Condition { + + public static class Parameter { + + private final String typeName; + private final List genericTypes; + + public Parameter(@JsonProperty("type_name") String typeName, @JsonProperty("generic_types") List genericTypes) { + this.typeName = typeName; + this.genericTypes = genericTypes; + } + + @JsonProperty("type_name") + public String getTypeName() { + return typeName; + } + + @JsonProperty("generic_types") + public List getGenericTypes() { + return genericTypes; + } + } + + private final String name; + private final String expression; + private final Map parameters; + + public Condition(String name, String expression, Map parameters) { + this.name = name; + this.expression = expression; + this.parameters = parameters; + } + + public String getName() { + return name; + } + + public String getExpression() { + return expression; + } + + public Map getParameters() { + return parameters; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Condition condition = (Condition) o; + return Objects.equals(name, condition.name) && Objects.equals(expression, condition.expression) + && Objects.equals(parameters, condition.parameters); + } + + @Override + public int hashCode() { + return Objects.hash(name, expression, parameters); + } + + @Override + public String toString() { + return "Condition{" + + "name='" + name + '\'' + + ", expression='" + expression + '\'' + + ", parameters=" + parameters + + '}'; + } +} diff --git a/model/src/main/java/io/quarkiverse/openfga/client/model/RelationReference.java b/model/src/main/java/io/quarkiverse/openfga/client/model/RelationReference.java index 329e34f..6e045da 100644 --- a/model/src/main/java/io/quarkiverse/openfga/client/model/RelationReference.java +++ b/model/src/main/java/io/quarkiverse/openfga/client/model/RelationReference.java @@ -12,20 +12,23 @@ public class RelationReference { String relation; @Nullable Object wildcard; + @Nullable + String condition; @JsonCreator - public RelationReference(String type, @Nullable String relation, @Nullable Object wildcard) { + public RelationReference(String type, @Nullable String relation, @Nullable Object wildcard, @Nullable String condition) { this.type = type; this.relation = relation; this.wildcard = wildcard; + this.condition = condition; } public RelationReference(String type) { - this(type, null, null); + this(type, null, null, null); } public RelationReference(String type, String relation) { - this(type, relation, null); + this(type, relation, null, null); } public String getType() { @@ -42,6 +45,11 @@ public Object getWildcard() { return wildcard; } + @Nullable + public String getCondition() { + return condition; + } + @Override public boolean equals(Object o) { if (this == o) @@ -50,12 +58,12 @@ public boolean equals(Object o) { return false; RelationReference that = (RelationReference) o; return Objects.equals(type, that.type) && Objects.equals(relation, that.relation) - && Objects.equals(wildcard, that.wildcard); + && Objects.equals(wildcard, that.wildcard) && Objects.equals(condition, that.condition); } @Override public int hashCode() { - return Objects.hash(type, relation, wildcard); + return Objects.hash(type, relation, wildcard, condition); } @Override @@ -63,7 +71,8 @@ public String toString() { return "RelationReference{" + "type='" + type + '\'' + ", relation='" + relation + '\'' + - ", wildcard=" + wildcard + + ", wildcard=" + wildcard + '\'' + + ", condition='" + condition + '\'' + '}'; } } diff --git a/model/src/main/java/io/quarkiverse/openfga/client/model/RelationshipCondition.java b/model/src/main/java/io/quarkiverse/openfga/client/model/RelationshipCondition.java new file mode 100644 index 0000000..455d1b6 --- /dev/null +++ b/model/src/main/java/io/quarkiverse/openfga/client/model/RelationshipCondition.java @@ -0,0 +1,45 @@ +package io.quarkiverse.openfga.client.model; + +import java.util.Objects; + +public class RelationshipCondition { + + private final String name; + private final Object context; + + public RelationshipCondition(String name, Object context) { + this.name = name; + this.context = context; + } + + public String getName() { + return name; + } + + public Object getContext() { + return context; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + RelationshipCondition that = (RelationshipCondition) o; + return Objects.equals(name, that.name) && Objects.equals(context, that.context); + } + + @Override + public int hashCode() { + return Objects.hash(name, context); + } + + @Override + public String toString() { + return "RelationshipCondition{" + + "name='" + name + '\'' + + ", context=" + context + + '}'; + } +} diff --git a/model/src/main/java/io/quarkiverse/openfga/client/model/TupleKey.java b/model/src/main/java/io/quarkiverse/openfga/client/model/TupleKey.java index 912183f..daaabfe 100644 --- a/model/src/main/java/io/quarkiverse/openfga/client/model/TupleKey.java +++ b/model/src/main/java/io/quarkiverse/openfga/client/model/TupleKey.java @@ -10,15 +10,17 @@ public final class TupleKey { private final String object; private final String relation; private final String user; + private final RelationshipCondition condition; - public TupleKey(String object, String relation, String user) { + public TupleKey(String object, String relation, String user, @Nullable RelationshipCondition condition) { this.object = Preconditions.parameterNonNull(object, "object"); this.relation = Preconditions.parameterNonNull(relation, "relation"); this.user = Preconditions.parameterNonNull(user, "user"); + this.condition = condition; } public static TupleKey of(String object, String relation, String user) { - return new TupleKey(object, relation, user); + return new TupleKey(object, relation, user, null); } public String getObject() { @@ -33,6 +35,11 @@ public String getUser() { return user; } + @Nullable + public RelationshipCondition getCondition() { + return condition; + } + @Override public boolean equals(@Nullable Object obj) { if (obj == this) @@ -42,12 +49,13 @@ public boolean equals(@Nullable Object obj) { var that = (TupleKey) obj; return Objects.equals(this.object, that.object) && Objects.equals(this.relation, that.relation) && - Objects.equals(this.user, that.user); + Objects.equals(this.user, that.user) && + Objects.equals(this.condition, that.condition); } @Override public int hashCode() { - return Objects.hash(object, relation, user); + return Objects.hash(object, relation, user, condition); } @Override @@ -55,7 +63,8 @@ public String toString() { return "TupleKey[" + "object=" + object + ", " + "relation=" + relation + ", " + - "user=" + user + ']'; + "user=" + user + ", " + + "condition=" + condition + ']'; } } diff --git a/model/src/main/java/io/quarkiverse/openfga/client/model/dto/GetStoreResponse.java b/model/src/main/java/io/quarkiverse/openfga/client/model/dto/GetStoreResponse.java index 9fda05f..2bf1cf2 100644 --- a/model/src/main/java/io/quarkiverse/openfga/client/model/dto/GetStoreResponse.java +++ b/model/src/main/java/io/quarkiverse/openfga/client/model/dto/GetStoreResponse.java @@ -20,14 +20,19 @@ public final class GetStoreResponse { private final OffsetDateTime createdAt; @JsonProperty("updated_at") private final OffsetDateTime updatedAt; + @JsonProperty("deleted_at") + @Nullable + private final OffsetDateTime deletedAt; @JsonCreator(mode = PROPERTIES) public GetStoreResponse(String id, String name, @JsonProperty("created_at") OffsetDateTime createdAt, - @JsonProperty("updated_at") OffsetDateTime updatedAt) { + @JsonProperty("updated_at") OffsetDateTime updatedAt, + @JsonProperty("deleted_at") @Nullable OffsetDateTime deletedAt) { this.id = Preconditions.parameterNonNull(id, "id"); this.name = Preconditions.parameterNonNull(name, "name"); this.createdAt = Preconditions.parameterNonNull(createdAt, "createdAt"); this.updatedAt = Preconditions.parameterNonNull(updatedAt, "updatedAt"); + this.deletedAt = deletedAt; } public Store asStore() { @@ -52,6 +57,12 @@ public OffsetDateTime getUpdatedAt() { return updatedAt; } + @JsonProperty("deleted_at") + @Nullable + public OffsetDateTime getDeletedAt() { + return deletedAt; + } + @Override public boolean equals(@Nullable Object obj) { if (obj == this) @@ -62,12 +73,13 @@ public boolean equals(@Nullable Object obj) { return Objects.equals(this.id, that.id) && Objects.equals(this.name, that.name) && Objects.equals(this.createdAt, that.createdAt) && - Objects.equals(this.updatedAt, that.updatedAt); + Objects.equals(this.updatedAt, that.updatedAt) && + Objects.equals(this.deletedAt, that.deletedAt); } @Override public int hashCode() { - return Objects.hash(id, name, createdAt, updatedAt); + return Objects.hash(id, name, createdAt, updatedAt, deletedAt); } @Override @@ -76,7 +88,8 @@ public String toString() { "id=" + id + ", " + "name=" + name + ", " + "createdAt=" + createdAt + ", " + - "updatedAt=" + updatedAt + ']'; + "updatedAt=" + updatedAt + ", " + + "deletedAt=" + deletedAt + ']'; } } diff --git a/runtime/src/main/java/io/quarkiverse/openfga/client/AuthorizationModelsClient.java b/runtime/src/main/java/io/quarkiverse/openfga/client/AuthorizationModelsClient.java index f493961..ff12eb8 100644 --- a/runtime/src/main/java/io/quarkiverse/openfga/client/AuthorizationModelsClient.java +++ b/runtime/src/main/java/io/quarkiverse/openfga/client/AuthorizationModelsClient.java @@ -37,6 +37,7 @@ public Uni> listAll(@Nullable Integer pageSize) { return collectAllPages(pageSize, this::list); } + @Deprecated public Uni create(List typeDefinitions) { return create(new TypeDefinitions(typeDefinitions)); }