mirror of
https://github.com/google/nomulus.git
synced 2025-04-29 19:47:51 +02:00
Create a registry lock permission and corresponding account manager role (#1740)
* Create a registry lock permission and corresponding account manager role This allows us to distinguish between standard account managers and users that might have the registry lock permission. This will make the registry lock password-setting flow easier (user can reset their password iff they have the REGISTRY_LOCK permission, instead of having a separate boolean) and allows us to easily determine whether or not a user should have access to registry lock views in the UI.
This commit is contained in:
parent
2f9a45c91f
commit
6d66f52359
6 changed files with 90 additions and 31 deletions
|
@ -63,5 +63,7 @@ public enum ConsolePermission {
|
|||
/** View announcements in the UI. */
|
||||
VIEW_ANNOUNCEMENTS,
|
||||
/** Viewing a record of actions performed in the UI for a particular registrar. */
|
||||
VIEW_ACTIVITY_LOG
|
||||
VIEW_ACTIVITY_LOG,
|
||||
/** View and perform registry locks. */
|
||||
REGISTRY_LOCK
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ public class ConsoleRoleDefinitions {
|
|||
ConsolePermission.VIEW_OPERATIONAL_DATA,
|
||||
ConsolePermission.SEND_ANNOUNCEMENTS,
|
||||
ConsolePermission.VIEW_ANNOUNCEMENTS,
|
||||
ConsolePermission.VIEW_ACTIVITY_LOG);
|
||||
ConsolePermission.VIEW_ACTIVITY_LOG,
|
||||
ConsolePermission.REGISTRY_LOCK);
|
||||
|
||||
/** Permissions for a registry support lead. */
|
||||
static final ImmutableSet<ConsolePermission> SUPPORT_LEAD_PERMISSIONS =
|
||||
|
@ -76,10 +77,17 @@ public class ConsoleRoleDefinitions {
|
|||
ConsolePermission.VIEW_OPERATIONAL_DATA,
|
||||
ConsolePermission.VIEW_ANNOUNCEMENTS);
|
||||
|
||||
/** Permissions for a registrar partner account manager that can perform registry locks. */
|
||||
static final ImmutableSet<ConsolePermission> ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS =
|
||||
new ImmutableSet.Builder<ConsolePermission>()
|
||||
.addAll(ACCOUNT_MANAGER_PERMISSIONS)
|
||||
.add(ConsolePermission.REGISTRY_LOCK)
|
||||
.build();
|
||||
|
||||
/** Permissions for the tech contact of a registrar. */
|
||||
static final ImmutableSet<ConsolePermission> TECH_CONTACT_PERMISSIONS =
|
||||
new ImmutableSet.Builder<ConsolePermission>()
|
||||
.addAll(ACCOUNT_MANAGER_PERMISSIONS)
|
||||
.addAll(ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS)
|
||||
.add(
|
||||
ConsolePermission.MANAGE_ACCREDITATION,
|
||||
ConsolePermission.CONFIGURE_EPP_CONNECTION,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package google.registry.model.console;
|
||||
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.ACCOUNT_MANAGER_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.PRIMARY_CONTACT_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.TECH_CONTACT_PERMISSIONS;
|
||||
|
||||
|
@ -25,6 +26,8 @@ public enum RegistrarRole {
|
|||
|
||||
/** The user is a standard account manager at a registrar. */
|
||||
ACCOUNT_MANAGER(ACCOUNT_MANAGER_PERMISSIONS),
|
||||
/** The user is an account manager that can perform registry locks. */
|
||||
ACCOUNT_MANAGER_WITH_REGISTRY_LOCK(ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS),
|
||||
/** The user is a technical contact of a registrar. */
|
||||
TECH_CONTACT(TECH_CONTACT_PERMISSIONS),
|
||||
/** The user is the primary contact at a registrar. */
|
||||
|
|
|
@ -40,12 +40,6 @@ public class User extends ImmutableObject implements Buildable {
|
|||
/** Roles (which grant permissions) associated with this user. */
|
||||
private UserRoles userRoles;
|
||||
|
||||
/**
|
||||
* Whether the contact is allowed to set their registry lock password through the registrar
|
||||
* console. This will be set to false on contact creation and when the user sets a password.
|
||||
*/
|
||||
boolean allowedToSetRegistryLockPassword = false;
|
||||
|
||||
/**
|
||||
* A hashed password that exists iff this contact is registry-lock-enabled. The hash is a base64
|
||||
* encoded SHA256 string.
|
||||
|
@ -55,6 +49,10 @@ public class User extends ImmutableObject implements Buildable {
|
|||
/** Randomly generated hash salt. */
|
||||
String registryLockPasswordSalt;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getGaiaId() {
|
||||
return gaiaId;
|
||||
}
|
||||
|
@ -67,11 +65,7 @@ public class User extends ImmutableObject implements Buildable {
|
|||
return userRoles;
|
||||
}
|
||||
|
||||
public boolean isAllowedToSetRegistryLockPassword() {
|
||||
return allowedToSetRegistryLockPassword;
|
||||
}
|
||||
|
||||
public boolean isRegistryLockAllowed() {
|
||||
public boolean hasRegistryLockPassword() {
|
||||
return !isNullOrEmpty(registryLockPasswordHash) && !isNullOrEmpty(registryLockPasswordSalt);
|
||||
}
|
||||
|
||||
|
@ -85,6 +79,22 @@ public class User extends ImmutableObject implements Buildable {
|
|||
.equals(registryLockPasswordHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user has the registry lock permission on any registrar or globally.
|
||||
*
|
||||
* <p>If so, they should be allowed to (re)set their registry lock password.
|
||||
*/
|
||||
public boolean hasAnyRegistryLockPermission() {
|
||||
if (userRoles == null) {
|
||||
return false;
|
||||
}
|
||||
if (userRoles.isAdmin() || userRoles.hasGlobalPermission(ConsolePermission.REGISTRY_LOCK)) {
|
||||
return true;
|
||||
}
|
||||
return userRoles.getRegistrarRoles().values().stream()
|
||||
.anyMatch(role -> role.hasPermission(ConsolePermission.REGISTRY_LOCK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
|
@ -99,6 +109,7 @@ public class User extends ImmutableObject implements Buildable {
|
|||
super(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User build() {
|
||||
checkArgumentNotNull(getInstance().gaiaId, "Gaia ID cannot be null");
|
||||
checkArgumentNotNull(getInstance().emailAddress, "Email address cannot be null");
|
||||
|
@ -123,25 +134,22 @@ public class User extends ImmutableObject implements Buildable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllowedToSetRegistryLockPassword(boolean allowedToSetRegistryLockPassword) {
|
||||
if (allowedToSetRegistryLockPassword) {
|
||||
getInstance().registryLockPasswordSalt = null;
|
||||
getInstance().registryLockPasswordHash = null;
|
||||
}
|
||||
getInstance().allowedToSetRegistryLockPassword = allowedToSetRegistryLockPassword;
|
||||
public Builder removeRegistryLockPassword() {
|
||||
getInstance().registryLockPasswordHash = null;
|
||||
getInstance().registryLockPasswordSalt = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRegistryLockPassword(String registryLockPassword) {
|
||||
checkArgument(
|
||||
getInstance().allowedToSetRegistryLockPassword,
|
||||
"Not allowed to set registry lock password for this user");
|
||||
getInstance().hasAnyRegistryLockPermission(), "User has no registry lock permission");
|
||||
checkArgument(
|
||||
!getInstance().hasRegistryLockPassword(), "User already has a password, remove it first");
|
||||
checkArgument(
|
||||
!isNullOrEmpty(registryLockPassword), "Registry lock password was null or empty");
|
||||
getInstance().registryLockPasswordSalt = base64().encode(SALT_SUPPLIER.get());
|
||||
getInstance().registryLockPasswordHash =
|
||||
hashPassword(registryLockPassword, getInstance().registryLockPasswordSalt);
|
||||
getInstance().allowedToSetRegistryLockPassword = false;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,21 +49,30 @@ public class ConsoleRoleDefinitionsTest {
|
|||
// Note: we can't use Truth's IterableSubject to check all the subset/superset restrictions
|
||||
// because it is generic to iterables and doesn't know about sets.
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS))
|
||||
ConsoleRoleDefinitions.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.ACCOUNT_MANAGER_PERMISSIONS))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS))
|
||||
ConsoleRoleDefinitions.ACCOUNT_MANAGER_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS))
|
||||
.isFalse();
|
||||
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS))
|
||||
ConsoleRoleDefinitions.TECH_CONTACT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS))
|
||||
ConsoleRoleDefinitions.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.TECH_CONTACT_PERMISSIONS))
|
||||
.isFalse();
|
||||
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.PRIMARY_CONTACT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.TECH_CONTACT_PERMISSIONS))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.TECH_CONTACT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.PRIMARY_CONTACT_PERMISSIONS))
|
||||
.isFalse();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,4 +58,33 @@ public class UserTest {
|
|||
builder.setUserRoles(new UserRoles.Builder().build());
|
||||
builder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistryLockPassword() {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
new User.Builder()
|
||||
.setUserRoles(new UserRoles.Builder().build())
|
||||
.setRegistryLockPassword("foobar")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("User has no registry lock permission");
|
||||
|
||||
User user =
|
||||
new User.Builder()
|
||||
.setGaiaId("gaiaId")
|
||||
.setEmailAddress("email@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
|
||||
.build();
|
||||
assertThat(user.hasRegistryLockPassword()).isFalse();
|
||||
|
||||
user = user.asBuilder().setRegistryLockPassword("foobar").build();
|
||||
assertThat(user.hasRegistryLockPassword()).isTrue();
|
||||
assertThat(user.verifyRegistryLockPassword("foobar")).isTrue();
|
||||
|
||||
user = user.asBuilder().removeRegistryLockPassword().build();
|
||||
assertThat(user.hasRegistryLockPassword()).isFalse();
|
||||
assertThat(user.verifyRegistryLockPassword("foobar")).isFalse();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue