mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
Add base object classes for new user/role permissioning model (#1707)
* Add base object classes for new user/role permissioning model - Adds the permissions themselves - Adds the six roles that a user may have -- three global, three per-registrar - Adds the mapping from role -> set of permissions - Adds a UserRoles object to encapsulate the answer to the question of "does this user have this permission?" - Adds a User class as a base to show how we will use the new UserRoles object
This commit is contained in:
parent
a12a716806
commit
6370baf9de
10 changed files with 733 additions and 1 deletions
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
/** Permissions that users may have in the UI, either per-registrar or globally. */
|
||||
public enum ConsolePermission {
|
||||
/** Add, update, or remove other console users. */
|
||||
MANAGE_USERS,
|
||||
/** Add, update, or remove registrars. */
|
||||
MANAGE_REGISTRARS,
|
||||
/** Manage related registrars, e.g. when one registrar owns another. */
|
||||
MANAGE_ACCREDITATION,
|
||||
/** Set up the EPP connection (e.g. certs). */
|
||||
CONFIGURE_EPP_CONNECTION,
|
||||
/** Retrieve the unredacted registrant email from a domain. */
|
||||
GET_REGISTRANT_EMAIL,
|
||||
/** Suspend a domain for compliance (non-URS) reasons. */
|
||||
SUSPEND_DOMAIN,
|
||||
/** Suspend a domain for the Uniform Rapid Suspension process. */
|
||||
SUSPEND_DOMAIN_URS,
|
||||
/** Download a list of domains under management. */
|
||||
DOWNLOAD_DOMAINS,
|
||||
/** Change the password for a registrar. */
|
||||
CHANGE_NOMULUS_PASSWORD,
|
||||
/** View all possible TLDs. */
|
||||
VIEW_TLD_PORTFOLIO,
|
||||
/** Onboarding the registrar(s) to extra programs like registry locking. */
|
||||
ONBOARD_ADDITIONAL_PROGRAMS,
|
||||
/** Execute arbitrary EPP commands through the UI. */
|
||||
EXECUTE_EPP_COMMANDS,
|
||||
/** Send messages to the registry support team. */
|
||||
CONTACT_SUPPORT,
|
||||
/** Access billing and payment details for a registrar. */
|
||||
ACCESS_BILLING_DETAILS,
|
||||
/** Access any available documentation about the registry. */
|
||||
ACCESS_DOCUMENTATION,
|
||||
/** Change the documentation available in the UI about the registry. */
|
||||
MANAGE_DOCUMENTATION,
|
||||
/** Viewing the onboarding status of a registrar on a TLD. */
|
||||
CHECK_ONBOARDING_STATUS,
|
||||
/** View premium and/or reserved lists for a TLD. */
|
||||
VIEW_PREMIUM_RESERVED_LISTS,
|
||||
/** Sign and/or change legal documents like RRAs. */
|
||||
UPLOAD_CONTRACTS,
|
||||
/** Viewing legal documents like RRAs. */
|
||||
ACCESS_CONTRACTS,
|
||||
/** View analytics on operations and billing data (possibly TBD). */
|
||||
VIEW_OPERATIONAL_DATA,
|
||||
/** Create announcements that can be displayed in the UI. */
|
||||
SEND_ANNOUNCEMENTS,
|
||||
/** View announcements in the UI. */
|
||||
VIEW_ANNOUNCEMENTS,
|
||||
/** Viewing a record of actions performed in the UI for a particular registrar. */
|
||||
VIEW_ACTIVITY_LOG
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Definitions of the {@link ConsolePermission} sets that each role contains.
|
||||
*
|
||||
* <p>Note: within the "registry" and "registrar" groupings, permissions expand hierarchically,
|
||||
* where each role has all the permissions of the role below it plus some others.
|
||||
*/
|
||||
public class ConsoleRoleDefinitions {
|
||||
|
||||
/** Permissions for a registry support agent. */
|
||||
static final ImmutableSet<ConsolePermission> SUPPORT_AGENT_PERMISSIONS =
|
||||
ImmutableSet.of(
|
||||
ConsolePermission.MANAGE_USERS,
|
||||
ConsolePermission.MANAGE_ACCREDITATION,
|
||||
ConsolePermission.CONFIGURE_EPP_CONNECTION,
|
||||
ConsolePermission.DOWNLOAD_DOMAINS,
|
||||
ConsolePermission.VIEW_TLD_PORTFOLIO,
|
||||
ConsolePermission.ONBOARD_ADDITIONAL_PROGRAMS,
|
||||
ConsolePermission.CONTACT_SUPPORT,
|
||||
ConsolePermission.ACCESS_BILLING_DETAILS,
|
||||
ConsolePermission.ACCESS_DOCUMENTATION,
|
||||
ConsolePermission.SUSPEND_DOMAIN_URS,
|
||||
ConsolePermission.CHECK_ONBOARDING_STATUS,
|
||||
ConsolePermission.VIEW_PREMIUM_RESERVED_LISTS,
|
||||
ConsolePermission.UPLOAD_CONTRACTS,
|
||||
ConsolePermission.ACCESS_CONTRACTS,
|
||||
ConsolePermission.VIEW_OPERATIONAL_DATA,
|
||||
ConsolePermission.SEND_ANNOUNCEMENTS,
|
||||
ConsolePermission.VIEW_ANNOUNCEMENTS,
|
||||
ConsolePermission.VIEW_ACTIVITY_LOG);
|
||||
|
||||
/** Permissions for a registry support lead. */
|
||||
static final ImmutableSet<ConsolePermission> SUPPORT_LEAD_PERMISSIONS =
|
||||
new ImmutableSet.Builder<ConsolePermission>()
|
||||
.addAll(SUPPORT_AGENT_PERMISSIONS)
|
||||
.add(
|
||||
ConsolePermission.MANAGE_REGISTRARS,
|
||||
ConsolePermission.GET_REGISTRANT_EMAIL,
|
||||
ConsolePermission.SUSPEND_DOMAIN,
|
||||
ConsolePermission.EXECUTE_EPP_COMMANDS,
|
||||
ConsolePermission.MANAGE_DOCUMENTATION)
|
||||
.build();
|
||||
|
||||
/** Permissions for a registry full-time employee. */
|
||||
static final ImmutableSet<ConsolePermission> FTE_PERMISSIONS =
|
||||
new ImmutableSet.Builder<ConsolePermission>()
|
||||
.addAll(SUPPORT_LEAD_PERMISSIONS)
|
||||
.add(ConsolePermission.CHANGE_NOMULUS_PASSWORD)
|
||||
.build();
|
||||
|
||||
/** Permissions for a registrar partner account manager. */
|
||||
static final ImmutableSet<ConsolePermission> ACCOUNT_MANAGER_PERMISSIONS =
|
||||
ImmutableSet.of(
|
||||
ConsolePermission.DOWNLOAD_DOMAINS,
|
||||
ConsolePermission.VIEW_TLD_PORTFOLIO,
|
||||
ConsolePermission.CONTACT_SUPPORT,
|
||||
ConsolePermission.ACCESS_DOCUMENTATION,
|
||||
ConsolePermission.VIEW_PREMIUM_RESERVED_LISTS,
|
||||
ConsolePermission.VIEW_OPERATIONAL_DATA,
|
||||
ConsolePermission.VIEW_ANNOUNCEMENTS);
|
||||
|
||||
/** Permissions for the tech contact of a registrar. */
|
||||
static final ImmutableSet<ConsolePermission> TECH_CONTACT_PERMISSIONS =
|
||||
new ImmutableSet.Builder<ConsolePermission>()
|
||||
.addAll(ACCOUNT_MANAGER_PERMISSIONS)
|
||||
.add(
|
||||
ConsolePermission.MANAGE_ACCREDITATION,
|
||||
ConsolePermission.CONFIGURE_EPP_CONNECTION,
|
||||
ConsolePermission.CHANGE_NOMULUS_PASSWORD,
|
||||
ConsolePermission.ONBOARD_ADDITIONAL_PROGRAMS,
|
||||
ConsolePermission.EXECUTE_EPP_COMMANDS,
|
||||
ConsolePermission.ACCESS_BILLING_DETAILS,
|
||||
ConsolePermission.CHECK_ONBOARDING_STATUS,
|
||||
ConsolePermission.UPLOAD_CONTRACTS,
|
||||
ConsolePermission.ACCESS_CONTRACTS,
|
||||
ConsolePermission.VIEW_ACTIVITY_LOG)
|
||||
.build();
|
||||
|
||||
/** Permissions for the primary registrar contact. */
|
||||
static final ImmutableSet<ConsolePermission> PRIMARY_CONTACT_PERMISSIONS =
|
||||
new ImmutableSet.Builder<ConsolePermission>()
|
||||
.addAll(TECH_CONTACT_PERMISSIONS)
|
||||
.add(ConsolePermission.MANAGE_USERS)
|
||||
.build();
|
||||
|
||||
private ConsoleRoleDefinitions() {}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.FTE_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/** Roles for registry employees that apply across all registrars. */
|
||||
public enum GlobalRole {
|
||||
|
||||
/** The user has no global role, i.e. they're a registrar partner. */
|
||||
NONE(ImmutableSet.of()),
|
||||
/** The user is a registry support agent. */
|
||||
SUPPORT_AGENT(SUPPORT_AGENT_PERMISSIONS),
|
||||
/** The user is a registry support lead. */
|
||||
SUPPORT_LEAD(SUPPORT_LEAD_PERMISSIONS),
|
||||
/** The user is a registry full-time employee. */
|
||||
FTE(FTE_PERMISSIONS);
|
||||
|
||||
private final ImmutableSet<ConsolePermission> permissions;
|
||||
|
||||
GlobalRole(ImmutableSet<ConsolePermission> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public boolean hasPermission(ConsolePermission permission) {
|
||||
return permissions.contains(permission);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.ACCOUNT_MANAGER_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.PRIMARY_CONTACT_PERMISSIONS;
|
||||
import static google.registry.model.console.ConsoleRoleDefinitions.TECH_CONTACT_PERMISSIONS;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/** Roles for registrar partners that apply to only one registrar. */
|
||||
public enum RegistrarRole {
|
||||
|
||||
/** The user is a standard account manager at a registrar. */
|
||||
ACCOUNT_MANAGER(ACCOUNT_MANAGER_PERMISSIONS),
|
||||
/** The user is a technical contact of a registrar. */
|
||||
TECH_CONTACT(TECH_CONTACT_PERMISSIONS),
|
||||
/** The user is the primary contact at a registrar. */
|
||||
PRIMARY_CONTACT(PRIMARY_CONTACT_PERMISSIONS);
|
||||
|
||||
private final ImmutableSet<ConsolePermission> permissions;
|
||||
|
||||
RegistrarRole(ImmutableSet<ConsolePermission> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public boolean hasPermission(ConsolePermission permission) {
|
||||
return permissions.contains(permission);
|
||||
}
|
||||
}
|
148
core/src/main/java/google/registry/model/console/User.java
Normal file
148
core/src/main/java/google/registry/model/console/User.java
Normal file
|
@ -0,0 +1,148 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static com.google.common.io.BaseEncoding.base64;
|
||||
import static google.registry.model.registrar.Registrar.checkValidEmail;
|
||||
import static google.registry.util.PasswordUtils.SALT_SUPPLIER;
|
||||
import static google.registry.util.PasswordUtils.hashPassword;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
|
||||
/** A console user, either a registry employee or a registrar partner. */
|
||||
public class User extends ImmutableObject implements Buildable {
|
||||
|
||||
/** Autogenerated unique ID of this user. */
|
||||
private long id;
|
||||
|
||||
/** GAIA ID associated with the user in question. */
|
||||
private String gaiaId;
|
||||
|
||||
/** Email address of the user in question. */
|
||||
private String emailAddress;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
String registryLockPasswordHash;
|
||||
|
||||
/** Randomly generated hash salt. */
|
||||
String registryLockPasswordSalt;
|
||||
|
||||
public String getGaiaId() {
|
||||
return gaiaId;
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public UserRoles getUserRoles() {
|
||||
return userRoles;
|
||||
}
|
||||
|
||||
public boolean isAllowedToSetRegistryLockPassword() {
|
||||
return allowedToSetRegistryLockPassword;
|
||||
}
|
||||
|
||||
public boolean isRegistryLockAllowed() {
|
||||
return !isNullOrEmpty(registryLockPasswordHash) && !isNullOrEmpty(registryLockPasswordSalt);
|
||||
}
|
||||
|
||||
public boolean verifyRegistryLockPassword(String registryLockPassword) {
|
||||
if (isNullOrEmpty(registryLockPassword)
|
||||
|| isNullOrEmpty(registryLockPasswordSalt)
|
||||
|| isNullOrEmpty(registryLockPasswordHash)) {
|
||||
return false;
|
||||
}
|
||||
return hashPassword(registryLockPassword, registryLockPasswordSalt)
|
||||
.equals(registryLockPasswordHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
/** Builder for constructing immutable {@link User} objects. */
|
||||
public static class Builder extends Buildable.Builder<User> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
public Builder(User user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public User build() {
|
||||
checkArgumentNotNull(getInstance().gaiaId, "Gaia ID cannot be null");
|
||||
checkArgumentNotNull(getInstance().emailAddress, "Email address cannot be null");
|
||||
checkArgumentNotNull(getInstance().userRoles, "User roles cannot be null");
|
||||
return super.build();
|
||||
}
|
||||
|
||||
public Builder setGaiaId(String gaiaId) {
|
||||
checkArgument(!isNullOrEmpty(gaiaId), "Gaia ID cannot be null or empty");
|
||||
getInstance().gaiaId = gaiaId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setEmailAddress(String emailAddress) {
|
||||
getInstance().emailAddress = checkValidEmail(emailAddress);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUserRoles(UserRoles userRoles) {
|
||||
checkArgumentNotNull(userRoles, "User roles cannot be null");
|
||||
getInstance().userRoles = userRoles;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllowedToSetRegistryLockPassword(boolean allowedToSetRegistryLockPassword) {
|
||||
if (allowedToSetRegistryLockPassword) {
|
||||
getInstance().registryLockPasswordSalt = null;
|
||||
getInstance().registryLockPasswordHash = null;
|
||||
}
|
||||
getInstance().allowedToSetRegistryLockPassword = allowedToSetRegistryLockPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRegistryLockPassword(String registryLockPassword) {
|
||||
checkArgument(
|
||||
getInstance().allowedToSetRegistryLockPassword,
|
||||
"Not allowed to set registry lock password for this user");
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
120
core/src/main/java/google/registry/model/console/UserRoles.java
Normal file
120
core/src/main/java/google/registry/model/console/UserRoles.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Contains the global and per-registrar roles for a given user.
|
||||
*
|
||||
* <p>See <a href="https://go/nomulus-console-authz">go/nomulus-console-authz</a> for more
|
||||
* information.
|
||||
*/
|
||||
public class UserRoles extends ImmutableObject implements Buildable {
|
||||
|
||||
/** Whether the user is a global admin, who has access to everything. */
|
||||
private boolean isAdmin = false;
|
||||
|
||||
/**
|
||||
* The global role (e.g. {@link GlobalRole#SUPPORT_AGENT}) that the user has across all
|
||||
* registrars.
|
||||
*/
|
||||
private GlobalRole globalRole = GlobalRole.NONE;
|
||||
|
||||
/** Any per-registrar roles that this user may have. */
|
||||
private Map<String, RegistrarRole> registrarRoles = ImmutableMap.of();
|
||||
|
||||
/** Whether the user is a global admin, who has access to everything. */
|
||||
public boolean isAdmin() {
|
||||
return isAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* The global role (e.g. {@link GlobalRole#SUPPORT_AGENT}) that the user has across all
|
||||
* registrars.
|
||||
*/
|
||||
public GlobalRole getGlobalRole() {
|
||||
return globalRole;
|
||||
}
|
||||
|
||||
/** Any per-registrar roles that this user may have. */
|
||||
public Map<String, RegistrarRole> getRegistrarRoles() {
|
||||
return ImmutableMap.copyOf(registrarRoles);
|
||||
}
|
||||
|
||||
/** If the user has the given permission either globally or on the given registrar. */
|
||||
public boolean hasPermission(String registrarId, ConsolePermission permission) {
|
||||
if (hasGlobalPermission(permission)) {
|
||||
return true;
|
||||
}
|
||||
if (!registrarRoles.containsKey(registrarId)) {
|
||||
return false;
|
||||
}
|
||||
return registrarRoles.get(registrarId).hasPermission(permission);
|
||||
}
|
||||
|
||||
/** If the user has the given permission globally across all registrars. */
|
||||
public boolean hasGlobalPermission(ConsolePermission permission) {
|
||||
return isAdmin || globalRole.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
/** Builder for constructing immutable {@link UserRoles} objects. */
|
||||
public static class Builder extends Buildable.Builder<UserRoles> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
private Builder(UserRoles userRoles) {
|
||||
super(userRoles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserRoles build() {
|
||||
// Users should only have a global role or per-registrar roles, not both
|
||||
checkArgument(
|
||||
getInstance().globalRole.equals(GlobalRole.NONE)
|
||||
|| getInstance().registrarRoles.isEmpty(),
|
||||
"Users cannot have both global and per-registrar roles");
|
||||
return super.build();
|
||||
}
|
||||
|
||||
public Builder setIsAdmin(boolean isAdmin) {
|
||||
getInstance().isAdmin = isAdmin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setGlobalRole(GlobalRole globalRole) {
|
||||
checkArgumentNotNull(globalRole, "Global role cannot be null");
|
||||
getInstance().globalRole = globalRole;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRegistrarRoles(Map<String, RegistrarRole> registrarRoles) {
|
||||
checkArgumentNotNull(registrarRoles, "Registrar roles map cannot be null");
|
||||
getInstance().registrarRoles = ImmutableMap.copyOf(registrarRoles);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -964,7 +964,7 @@ public class Registrar extends ImmutableObject
|
|||
}
|
||||
|
||||
/** Verifies that the email address in question is not null and has a valid format. */
|
||||
static String checkValidEmail(String email) {
|
||||
public static String checkValidEmail(String email) {
|
||||
checkNotNull(email, "Provided email was null");
|
||||
try {
|
||||
InternetAddress internetAddress = new InternetAddress(email, true);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link ConsoleRoleDefinitions}. */
|
||||
public class ConsoleRoleDefinitionsTest {
|
||||
|
||||
@Test
|
||||
void testHierarchicalPermissions_registry() {
|
||||
// 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))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS))
|
||||
.isFalse();
|
||||
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.FTE_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.FTE_PERMISSIONS))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHierarchicalPermissions_registrar() {
|
||||
// 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))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS))
|
||||
.isFalse();
|
||||
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
ConsoleRoleDefinitions.SUPPORT_AGENT_PERMISSIONS.containsAll(
|
||||
ConsoleRoleDefinitions.SUPPORT_LEAD_PERMISSIONS))
|
||||
.isFalse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link UserRoles}. */
|
||||
public class UserRolesTest {
|
||||
|
||||
@Test
|
||||
void testDefaults() {
|
||||
UserRoles userRoles = new UserRoles.Builder().build();
|
||||
for (ConsolePermission permission : ConsolePermission.values()) {
|
||||
assertThat(userRoles.getGlobalRole().hasPermission(permission)).isFalse();
|
||||
}
|
||||
assertThat(userRoles.getRegistrarRoles()).isEmpty();
|
||||
assertThat(userRoles.isAdmin()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdmin_overridesAll() {
|
||||
UserRoles userRoles = new UserRoles.Builder().setIsAdmin(true).build();
|
||||
for (ConsolePermission permission : ConsolePermission.values()) {
|
||||
assertThat(userRoles.hasGlobalPermission(permission)).isTrue();
|
||||
assertThat(userRoles.hasPermission("TheRegistrar", permission)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrarPermission_withGlobal() {
|
||||
UserRoles userRoles = new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build();
|
||||
for (ConsolePermission permission : ConsolePermission.values()) {
|
||||
assertThat(userRoles.hasGlobalPermission(permission)).isTrue();
|
||||
assertThat(userRoles.hasPermission("TheRegistrar", permission)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrarRoles() {
|
||||
UserRoles userRoles =
|
||||
new UserRoles.Builder()
|
||||
.setGlobalRole(GlobalRole.NONE)
|
||||
.setIsAdmin(false)
|
||||
.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.PRIMARY_CONTACT))
|
||||
.build();
|
||||
assertThat(userRoles.hasPermission("TheRegistrar", ConsolePermission.MANAGE_USERS)).isTrue();
|
||||
assertThat(userRoles.hasPermission("TheRegistrar", ConsolePermission.SUSPEND_DOMAIN)).isFalse();
|
||||
assertThat(userRoles.hasPermission("nonexistent", ConsolePermission.MANAGE_USERS)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_globalOrPerRegistrar() {
|
||||
UserRoles.Builder builder =
|
||||
new UserRoles.Builder()
|
||||
.setGlobalRole(GlobalRole.SUPPORT_AGENT)
|
||||
.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.PRIMARY_CONTACT));
|
||||
assertThat(assertThrows(IllegalArgumentException.class, builder::build))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Users cannot have both global and per-registrar roles");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link User}. */
|
||||
public class UserTest {
|
||||
|
||||
@Test
|
||||
void testFailure_badInputs() {
|
||||
User.Builder builder = new User.Builder();
|
||||
assertThat(assertThrows(IllegalArgumentException.class, () -> builder.setGaiaId(null)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Gaia ID cannot be null or empty");
|
||||
assertThat(assertThrows(IllegalArgumentException.class, () -> builder.setEmailAddress("")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email is not a valid email address");
|
||||
assertThat(assertThrows(NullPointerException.class, () -> builder.setEmailAddress(null)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email was null");
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> builder.setEmailAddress("invalidEmail")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email invalidEmail is not a valid email address");
|
||||
assertThat(assertThrows(IllegalArgumentException.class, () -> builder.setUserRoles(null)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("User roles cannot be null");
|
||||
|
||||
assertThat(assertThrows(IllegalArgumentException.class, builder::build))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Gaia ID cannot be null");
|
||||
builder.setGaiaId("gaiaId");
|
||||
assertThat(assertThrows(IllegalArgumentException.class, builder::build))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Email address cannot be null");
|
||||
builder.setEmailAddress("email@email.com");
|
||||
assertThat(assertThrows(IllegalArgumentException.class, builder::build))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("User roles cannot be null");
|
||||
|
||||
builder.setUserRoles(new UserRoles.Builder().build());
|
||||
builder.build();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue