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:
gbrodman
2022-08-05 14:18:16 -04:00
committed by GitHub
parent 0e182546f9
commit eb1a314666
10 changed files with 733 additions and 1 deletions
@@ -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();
}
}