Skip to content

Commit

Permalink
test: add integration tests for add-/remove-/has-permission
Browse files Browse the repository at this point in the history
  • Loading branch information
bevzzz committed Jan 23, 2025
1 parent 4895040 commit 01a55ad
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 36 deletions.
16 changes: 11 additions & 5 deletions src/main/java/io/weaviate/client/v1/rbac/api/PermissionAdder.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
import io.weaviate.client.base.Result;
import io.weaviate.client.base.http.HttpClient;
import io.weaviate.client.v1.rbac.model.Permission;
import lombok.AllArgsConstructor;

public class PermissionAdder extends BaseClient<Void> implements ClientResult<Void> {
private String name;
private String role;
private List<Permission<?>> permissions = new ArrayList<>();

public PermissionAdder(HttpClient httpClient, Config config) {
super(httpClient, config);
}

public PermissionAdder withName(String name) {
this.name = name;
public PermissionAdder withRole(String name) {
this.role = name;
return this;
}

Expand All @@ -29,13 +30,18 @@ public PermissionAdder withPermissions(Permission<?>... permissions) {
return this;
}

@AllArgsConstructor
private static class Body {
public final List<?> permissions;
}

@Override
public Result<Void> run() {
List<WeaviatePermission> permissions = WeaviatePermission.mergePermissions(this.permissions);
return new Result<Void>(sendPostRequest(path(), permissions, Void.class));
return new Result<Void>(sendPostRequest(path(), new Body(permissions), Void.class));
}

private String path() {
return String.format("/authz/roles/%s/add-permissions", this.name);
return String.format("/authz/roles/%s/add-permissions", this.role);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import io.weaviate.client.v1.rbac.model.Permission;

public class PermissionChecker extends BaseClient<Boolean> implements ClientResult<Boolean> {
private String name;
private String role;
private Permission<?> permission;

public PermissionChecker(HttpClient httpClient, Config config) {
super(httpClient, config);
}

public PermissionChecker withName(String name) {
this.name = name;
public PermissionChecker withRole(String role) {
this.role = role;
return this;
}

Expand All @@ -27,10 +27,10 @@ public PermissionChecker withPermission(Permission<?> permission) {

@Override
public Result<Boolean> run() {
return new Result<Boolean>(sendPostRequest(path(), permission, Boolean.class));
return new Result<Boolean>(sendPostRequest(path(), permission.toWeaviate(), Boolean.class));
}

private String path() {
return String.format("/authz/roles/%s/has-permission", this.name);
return String.format("/authz/roles/%s/has-permission", this.role);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
import io.weaviate.client.base.Result;
import io.weaviate.client.base.http.HttpClient;
import io.weaviate.client.v1.rbac.model.Permission;
import lombok.AllArgsConstructor;

public class PermissionRemover extends BaseClient<Void> implements ClientResult<Void> {
private String name;
private String role;
private List<Permission<?>> permissions = new ArrayList<>();

public PermissionRemover(HttpClient httpClient, Config config) {
super(httpClient, config);
}

public PermissionRemover withName(String name) {
this.name = name;
public PermissionRemover withRole(String role) {
this.role = role;
return this;
}

Expand All @@ -29,13 +30,18 @@ public PermissionRemover withPermissions(Permission<?>... permissions) {
return this;
}

@AllArgsConstructor
private static class Body {
public final List<?> permissions;
}

@Override
public Result<Void> run() {
List<WeaviatePermission> permissions = WeaviatePermission.mergePermissions(this.permissions);
return new Result<Void>(sendPostRequest(path(), permissions, Void.class));
return new Result<Void>(sendPostRequest(path(), new Body(permissions), Void.class));
}

private String path() {
return String.format("/authz/roles/%s/remove-permissions", this.name);
return String.format("/authz/roles/%s/remove-permissions", this.role);
}
}
4 changes: 2 additions & 2 deletions src/main/java/io/weaviate/client/v1/rbac/api/RoleGetter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public RoleGetter withName(String name) {
@Override
public Result<Role> run() {
Response<WeaviateRole> resp = sendGetRequest("/authz/roles/" + this.name, WeaviateRole.class);
WeaviateRole role = Optional.ofNullable(resp.getBody()).orElse(null);
return new Result<Role>(resp.getStatusCode(), role.toRole(), resp.getErrors());
Role role = Optional.ofNullable(resp.getBody()).map(WeaviateRole::toRole).orElse(null);
return new Result<Role>(resp.getStatusCode(), role, resp.getErrors());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static Permission<?> fromWeaviate(WeaviatePermission perm) {
return new UsersPermission(action);
}
return null;
};
}

public static BackupsPermission backups(BackupsPermission.Action action, String collection) {
return new BackupsPermission(action, collection);
Expand Down Expand Up @@ -75,6 +75,11 @@ public static TenantsPermission tenants(TenantsPermission.Action action) {
// public static UsersPermission users(UsersPermission.Action action) {
// return new UsersPermission(action);
// }

public String toString() {
return String.format("Permission<action=%s>", this.action);
}

}

interface CustomAction {
Expand Down
104 changes: 86 additions & 18 deletions src/test/java/io/weaviate/integration/client/rbac/ClientRbacTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.InstanceOfAssertFactories.list;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.util.List;

Expand All @@ -14,6 +18,7 @@

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;
import io.weaviate.client.WeaviateClient;
import io.weaviate.client.base.Result;
import io.weaviate.client.v1.auth.exception.AuthException;
import io.weaviate.client.v1.rbac.Roles;
Expand Down Expand Up @@ -73,39 +78,94 @@ public void testGetAll() {
// paramter

@Test
public void testCreateAndList() {
public void testCreate() {
String myRole = roleName("VectorOwner");
String myCollection = "Pizza";

Permission<?>[] wantPermissions = new Permission<?>[] {
Permission.backups(BackupsPermission.Action.MANAGE, myCollection),
Permission.cluster(ClusterPermission.Action.READ),
Permission.nodes(NodesPermission.Action.READ, Verbosity.MINIMAL, myCollection),
Permission.roles(RolesPermission.Action.MANAGE, viewerRole),
Permission.collections(CollectionsPermission.Action.CREATE, myCollection),
Permission.data(DataPermission.Action.UPDATE, myCollection),
Permission.tenants(TenantsPermission.Action.DELETE),
};

try {
// Arrange
roles.deleter().withName(myRole).run();

// Act
roles.creator().withName(myRole)
.withPermissions(
Permission.backups(BackupsPermission.Action.MANAGE, myCollection),
Permission.cluster(ClusterPermission.Action.READ),
Permission.nodes(NodesPermission.Action.READ, Verbosity.MINIMAL, myCollection),
Permission.roles(RolesPermission.Action.MANAGE, viewerRole),
Permission.collections(CollectionsPermission.Action.CREATE, myCollection),
Permission.data(DataPermission.Action.UPDATE, myCollection),
Permission.tenants(TenantsPermission.Action.DELETE))
.withPermissions(wantPermissions)
.run();
assumeTrue(checkRoleExists(myRole), "role should exist after creation");

Result<Role> response = roles.getter().withName(myRole).run();
Role role = response.getResult();
assertThat(response.getError()).as("result had errors").isNull();
assertNull("error fetching a role", response.getError());
assertThat(role).as("wrong role name").returns(myRole, Role::getName);

List<? extends Permission<?>> permissions = role.getPermissions();
assertTrue(hasPermissionWithAction(permissions, BackupsPermission.Action.MANAGE.getValue()));
assertTrue(hasPermissionWithAction(permissions, ClusterPermission.Action.READ.getValue()));
assertTrue(hasPermissionWithAction(permissions, NodesPermission.Action.READ.getValue()));
assertTrue(hasPermissionWithAction(permissions, RolesPermission.Action.MANAGE.getValue()));
assertTrue(hasPermissionWithAction(permissions, CollectionsPermission.Action.CREATE.getValue()));
assertTrue(hasPermissionWithAction(permissions, DataPermission.Action.UPDATE.getValue()));
assertTrue(hasPermissionWithAction(permissions, TenantsPermission.Action.DELETE.getValue()));
for (int i = 0; i < wantPermissions.length; i++) {
Permission<?> perm = wantPermissions[i];
assertTrue("should have permission " + perm, hasPermission(myRole, perm));
}
} finally {
roles.deleter().withName(myRole).run();
assertFalse("should not exist after deletion", checkRoleExists(myRole));
}
}

@Test
public void testAddPermissions() {
String myRole = roleName("VectorOwner");
Permission<?> toAdd = Permission.cluster(ClusterPermission.Action.READ);
try {
// Arrange
roles.creator().withName(myRole)
.withPermissions(Permission.tenants(TenantsPermission.Action.DELETE))
.run();
assumeTrue(checkRoleExists(myRole), "role should exist after creation");

// Act
Result<?> addResult = roles.permissionAdder().withRole(myRole)
.withPermissions(toAdd)
.run();
assertNull("add-permissions operation error", addResult.getError());

// Assert
assertTrue("should have permission " + toAdd, hasPermission(myRole, toAdd));
} finally {
roles.deleter().withName(myRole).run();
assertFalse("should not exist after deletion", checkRoleExists(myRole));
}
}

@Test
public void testRemovePermissions() {
String myRole = roleName("VectorOwner");
Permission<?> toRemove = Permission.tenants(TenantsPermission.Action.DELETE);
try {
// Arrange
roles.creator().withName(myRole)
.withPermissions(
Permission.cluster(ClusterPermission.Action.READ),
Permission.tenants(TenantsPermission.Action.DELETE))
.run();
assumeTrue(checkRoleExists(myRole), "role should exist after creation");

// Act
Result<?> addResult = roles.permissionRemover().withRole(myRole)
.withPermissions(toRemove)
.run();
assertNull("remove-permissions operation error", addResult.getError());

// Assert
assertFalse("should not have permission " + toRemove, hasPermission(myRole, toRemove));
} finally {
roles.deleter().withName(myRole).run();
assertFalse("should not exist after deletion", checkRoleExists(myRole));
}
}

Expand All @@ -114,9 +174,17 @@ private String roleName(String name) {
return String.format("%s-%s", currentTest.getMethodName(), name);
}

private boolean hasPermission(String role, Permission<? extends Permission<?>> perm) {
return roles.permissionChecker().withRole(role).withPermission(perm).run().getResult();
}

private boolean hasPermissionWithAction(List<? extends Permission<?>> permissions, String action) {
return permissions.stream()
.filter(perm -> perm.getAction().equals(action))
.findFirst().isPresent();
}

private boolean checkRoleExists(String role) {
return roles.exists().withName(role).run().getResult();
}
}

0 comments on commit 01a55ad

Please sign in to comment.