Skip to content

Commit

Permalink
Backport to branch(3) : Add AuthAdmin (#1340)
Browse files Browse the repository at this point in the history
Co-authored-by: Toshihiro Suzuki <[email protected]>
  • Loading branch information
feeblefakie and brfrn169 authored Dec 1, 2023
1 parent 988c937 commit e07d274
Show file tree
Hide file tree
Showing 10 changed files with 399 additions and 3 deletions.
189 changes: 189 additions & 0 deletions core/src/main/java/com/scalar/db/api/AuthAdmin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package com.scalar.db.api;

import com.scalar.db.exception.storage.ExecutionException;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/**
* An interface for administrative operations for authentication and authorization. This interface
* is used for creating and dropping users, and granting and revoking privileges.
*/
public interface AuthAdmin {

/**
* Creates a user with the given username, password and user options. If the password is null, the
* user is created without a password.
*
* @param username the username
* @param password the password. If null, the user is created without a password
* @param userOptions the user options
* @throws ExecutionException if the operation fails
*/
default void createUser(String username, @Nullable String password, UserOption... userOptions)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Alters a user with the given username, password and user options. If the password is null, the
* password is not changed.
*
* @param username the username
* @param password the password. If null, the password is not changed
* @param userOptions the user options
* @throws ExecutionException if the operation fails
*/
default void alterUser(String username, @Nullable String password, UserOption... userOptions)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Drops a user with the given username.
*
* @param username the username
* @throws ExecutionException if the operation fails
*/
default void dropUser(String username) throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Grants privileges to a user for the given table.
*
* @param username the username
* @param namespaceName the namespace name of the table
* @param tableName the table name
* @param privileges the privileges
* @throws ExecutionException if the user does not exist or the operation fails
*/
default void grant(
String username, String namespaceName, String tableName, Privilege... privileges)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Grants privileges to a user for all tables in the given namespace.
*
* @param username the username
* @param namespaceName the namespace name
* @param privileges the privileges
* @throws ExecutionException if the user does not exist or the operation fails
*/
default void grant(String username, String namespaceName, Privilege... privileges)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Revokes privileges from a user for the given table.
*
* @param username the username
* @param namespaceName the namespace name of the table
* @param tableName the table name
* @param privileges the privileges
* @throws ExecutionException if the user does not exist or the operation fails
*/
default void revoke(
String username, String namespaceName, String tableName, Privilege... privileges)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Revokes privileges from a user for all tables in the given namespace.
*
* @param username the username
* @param namespaceName the namespace name
* @param privileges the privileges
* @throws ExecutionException if the user does not exist or the operation fails
*/
default void revoke(String username, String namespaceName, Privilege... privileges)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Retrieve a list of {@link User}s.
*
* @return a list of {@link User}s
* @throws ExecutionException if the operation fails
*/
default List<User> getUsers() throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Retrieve privileges for the given table for the given user.
*
* @param username the username
* @param namespaceName the namespace name of the table
* @param tableName the table name
* @return a set of privileges
* @throws ExecutionException if the user does not exist or the operation fails
*/
default Set<Privilege> getPrivileges(String username, String namespaceName, String tableName)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

/**
* Retrieve privileges for all tables in the given namespace for the given user.
*
* @param username the username
* @param namespaceName the namespace name
* @return a set of privileges
* @throws ExecutionException if the user does not exist or the operation fails
*/
default Set<Privilege> getPrivileges(String username, String namespaceName)
throws ExecutionException {
throw new UnsupportedOperationException("Not supported in the community edition");
}

interface User {
String getName();

boolean isSuperuser();
}

/** The user options. */
enum UserOption {
/** If specified, the user is created as a superuser. */
SUPERUSER,

/**
* If specified, the user is created as a non-superuser. If neither SUPERUSER nor NO_SUPERUSER
* is specified, the user is created as a non-superuser.
*/
NO_SUPERUSER,
}

/** The privileges for ScalarDB operations. */
enum Privilege {
/** The privilege for read (Get and Scan) operations. */
READ,

/** The privilege for write (Put) operations. */
WRITE,

/** The privilege for delete (Delete) operations. */
DELETE,

/** The privilege for creating tables and indexes. */
CREATE,

/** The privilege for dropping tables and indexes. */
DROP,

/** The privilege for truncating tables. */
TRUNCATE,

/** The privilege for altering tables. */
ALTER,

/** The privilege for granting and revoking privileges on tables to other users. */
GRANT
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* An administrative interface for distributed transaction implementations. The user can execute
* administrative operations with it like createNamespace/createTable/getTableMetadata.
*/
public interface DistributedTransactionAdmin extends Admin {
public interface DistributedTransactionAdmin extends Admin, AuthAdmin {

/**
* Creates coordinator namespace and tables.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,64 @@
package com.scalar.db.exception.storage;

import com.scalar.db.api.AuthAdmin;
import java.util.Optional;
import javax.annotation.Nullable;

public class ExecutionException extends Exception {

private final boolean authenticationError;
private final boolean authorizationError;
private final boolean superuserRequired;
@Nullable private final AuthAdmin.Privilege requiredPrivilege;

public ExecutionException(String message) {
super(message);
this(message, false, false, false, null);
}

public ExecutionException(String message, Throwable cause) {
this(message, cause, false, false, false, null);
}

public ExecutionException(
String message,
boolean authenticationError,
boolean authorizationError,
boolean superuserRequired,
@Nullable AuthAdmin.Privilege requiredPrivilege) {
super(message);
this.authenticationError = authenticationError;
this.authorizationError = authorizationError;
this.superuserRequired = superuserRequired;
this.requiredPrivilege = requiredPrivilege;
}

public ExecutionException(
String message,
Throwable cause,
boolean authenticationError,
boolean authorizationError,
boolean superuserRequired,
@Nullable AuthAdmin.Privilege requiredPrivilege) {
super(message, cause);
this.authenticationError = authenticationError;
this.authorizationError = authorizationError;
this.superuserRequired = superuserRequired;
this.requiredPrivilege = requiredPrivilege;
}

public boolean isAuthenticationError() {
return authenticationError;
}

public boolean isAuthorizationError() {
return authorizationError;
}

public boolean isSuperuserRequired() {
return superuserRequired;
}

public Optional<AuthAdmin.Privilege> getRequiredPrivilege() {
return Optional.ofNullable(requiredPrivilege);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.scalar.db.exception.transaction;

import javax.annotation.Nullable;

/**
* An exception thrown when aborting (rolling back) a transaction fails due to transient or
* nontransient faults.
Expand All @@ -13,4 +15,17 @@ public AbortException(String message, String transactionId) {
public AbortException(String message, Throwable cause, String transactionId) {
super(message, cause, transactionId);
}

public AbortException(
String message, @Nullable String transactionId, boolean authenticationError) {
super(message, transactionId, authenticationError, false, false, null);
}

public AbortException(
String message,
Throwable cause,
@Nullable String transactionId,
boolean authenticationError) {
super(message, cause, transactionId, authenticationError, false, false, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.scalar.db.exception.transaction;

import javax.annotation.Nullable;

/**
* An exception thrown when committing a transaction fails due to transient or nontransient faults.
* You can try retrying the transaction from the beginning, but the transaction may still fail if
Expand All @@ -14,4 +16,17 @@ public CommitException(String message, String transactionId) {
public CommitException(String message, Throwable cause, String transactionId) {
super(message, cause, transactionId);
}

public CommitException(
String message, @Nullable String transactionId, boolean authenticationError) {
super(message, transactionId, authenticationError, false, false, null);
}

public CommitException(
String message,
Throwable cause,
@Nullable String transactionId,
boolean authenticationError) {
super(message, cause, transactionId, authenticationError, false, false, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.scalar.db.exception.transaction;

import com.scalar.db.api.AuthAdmin;
import javax.annotation.Nullable;

/**
* An exception thrown when a transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may still
Expand All @@ -14,4 +17,31 @@ public CrudException(String message, String transactionId) {
public CrudException(String message, Throwable cause, String transactionId) {
super(message, cause, transactionId);
}

public CrudException(
String message,
@Nullable String transactionId,
boolean authenticationError,
boolean authorizationError,
@Nullable AuthAdmin.Privilege requiredPrivileges) {
super(
message, transactionId, authenticationError, authorizationError, false, requiredPrivileges);
}

public CrudException(
String message,
Throwable cause,
@Nullable String transactionId,
boolean authenticationError,
boolean authorizationError,
@Nullable AuthAdmin.Privilege requiredPrivileges) {
super(
message,
cause,
transactionId,
authenticationError,
authorizationError,
false,
requiredPrivileges);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.scalar.db.exception.transaction;

import javax.annotation.Nullable;

/**
* An exception thrown when preparing a transaction fails due to transient or nontransient faults.
* You can try retrying the transaction from the beginning, but the transaction may still fail if
Expand All @@ -14,4 +16,17 @@ public PreparationException(String message, String transactionId) {
public PreparationException(String message, Throwable cause, String transactionId) {
super(message, cause, transactionId);
}

public PreparationException(
String message, @Nullable String transactionId, boolean authenticationError) {
super(message, transactionId, authenticationError, false, false, null);
}

public PreparationException(
String message,
Throwable cause,
@Nullable String transactionId,
boolean authenticationError) {
super(message, cause, transactionId, authenticationError, false, false, null);
}
}
Loading

0 comments on commit e07d274

Please sign in to comment.