Skip to content

Commit

Permalink
Merge pull request #705 from MrCreosote/develop
Browse files Browse the repository at this point in the history
Add WorkspaceAdministration.ensureAdminRole
  • Loading branch information
MrCreosote authored Oct 24, 2023
2 parents 0c2b4e7 + e07e8d7 commit b4e64db
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/us/kbase/workspace/database/Workspace.java
Original file line number Diff line number Diff line change
Expand Up @@ -1627,8 +1627,8 @@ public long setWorkspaceDeleted(

/** Set administrator metadata on one or more objects.
*
* This method should not be exposed in a public API; it is restricted to administrator
* use only.
* This method should not be exposed in a public API; it is restricted to administrators
* with full privileges only.
*
* Only direct object access is supported; reference paths and object DAG
* searches are not allowed (which are not necessary for admins in any case).
Expand Down
9 changes: 4 additions & 5 deletions src/us/kbase/workspace/kbase/admin/AdminRole.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
*/
public enum AdminRole {

/** Full administration privileges. */
ADMIN,
/** No administration privileges. */
NONE,

/** Read only privileges. */
READ_ONLY,

/** No administration privileges. */
NONE;

/** Full administration privileges. */
ADMIN;
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@

/** Builds the standard set of administration command handlers. */
public class AdministrationCommandSetInstaller {

/* NOTE FOR FUTURE DEVS:
* Doing admin methods this way was probably a mistake. It makes them a real pain to use
* as you have to go to the admin interface documentation, find the method you want,
* flip back to the API documentation to figure out the data structures for the method,
* flip back to the admin docs to figure out the overall structure, etc. etc.
*
* In the future, instead of adding more admin methods, we should just add standard API
* methods that check the user's admin status with an `asAdmin` boolean toggle if the method
* is applicable to admins and non-admins. This keeps the `sudo` like protections for admin
* methods.
*
* Currently there are no plans to revamp all the current admin methods - the time spent
* there would be better spent converting the workspace from JSON-RPC to a more REST like
* interface.
*/

private static final String GET_TYPE_DELEGATION_TARGET = "getTypeDelegationTarget";
private static final String DENY_MOD_REQUEST = "denyModRequest";
Expand Down
20 changes: 20 additions & 0 deletions src/us/kbase/workspace/kbase/admin/WorkspaceAdministration.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,26 @@ public AdminRole call() throws AdministratorHandlerException {
throw (AdministratorHandlerException) e.getCause();
}
}

/** Ensure that a user has a particular administrative role.
* @param token the user's token.
* @param requiredRole the required administrative role.
* @param failMessage the message for the exception thrown if the user doesn't have a
* role with the required privileges.
* @throws AdministratorHandlerException if an error occurs looking up the user's role.
* @throws AuthException if the user does not possess the required role.
*/
public void ensureAdminRole(
final AuthToken token,
final AdminRole requiredRole,
final String failMessage)
throws AdministratorHandlerException, AuthException {
requireNonNull(requiredRole, "requiredRole");
final AdminRole role = getAdminRole(token);
if (role.compareTo(requiredRole) < 0) {
throw new AuthException(failMessage);
}
}

/** Run an administration command.
* @param token the administrator's token.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import us.kbase.auth.AuthException;
import us.kbase.auth.AuthToken;
import us.kbase.common.service.JsonTokenStream;
import us.kbase.common.service.UObject;
Expand Down Expand Up @@ -217,6 +218,65 @@ private void getAdminRole(final AdminRole role) throws AdministratorHandlerExcep
is(role));
}

@Test
public void ensureAdminRole() throws Exception {
ensureAdminRole(AdminRole.NONE, AdminRole.NONE);
ensureAdminRole(AdminRole.NONE, AdminRole.READ_ONLY);
ensureAdminRole(AdminRole.NONE, AdminRole.ADMIN);
ensureAdminRole(AdminRole.READ_ONLY, AdminRole.READ_ONLY);
ensureAdminRole(AdminRole.READ_ONLY, AdminRole.ADMIN);
ensureAdminRole(AdminRole.ADMIN, AdminRole.ADMIN);
}

private void ensureAdminRole(final AdminRole required, final AdminRole has)
throws Exception {
final TestMocks mocks = initTestMocks();
when(mocks.ah.getAdminRole(new AuthToken("t", "u"))).thenReturn(has);

mocks.admin.ensureAdminRole(new AuthToken("t", "u"), required, "no message");
}

@Test
public void ensureAdminRoleFailNulls() throws Exception {
final WorkspaceAdministration a = initTestMocks().admin;

ensureAdminRoleFail(a, null, AdminRole.ADMIN, "oops",
new NullPointerException("token"));
ensureAdminRoleFail(a, new AuthToken("t", "u"), null, "oops",
new NullPointerException("requiredRole"));
}

@Test
public void ensureAdminRoleFailUnAuthorized() throws Exception {
final TestMocks mocks = initTestMocks();

final WorkspaceAdministration a = mocks.admin;
final AuthToken t = new AuthToken("t", "u");
final AdminRole r = AdminRole.READ_ONLY;
final AdminRole f = AdminRole.ADMIN;

when(mocks.ah.getAdminRole(t))
.thenReturn(AdminRole.NONE, AdminRole.NONE, AdminRole.READ_ONLY, null);

ensureAdminRoleFail(a, t, r, "read req", new AuthException("read req"));
ensureAdminRoleFail(a, t, f, "full req", new AuthException("full req"));
ensureAdminRoleFail(a, t, f, "full req 2", new AuthException("full req 2"));
}

private void ensureAdminRoleFail(
final WorkspaceAdministration admin,
final AuthToken token,
final AdminRole required,
final String message,
final Exception expected) {
try {
admin.ensureAdminRole(token, required, message);
fail("expected exception");
} catch (Exception got) {
TestCommon.assertExceptionCorrect(got, expected);
}
}

@Test
public void getAdminRoleFail() {
try {
Expand Down

0 comments on commit b4e64db

Please sign in to comment.