mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
Allow UserAuthInfo to contain either old GAE Users or new console Users (#1744)
This means that LegacyAuthenticationMechanism or a to-be-created OAuth2AuthenticationMechanism) can return a UserAuthInfo object that contains either the GAE User or the console User as appropriate. The goal is that the non-auth flows shouldn't have to know about which user type it is. Note: the registry lock flow (for now) needs to know about the separate types of auth because it is a separate level of auth from the standard AuthenticatedRegistrarAccessor. The AuthenticatedRegistrarAccessor code is a bit odd because the new role system doesn't quite fit neatly into the old registrar -> OWNER,ADMIN system but this is a fine approximation. Basically, any new registrar role will map to the old OWNER role.
This commit is contained in:
parent
a6087bf328
commit
dbc6cd2377
13 changed files with 416 additions and 167 deletions
|
@ -108,7 +108,7 @@ public final class RdapModule {
|
||||||
if (userAuthInfo.isUserAdmin()) {
|
if (userAuthInfo.isUserAdmin()) {
|
||||||
return RdapAuthorization.ADMINISTRATOR_AUTHORIZATION;
|
return RdapAuthorization.ADMINISTRATOR_AUTHORIZATION;
|
||||||
}
|
}
|
||||||
ImmutableSet<String> clientIds = registrarAccessor.getAllClientIdWithRoles().keySet();
|
ImmutableSet<String> clientIds = registrarAccessor.getAllRegistrarIdsWithRoles().keySet();
|
||||||
if (clientIds.isEmpty()) {
|
if (clientIds.isEmpty()) {
|
||||||
logger.atWarning().log("Couldn't find registrar for User %s.", authResult.userIdForLogging());
|
logger.atWarning().log("Couldn't find registrar for User %s.", authResult.userIdForLogging());
|
||||||
return RdapAuthorization.PUBLIC_AUTHORIZATION;
|
return RdapAuthorization.PUBLIC_AUTHORIZATION;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public abstract class AuthResult {
|
||||||
userAuthInfo ->
|
userAuthInfo ->
|
||||||
String.format(
|
String.format(
|
||||||
"%s %s",
|
"%s %s",
|
||||||
userAuthInfo.isUserAdmin() ? "admin" : "user", userAuthInfo.user().getEmail()))
|
userAuthInfo.isUserAdmin() ? "admin" : "user", userAuthInfo.getEmailAddress()))
|
||||||
.orElse("<logged-out user>");
|
.orElse("<logged-out user>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ import javax.inject.Inject;
|
||||||
* <p>A user has OWNER role on a Registrar if there exists a {@link RegistrarPoc} with that user's
|
* <p>A user has OWNER role on a Registrar if there exists a {@link RegistrarPoc} with that user's
|
||||||
* gaeId and the registrar as a parent.
|
* gaeId and the registrar as a parent.
|
||||||
*
|
*
|
||||||
* <p>An "admin" has in addition OWNER role on {@code #registryAdminClientId} and to all non-{@code
|
* <p>An "admin" has in addition OWNER role on {@code #registryAdminRegistrarId} and to all
|
||||||
* REAL} registrars (see {@link Registrar#getType}).
|
* non-{@code REAL} registrars (see {@link Registrar#getType}).
|
||||||
*
|
*
|
||||||
* <p>An "admin" also has ADMIN role on ALL registrars.
|
* <p>An "admin" also has ADMIN role on ALL registrars.
|
||||||
*
|
*
|
||||||
|
@ -76,7 +76,7 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
private final boolean isAdmin;
|
private final boolean isAdmin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives all roles a user has for a given clientId.
|
* Gives all roles a user has for a given registrar ID.
|
||||||
*
|
*
|
||||||
* <p>The order is significant, with "more specific to this user" coming first.
|
* <p>The order is significant, with "more specific to this user" coming first.
|
||||||
*
|
*
|
||||||
|
@ -107,13 +107,13 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
@Inject
|
@Inject
|
||||||
public AuthenticatedRegistrarAccessor(
|
public AuthenticatedRegistrarAccessor(
|
||||||
AuthResult authResult,
|
AuthResult authResult,
|
||||||
@Config("registryAdminClientId") String registryAdminClientId,
|
@Config("registryAdminClientId") String registryAdminRegistrarId,
|
||||||
@Config("gSuiteSupportGroupEmailAddress") Optional<String> gSuiteSupportGroupEmailAddress,
|
@Config("gSuiteSupportGroupEmailAddress") Optional<String> gSuiteSupportGroupEmailAddress,
|
||||||
Lazy<GroupsConnection> lazyGroupsConnection) {
|
Lazy<GroupsConnection> lazyGroupsConnection) {
|
||||||
this.isAdmin = userIsAdmin(authResult, gSuiteSupportGroupEmailAddress, lazyGroupsConnection);
|
this.isAdmin = userIsAdmin(authResult, gSuiteSupportGroupEmailAddress, lazyGroupsConnection);
|
||||||
|
|
||||||
this.userIdForLogging = authResult.userIdForLogging();
|
this.userIdForLogging = authResult.userIdForLogging();
|
||||||
this.roleMap = createRoleMap(authResult, this.isAdmin, registryAdminClientId);
|
this.roleMap = createRoleMap(authResult, this.isAdmin, registryAdminRegistrarId);
|
||||||
|
|
||||||
logger.atInfo().log("%s has the following roles: %s", userIdForLogging(), roleMap);
|
logger.atInfo().log("%s has the following roles: %s", userIdForLogging(), roleMap);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
* Creates a "logged-in user" accessor with a given role map, used for tests.
|
* Creates a "logged-in user" accessor with a given role map, used for tests.
|
||||||
*
|
*
|
||||||
* <p>The user will be allowed to create Registrars (and hence do OT&E setup) iff they have
|
* <p>The user will be allowed to create Registrars (and hence do OT&E setup) iff they have
|
||||||
* the role of ADMIN for at least one clientId.
|
* the role of ADMIN for at least one registrar ID.
|
||||||
*
|
*
|
||||||
* <p>The user's "name" in logs and exception messages is "TestUserId".
|
* <p>The user's "name" in logs and exception messages is "TestUserId".
|
||||||
*/
|
*/
|
||||||
|
@ -148,59 +148,62 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map that gives all roles a user has for a given clientId.
|
* A map that gives all roles a user has for a given registrar ID.
|
||||||
*
|
*
|
||||||
* <p>Throws a {@link RegistrarAccessDeniedException} if the user is not logged in.
|
* <p>Throws a {@link RegistrarAccessDeniedException} if the user is not logged in.
|
||||||
*
|
*
|
||||||
* <p>The result is ordered starting from "most specific to this user".
|
* <p>The result is ordered starting from "most specific to this user".
|
||||||
*
|
*
|
||||||
* <p>If you want to load the {@link Registrar} object from these (or any other) {@code clientId},
|
* <p>If you want to load the {@link Registrar} object from these (or any other) {@code
|
||||||
* in order to perform actions on behalf of a user, you must use {@link #getRegistrar} which makes
|
* registrarId}, in order to perform actions on behalf of a user, you must use {@link
|
||||||
* sure the user has permissions.
|
* #getRegistrar} which makes sure the user has permissions.
|
||||||
*
|
*
|
||||||
* <p>Note that this is an OPTIONAL step in the authentication - only used if we don't have any
|
* <p>Note that this is an OPTIONAL step in the authentication - only used if we don't have any
|
||||||
* other clue as to the requested {@code clientId}. It is perfectly OK to get a {@code clientId}
|
* other clue as to the requested {@code registrarId}. It is perfectly OK to get a {@code
|
||||||
* from any other source, as long as the registrar is then loaded using {@link #getRegistrar}.
|
* registrarId} from any other source, as long as the registrar is then loaded using {@link
|
||||||
|
* #getRegistrar}.
|
||||||
*/
|
*/
|
||||||
public ImmutableSetMultimap<String, Role> getAllClientIdWithRoles() {
|
public ImmutableSetMultimap<String, Role> getAllRegistrarIdsWithRoles() {
|
||||||
return roleMap;
|
return roleMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the roles the current user has on the given registrar.
|
* Returns all the roles the current user has on the given registrar.
|
||||||
*
|
*
|
||||||
* <p>This is syntactic sugar for {@code getAllClientIdWithRoles().get(clientId)}.
|
* <p>This is syntactic sugar for {@code getAllRegistrarIdsWithRoles().get(registrarId)}.
|
||||||
*/
|
*/
|
||||||
public ImmutableSet<Role> getRolesForRegistrar(String clientId) {
|
public ImmutableSet<Role> getRolesForRegistrar(String registrarId) {
|
||||||
return getAllClientIdWithRoles().get(clientId);
|
return getAllRegistrarIdsWithRoles().get(registrarId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if we have a given role for a given registrar.
|
* Checks if we have a given role for a given registrar.
|
||||||
*
|
*
|
||||||
* <p>This is syntactic sugar for {@code getAllClientIdWithRoles().containsEntry(clientId, role)}.
|
* <p>This is syntactic sugar for {@code getAllRegistrarIdsWithRoles().containsEntry(registrarId,
|
||||||
|
* role)}.
|
||||||
*/
|
*/
|
||||||
public boolean hasRoleOnRegistrar(Role role, String clientId) {
|
public boolean hasRoleOnRegistrar(Role role, String registrarId) {
|
||||||
return getAllClientIdWithRoles().containsEntry(clientId, role);
|
return getAllRegistrarIdsWithRoles().containsEntry(registrarId, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Guesses" which client ID the user wants from all those they have access to.
|
* "Guesses" which client ID the user wants from all those they have access to.
|
||||||
*
|
*
|
||||||
* <p>If no such ClientIds exist, throws a RegistrarAccessDeniedException.
|
* <p>If no such registrar IDs exist, throws a RegistrarAccessDeniedException.
|
||||||
*
|
*
|
||||||
* <p>This should be the ClientId "most likely wanted by the user".
|
* <p>This should be the registrar ID "most likely wanted by the user".
|
||||||
*
|
*
|
||||||
* <p>If you want to load the {@link Registrar} object from this (or any other) {@code clientId},
|
* <p>If you want to load the {@link Registrar} object from this (or any other) {@code
|
||||||
* in order to perform actions on behalf of a user, you must use {@link #getRegistrar} which makes
|
* registrarId}, in order to perform actions on behalf of a user, you must use {@link
|
||||||
* sure the user has permissions.
|
* #getRegistrar} which makes sure the user has permissions.
|
||||||
*
|
*
|
||||||
* <p>Note that this is an OPTIONAL step in the authentication - only used if we don't have any
|
* <p>Note that this is an OPTIONAL step in the authentication - only used if we don't have any
|
||||||
* other clue as to the requested {@code clientId}. It is perfectly OK to get a {@code clientId}
|
* other clue as to the requested {@code registrarId}. It is perfectly OK to get a {@code
|
||||||
* from any other source, as long as the registrar is then loaded using {@link #getRegistrar}.
|
* registrarId} from any other source, as long as the registrar is then loaded using {@link
|
||||||
|
* #getRegistrar}.
|
||||||
*/
|
*/
|
||||||
public String guessClientId() throws RegistrarAccessDeniedException {
|
public String guessRegistrarId() throws RegistrarAccessDeniedException {
|
||||||
return getAllClientIdWithRoles().keySet().stream()
|
return getAllRegistrarIdsWithRoles().keySet().stream()
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow(
|
.orElseThrow(
|
||||||
() ->
|
() ->
|
||||||
|
@ -227,7 +230,7 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
|
|
||||||
if (!registrarId.equals(registrar.getRegistrarId())) {
|
if (!registrarId.equals(registrar.getRegistrarId())) {
|
||||||
logger.atSevere().log(
|
logger.atSevere().log(
|
||||||
"registrarLoader.apply(clientId) returned a Registrar with a different clientId. "
|
"registrarLoader.apply(registrarId) returned a Registrar with a different registrarId. "
|
||||||
+ "Requested: %s, returned: %s.",
|
+ "Requested: %s, returned: %s.",
|
||||||
registrarId, registrar.getRegistrarId());
|
registrarId, registrar.getRegistrarId());
|
||||||
throw new RegistrarAccessDeniedException("Internal error - please check logs");
|
throw new RegistrarAccessDeniedException("Internal error - please check logs");
|
||||||
|
@ -237,7 +240,7 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyAccess(String registrarId) throws RegistrarAccessDeniedException {
|
public void verifyAccess(String registrarId) throws RegistrarAccessDeniedException {
|
||||||
ImmutableSet<Role> roles = getAllClientIdWithRoles().get(registrarId);
|
ImmutableSet<Role> roles = getAllRegistrarIdsWithRoles().get(registrarId);
|
||||||
|
|
||||||
if (roles.isEmpty()) {
|
if (roles.isEmpty()) {
|
||||||
throw new RegistrarAccessDeniedException(
|
throw new RegistrarAccessDeniedException(
|
||||||
|
@ -279,37 +282,31 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
AuthResult authResult,
|
AuthResult authResult,
|
||||||
Optional<String> gSuiteSupportGroupEmailAddress,
|
Optional<String> gSuiteSupportGroupEmailAddress,
|
||||||
Lazy<GroupsConnection> lazyGroupsConnection) {
|
Lazy<GroupsConnection> lazyGroupsConnection) {
|
||||||
|
|
||||||
if (!authResult.userAuthInfo().isPresent()) {
|
if (!authResult.userAuthInfo().isPresent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
||||||
|
|
||||||
User user = userAuthInfo.user();
|
|
||||||
|
|
||||||
// both GAE project admin and members of the gSuiteSupportGroupEmailAddress are considered
|
// both GAE project admin and members of the gSuiteSupportGroupEmailAddress are considered
|
||||||
// admins for the RegistrarConsole.
|
// admins for the RegistrarConsole.
|
||||||
return !bypassAdminCheck
|
return !bypassAdminCheck
|
||||||
&& (userAuthInfo.isUserAdmin()
|
&& (userAuthInfo.isUserAdmin()
|
||||||
|| checkIsSupport(
|
|| checkIsSupport(
|
||||||
lazyGroupsConnection, user.getEmail(), gSuiteSupportGroupEmailAddress));
|
lazyGroupsConnection,
|
||||||
|
userAuthInfo.getEmailAddress(),
|
||||||
|
gSuiteSupportGroupEmailAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Returns a map of registrar IDs to roles for all registrars that the user has access to. */
|
||||||
* Returns a map of registrar client IDs to roles for all registrars that the user has access to.
|
|
||||||
*/
|
|
||||||
private static ImmutableSetMultimap<String, Role> createRoleMap(
|
private static ImmutableSetMultimap<String, Role> createRoleMap(
|
||||||
AuthResult authResult,
|
AuthResult authResult, boolean isAdmin, String registryAdminRegistrarId) {
|
||||||
boolean isAdmin,
|
|
||||||
String registryAdminClientId) {
|
|
||||||
|
|
||||||
if (!authResult.userAuthInfo().isPresent()) {
|
if (!authResult.userAuthInfo().isPresent()) {
|
||||||
return ImmutableSetMultimap.of();
|
return ImmutableSetMultimap.of();
|
||||||
}
|
}
|
||||||
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
|
||||||
User user = userAuthInfo.user();
|
|
||||||
ImmutableSetMultimap.Builder<String, Role> builder = new ImmutableSetMultimap.Builder<>();
|
ImmutableSetMultimap.Builder<String, Role> builder = new ImmutableSetMultimap.Builder<>();
|
||||||
|
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
||||||
|
if (userAuthInfo.appEngineUser().isPresent()) {
|
||||||
|
User user = userAuthInfo.appEngineUser().get();
|
||||||
logger.atInfo().log("Checking registrar contacts for user ID %s.", user.getUserId());
|
logger.atInfo().log("Checking registrar contacts for user ID %s.", user.getUserId());
|
||||||
|
|
||||||
// Find all registrars that have a registrar contact with this user's ID.
|
// Find all registrars that have a registrar contact with this user's ID.
|
||||||
|
@ -326,6 +323,14 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
.setParameter("state", State.DISABLED)
|
.setParameter("state", State.DISABLED)
|
||||||
.getResultStream()
|
.getResultStream()
|
||||||
.forEach(registrar -> builder.put(registrar.getRegistrarId(), Role.OWNER)));
|
.forEach(registrar -> builder.put(registrar.getRegistrarId(), Role.OWNER)));
|
||||||
|
} else {
|
||||||
|
userAuthInfo
|
||||||
|
.consoleUser()
|
||||||
|
.get()
|
||||||
|
.getUserRoles()
|
||||||
|
.getRegistrarRoles()
|
||||||
|
.forEach((k, v) -> builder.put(k, Role.OWNER));
|
||||||
|
}
|
||||||
|
|
||||||
// Admins have ADMIN access to all registrars, and also OWNER access to the registry registrar
|
// Admins have ADMIN access to all registrars, and also OWNER access to the registry registrar
|
||||||
// and all non-REAL or non-live registrars.
|
// and all non-REAL or non-live registrars.
|
||||||
|
@ -337,7 +342,7 @@ public class AuthenticatedRegistrarAccessor {
|
||||||
registrar -> {
|
registrar -> {
|
||||||
if (registrar.getType() != Registrar.Type.REAL
|
if (registrar.getType() != Registrar.Type.REAL
|
||||||
|| !registrar.isLive()
|
|| !registrar.isLive()
|
||||||
|| registrar.getRegistrarId().equals(registryAdminClientId)) {
|
|| registrar.getRegistrarId().equals(registryAdminRegistrarId)) {
|
||||||
builder.put(registrar.getRegistrarId(), Role.OWNER);
|
builder.put(registrar.getRegistrarId(), Role.OWNER);
|
||||||
}
|
}
|
||||||
builder.put(registrar.getRegistrarId(), Role.ADMIN);
|
builder.put(registrar.getRegistrarId(), Role.ADMIN);
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Optional;
|
||||||
public abstract class UserAuthInfo {
|
public abstract class UserAuthInfo {
|
||||||
|
|
||||||
/** User object from the AppEngine Users API. */
|
/** User object from the AppEngine Users API. */
|
||||||
public abstract User user();
|
public abstract Optional<User> appEngineUser();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the user is an admin.
|
* Whether the user is an admin.
|
||||||
|
@ -34,16 +34,37 @@ public abstract class UserAuthInfo {
|
||||||
*/
|
*/
|
||||||
public abstract boolean isUserAdmin();
|
public abstract boolean isUserAdmin();
|
||||||
|
|
||||||
|
public abstract Optional<google.registry.model.console.User> consoleUser();
|
||||||
|
|
||||||
/** Used by the OAuth authentication mechanism (only) to return information about the session. */
|
/** Used by the OAuth authentication mechanism (only) to return information about the session. */
|
||||||
public abstract Optional<OAuthTokenInfo> oauthTokenInfo();
|
public abstract Optional<OAuthTokenInfo> oauthTokenInfo();
|
||||||
|
|
||||||
|
public String getEmailAddress() {
|
||||||
|
return appEngineUser()
|
||||||
|
.map(User::getEmail)
|
||||||
|
.orElseGet(() -> consoleUser().get().getEmailAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return appEngineUser()
|
||||||
|
.map(User::getNickname)
|
||||||
|
.orElseGet(() -> consoleUser().get().getEmailAddress());
|
||||||
|
}
|
||||||
|
|
||||||
public static UserAuthInfo create(
|
public static UserAuthInfo create(
|
||||||
User user, boolean isUserAdmin) {
|
User user, boolean isUserAdmin) {
|
||||||
return new AutoValue_UserAuthInfo(user, isUserAdmin, Optional.empty());
|
return new AutoValue_UserAuthInfo(
|
||||||
|
Optional.of(user), isUserAdmin, Optional.empty(), Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserAuthInfo create(
|
public static UserAuthInfo create(
|
||||||
User user, boolean isUserAdmin, OAuthTokenInfo oauthTokenInfo) {
|
User user, boolean isUserAdmin, OAuthTokenInfo oauthTokenInfo) {
|
||||||
return new AutoValue_UserAuthInfo(user, isUserAdmin, Optional.of(oauthTokenInfo));
|
return new AutoValue_UserAuthInfo(
|
||||||
|
Optional.of(user), isUserAdmin, Optional.empty(), Optional.of(oauthTokenInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserAuthInfo create(google.registry.model.console.User user) {
|
||||||
|
return new AutoValue_UserAuthInfo(
|
||||||
|
Optional.empty(), user.getUserRoles().isAdmin(), Optional.of(user), Optional.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,13 +109,13 @@ public final class ConsoleUiAction extends HtmlAction {
|
||||||
.render());
|
.render());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ImmutableSetMultimap<String, Role> roleMap = registrarAccessor.getAllClientIdWithRoles();
|
ImmutableSetMultimap<String, Role> roleMap = registrarAccessor.getAllRegistrarIdsWithRoles();
|
||||||
soyMapData.put("allClientIds", roleMap.keySet());
|
soyMapData.put("allClientIds", roleMap.keySet());
|
||||||
soyMapData.put("environment", RegistryEnvironment.get().toString());
|
soyMapData.put("environment", RegistryEnvironment.get().toString());
|
||||||
// We set the initial value to the value that will show if guessClientId throws.
|
// We set the initial value to the value that will show if guessClientId throws.
|
||||||
String clientId = "<null>";
|
String clientId = "<null>";
|
||||||
try {
|
try {
|
||||||
clientId = paramClientId.orElse(registrarAccessor.guessClientId());
|
clientId = paramClientId.orElse(registrarAccessor.guessRegistrarId());
|
||||||
soyMapData.put("clientId", clientId);
|
soyMapData.put("clientId", clientId);
|
||||||
soyMapData.put("isOwner", roleMap.containsEntry(clientId, OWNER));
|
soyMapData.put("isOwner", roleMap.containsEntry(clientId, OWNER));
|
||||||
soyMapData.put("isAdmin", roleMap.containsEntry(clientId, ADMIN));
|
soyMapData.put("isAdmin", roleMap.containsEntry(clientId, ADMIN));
|
||||||
|
|
|
@ -18,7 +18,6 @@ import static com.google.common.net.HttpHeaders.LOCATION;
|
||||||
import static com.google.common.net.HttpHeaders.X_FRAME_OPTIONS;
|
import static com.google.common.net.HttpHeaders.X_FRAME_OPTIONS;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_MOVED_TEMPORARILY;
|
import static javax.servlet.http.HttpServletResponse.SC_MOVED_TEMPORARILY;
|
||||||
|
|
||||||
import com.google.appengine.api.users.User;
|
|
||||||
import com.google.appengine.api.users.UserService;
|
import com.google.appengine.api.users.UserService;
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
import com.google.common.net.MediaType;
|
import com.google.common.net.MediaType;
|
||||||
|
@ -27,6 +26,7 @@ import google.registry.request.Action;
|
||||||
import google.registry.request.RequestMethod;
|
import google.registry.request.RequestMethod;
|
||||||
import google.registry.request.Response;
|
import google.registry.request.Response;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
|
import google.registry.request.auth.UserAuthInfo;
|
||||||
import google.registry.security.XsrfTokenManager;
|
import google.registry.security.XsrfTokenManager;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -86,16 +86,15 @@ public abstract class HtmlAction implements Runnable {
|
||||||
}
|
}
|
||||||
response.setContentType(MediaType.HTML_UTF_8);
|
response.setContentType(MediaType.HTML_UTF_8);
|
||||||
|
|
||||||
User user = authResult.userAuthInfo().get().user();
|
UserAuthInfo authInfo = authResult.userAuthInfo().get();
|
||||||
|
|
||||||
// Using HashMap to allow null values
|
// Using HashMap to allow null values
|
||||||
HashMap<String, Object> data = new HashMap<>();
|
HashMap<String, Object> data = new HashMap<>();
|
||||||
data.put("logoFilename", logoFilename);
|
data.put("logoFilename", logoFilename);
|
||||||
data.put("productName", productName);
|
data.put("productName", productName);
|
||||||
data.put("username", user.getNickname());
|
data.put("username", authInfo.getUsername());
|
||||||
data.put("logoutUrl", userService.createLogoutURL(getPath()));
|
data.put("logoutUrl", userService.createLogoutURL(getPath()));
|
||||||
data.put("analyticsConfig", analyticsConfig);
|
data.put("analyticsConfig", analyticsConfig);
|
||||||
data.put("xsrfToken", xsrfTokenManager.generateToken(user.getEmail()));
|
data.put("xsrfToken", xsrfTokenManager.generateToken(authInfo.getEmailAddress()));
|
||||||
|
|
||||||
logger.atInfo().log(
|
logger.atInfo().log(
|
||||||
"User %s is accessing %s with method %s.",
|
"User %s is accessing %s with method %s.",
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
import com.google.common.net.MediaType;
|
import com.google.common.net.MediaType;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import google.registry.model.console.ConsolePermission;
|
||||||
import google.registry.model.domain.RegistryLock;
|
import google.registry.model.domain.RegistryLock;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registrar.RegistrarPoc;
|
import google.registry.model.registrar.RegistrarPoc;
|
||||||
|
@ -42,6 +43,7 @@ import google.registry.request.auth.Auth;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||||
|
import google.registry.request.auth.UserAuthInfo;
|
||||||
import google.registry.security.JsonResponseHelper;
|
import google.registry.security.JsonResponseHelper;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -153,24 +155,35 @@ public final class RegistryLockGetAction implements JsonGetAction {
|
||||||
|
|
||||||
boolean isAdmin = registrarAccessor.isAdmin();
|
boolean isAdmin = registrarAccessor.isAdmin();
|
||||||
Registrar registrar = getRegistrarAndVerifyLockAccess(registrarAccessor, registrarId, isAdmin);
|
Registrar registrar = getRegistrarAndVerifyLockAccess(registrarAccessor, registrarId, isAdmin);
|
||||||
User user = authResult.userAuthInfo().get().user();
|
|
||||||
|
|
||||||
|
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
||||||
|
// Split logic depending on whether we are using the old auth system or the new one
|
||||||
|
boolean isRegistryLockAllowed;
|
||||||
|
String relevantEmail;
|
||||||
|
if (userAuthInfo.appEngineUser().isPresent()) {
|
||||||
|
User user = userAuthInfo.appEngineUser().get();
|
||||||
Optional<RegistrarPoc> contactOptional = getContactMatchingLogin(user, registrar);
|
Optional<RegistrarPoc> contactOptional = getContactMatchingLogin(user, registrar);
|
||||||
boolean isRegistryLockAllowed =
|
isRegistryLockAllowed =
|
||||||
isAdmin || contactOptional.map(RegistrarPoc::isRegistryLockAllowed).orElse(false);
|
isAdmin || contactOptional.map(RegistrarPoc::isRegistryLockAllowed).orElse(false);
|
||||||
// Use the contact's registry lock email if it's present, else use the login email (for admins)
|
relevantEmail =
|
||||||
String relevantEmail =
|
|
||||||
isAdmin
|
isAdmin
|
||||||
? user.getEmail()
|
? user.getEmail()
|
||||||
// if the contact isn't present, we shouldn't display the email anyway so empty is fine
|
// if the contact isn't present, we shouldn't display the email anyway
|
||||||
: contactOptional.flatMap(RegistrarPoc::getRegistryLockEmailAddress).orElse("");
|
: contactOptional.flatMap(RegistrarPoc::getRegistryLockEmailAddress).orElse("");
|
||||||
|
} else {
|
||||||
|
google.registry.model.console.User user = userAuthInfo.consoleUser().get();
|
||||||
|
isRegistryLockAllowed =
|
||||||
|
user.getUserRoles().hasPermission(registrarId, ConsolePermission.REGISTRY_LOCK);
|
||||||
|
relevantEmail = user.getEmailAddress();
|
||||||
|
}
|
||||||
|
// Use the contact's registry lock email if it's present, else use the login email (for admins)
|
||||||
return ImmutableMap.of(
|
return ImmutableMap.of(
|
||||||
LOCK_ENABLED_FOR_CONTACT_PARAM,
|
LOCK_ENABLED_FOR_CONTACT_PARAM,
|
||||||
isRegistryLockAllowed,
|
isRegistryLockAllowed,
|
||||||
EMAIL_PARAM,
|
EMAIL_PARAM,
|
||||||
relevantEmail,
|
relevantEmail,
|
||||||
PARAM_CLIENT_ID,
|
PARAM_CLIENT_ID,
|
||||||
registrar.getRegistrarId(),
|
registrarId,
|
||||||
LOCKS_PARAM,
|
LOCKS_PARAM,
|
||||||
getLockedDomains(registrarId, isAdmin));
|
getLockedDomains(registrarId, isAdmin));
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,10 +184,29 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
||||||
private String verifyPasswordAndGetEmail(
|
private String verifyPasswordAndGetEmail(
|
||||||
UserAuthInfo userAuthInfo, RegistryLockPostInput postInput)
|
UserAuthInfo userAuthInfo, RegistryLockPostInput postInput)
|
||||||
throws RegistrarAccessDeniedException {
|
throws RegistrarAccessDeniedException {
|
||||||
User user = userAuthInfo.user();
|
|
||||||
if (registrarAccessor.isAdmin()) {
|
if (registrarAccessor.isAdmin()) {
|
||||||
return user.getEmail();
|
return userAuthInfo.getEmailAddress();
|
||||||
}
|
}
|
||||||
|
if (userAuthInfo.appEngineUser().isPresent()) {
|
||||||
|
return verifyPasswordAndGetEmailLegacyUser(userAuthInfo.appEngineUser().get(), postInput);
|
||||||
|
} else {
|
||||||
|
return verifyPasswordAndGetEmailConsoleUser(userAuthInfo.consoleUser().get(), postInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String verifyPasswordAndGetEmailConsoleUser(
|
||||||
|
google.registry.model.console.User user, RegistryLockPostInput postInput)
|
||||||
|
throws RegistrarAccessDeniedException {
|
||||||
|
// Verify that the registrar has locking enabled
|
||||||
|
getRegistrarAndVerifyLockAccess(registrarAccessor, postInput.registrarId, false);
|
||||||
|
checkArgument(
|
||||||
|
user.verifyRegistryLockPassword(postInput.password),
|
||||||
|
"Incorrect registry lock password for user");
|
||||||
|
return user.getEmailAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String verifyPasswordAndGetEmailLegacyUser(User user, RegistryLockPostInput postInput)
|
||||||
|
throws RegistrarAccessDeniedException {
|
||||||
// Verify that the user can access the registrar, that the user has
|
// Verify that the user can access the registrar, that the user has
|
||||||
// registry lock enabled, and that the user provided a correct password
|
// registry lock enabled, and that the user provided a correct password
|
||||||
Registrar registrar =
|
Registrar registrar =
|
||||||
|
|
|
@ -474,7 +474,7 @@ public final class RequestHandlerTest {
|
||||||
assertThat(providedAuthResult).isNotNull();
|
assertThat(providedAuthResult).isNotNull();
|
||||||
assertThat(providedAuthResult.authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(providedAuthResult.authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(providedAuthResult.userAuthInfo()).isPresent();
|
assertThat(providedAuthResult.userAuthInfo()).isPresent();
|
||||||
assertThat(providedAuthResult.userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(providedAuthResult.userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(providedAuthResult.userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
assertThat(providedAuthResult.userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
||||||
assertMetric("/auth/adminUser", GET, AuthLevel.USER, true);
|
assertMetric("/auth/adminUser", GET, AuthLevel.USER, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,15 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.google.appengine.api.users.User;
|
import com.google.appengine.api.users.User;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
import com.google.common.testing.NullPointerTester;
|
import com.google.common.testing.NullPointerTester;
|
||||||
import com.google.common.testing.TestLogHandler;
|
import com.google.common.testing.TestLogHandler;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
import google.registry.groups.GroupsConnection;
|
import google.registry.groups.GroupsConnection;
|
||||||
|
import google.registry.model.console.GlobalRole;
|
||||||
|
import google.registry.model.console.RegistrarRole;
|
||||||
|
import google.registry.model.console.UserRoles;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registrar.Registrar.State;
|
import google.registry.model.registrar.Registrar.State;
|
||||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||||
|
@ -71,14 +75,14 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
private static final AuthResult GAE_ADMIN = createAuthResult(true);
|
private static final AuthResult GAE_ADMIN = createAuthResult(true);
|
||||||
private static final AuthResult NO_USER = AuthResult.create(AuthLevel.NONE);
|
private static final AuthResult NO_USER = AuthResult.create(AuthLevel.NONE);
|
||||||
private static final Optional<String> SUPPORT_GROUP = Optional.of("support@registry.example");
|
private static final Optional<String> SUPPORT_GROUP = Optional.of("support@registry.example");
|
||||||
/** Client ID of a REAL registrar with a RegistrarContact for USER and GAE_ADMIN. */
|
/** Registrar ID of a REAL registrar with a RegistrarContact for USER and GAE_ADMIN. */
|
||||||
private static final String CLIENT_ID_WITH_CONTACT = "TheRegistrar";
|
private static final String REGISTRAR_ID_WITH_CONTACT = "TheRegistrar";
|
||||||
/** Client ID of a REAL registrar without a RegistrarContact. */
|
/** Registrar ID of a REAL registrar without a RegistrarContact. */
|
||||||
private static final String REAL_CLIENT_ID_WITHOUT_CONTACT = "NewRegistrar";
|
private static final String REAL_REGISTRAR_ID_WITHOUT_CONTACT = "NewRegistrar";
|
||||||
/** Client ID of an OTE registrar without a RegistrarContact. */
|
/** Registrar ID of an OTE registrar without a RegistrarContact. */
|
||||||
private static final String OTE_CLIENT_ID_WITHOUT_CONTACT = "OteRegistrar";
|
private static final String OTE_REGISTRAR_ID_WITHOUT_CONTACT = "OteRegistrar";
|
||||||
/** Client ID of the Admin registrar without a RegistrarContact. */
|
/** Registrar ID of the Admin registrar without a RegistrarContact. */
|
||||||
private static final String ADMIN_CLIENT_ID = "AdminRegistrar";
|
private static final String ADMIN_REGISTRAR_ID = "AdminRegistrar";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an AuthResult for a fake user.
|
* Creates an AuthResult for a fake user.
|
||||||
|
@ -104,18 +108,17 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
void beforeEach() {
|
void beforeEach() {
|
||||||
when(lazyGroupsConnection.get()).thenReturn(groupsConnection);
|
when(lazyGroupsConnection.get()).thenReturn(groupsConnection);
|
||||||
JdkLoggerConfig.getConfig(AuthenticatedRegistrarAccessor.class).addHandler(testLogHandler);
|
JdkLoggerConfig.getConfig(AuthenticatedRegistrarAccessor.class).addHandler(testLogHandler);
|
||||||
// persistResource(loadRegistrar(ADMIN_CLIENT_ID));
|
|
||||||
persistResource(
|
persistResource(
|
||||||
loadRegistrar(REAL_CLIENT_ID_WITHOUT_CONTACT)
|
loadRegistrar(REAL_REGISTRAR_ID_WITHOUT_CONTACT)
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setRegistrarId(OTE_CLIENT_ID_WITHOUT_CONTACT)
|
.setRegistrarId(OTE_REGISTRAR_ID_WITHOUT_CONTACT)
|
||||||
.setType(Registrar.Type.OTE)
|
.setType(Registrar.Type.OTE)
|
||||||
.setIanaIdentifier(null)
|
.setIanaIdentifier(null)
|
||||||
.build());
|
.build());
|
||||||
persistResource(
|
persistResource(
|
||||||
loadRegistrar(REAL_CLIENT_ID_WITHOUT_CONTACT)
|
loadRegistrar(REAL_REGISTRAR_ID_WITHOUT_CONTACT)
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setRegistrarId(ADMIN_CLIENT_ID)
|
.setRegistrarId(ADMIN_REGISTRAR_ID)
|
||||||
.setType(Registrar.Type.OTE)
|
.setType(Registrar.Type.OTE)
|
||||||
.setIanaIdentifier(null)
|
.setIanaIdentifier(null)
|
||||||
.build());
|
.build());
|
||||||
|
@ -129,24 +132,24 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
|
|
||||||
/** Users are owners for registrars if and only if they are in the contacts for that registrar. */
|
/** Users are owners for registrars if and only if they are in the contacts for that registrar. */
|
||||||
@Test
|
@Test
|
||||||
void getAllClientIdWithAccess_user() {
|
void getAllRegistrarIdWithAccess_user() {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
USER, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
.containsExactly(CLIENT_ID_WITH_CONTACT, OWNER);
|
.containsExactly(REGISTRAR_ID_WITH_CONTACT, OWNER);
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Logged-out users don't have access to anything. */
|
/** Logged-out users don't have access to anything. */
|
||||||
@Test
|
@Test
|
||||||
void getAllClientIdWithAccess_loggedOutUser() {
|
void getAllRegistrarIdWithAccess_loggedOutUser() {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
NO_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
NO_USER, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
assertThat(registrarAccessor.getAllClientIdWithRoles()).isEmpty();
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles()).isEmpty();
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,23 +165,20 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
|
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void getAllClientIdWithAccess_gaeAdmin() {
|
void getAllRegistrarIdWithAccess_gaeAdmin() {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
GAE_ADMIN, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
GAE_ADMIN, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
.containsExactly(
|
.containsExactly(
|
||||||
CLIENT_ID_WITH_CONTACT, ADMIN,
|
REGISTRAR_ID_WITH_CONTACT, ADMIN,
|
||||||
CLIENT_ID_WITH_CONTACT, OWNER,
|
REGISTRAR_ID_WITH_CONTACT, OWNER,
|
||||||
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT, ADMIN,
|
||||||
REAL_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT, ADMIN,
|
||||||
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT, OWNER,
|
||||||
OTE_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
|
ADMIN_REGISTRAR_ID, ADMIN,
|
||||||
OTE_CLIENT_ID_WITHOUT_CONTACT, OWNER,
|
ADMIN_REGISTRAR_ID, OWNER);
|
||||||
|
|
||||||
ADMIN_CLIENT_ID, ADMIN,
|
|
||||||
ADMIN_CLIENT_ID, OWNER);
|
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,51 +194,48 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
|
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void getAllClientIdWithAccess_userInSupportGroup() {
|
void getAllRegistrarIdWithAccess_userInSupportGroup() {
|
||||||
when(groupsConnection.isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get())).thenReturn(true);
|
when(groupsConnection.isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get())).thenReturn(true);
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
USER, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
.containsExactly(
|
.containsExactly(
|
||||||
CLIENT_ID_WITH_CONTACT, ADMIN,
|
REGISTRAR_ID_WITH_CONTACT, ADMIN,
|
||||||
CLIENT_ID_WITH_CONTACT, OWNER,
|
REGISTRAR_ID_WITH_CONTACT, OWNER,
|
||||||
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT, ADMIN,
|
||||||
REAL_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT, ADMIN,
|
||||||
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT, OWNER,
|
||||||
OTE_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
|
ADMIN_REGISTRAR_ID, ADMIN,
|
||||||
OTE_CLIENT_ID_WITHOUT_CONTACT, OWNER,
|
ADMIN_REGISTRAR_ID, OWNER);
|
||||||
|
|
||||||
ADMIN_CLIENT_ID, ADMIN,
|
|
||||||
ADMIN_CLIENT_ID, OWNER);
|
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Empty Support group email - skips check and doesn't generate the lazy. */
|
/** Empty Support group email - skips check and doesn't generate the lazy. */
|
||||||
@Test
|
@Test
|
||||||
void getAllClientIdWithAccess_emptySupportEmail_works() {
|
void getAllRegistrarIdWithAccess_emptySupportEmail_works() {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
USER, ADMIN_CLIENT_ID, Optional.empty(), lazyGroupsConnection);
|
USER, ADMIN_REGISTRAR_ID, Optional.empty(), lazyGroupsConnection);
|
||||||
|
|
||||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
.containsExactly(CLIENT_ID_WITH_CONTACT, OWNER);
|
.containsExactly(REGISTRAR_ID_WITH_CONTACT, OWNER);
|
||||||
// Make sure we didn't instantiate the lazyGroupsConnection
|
// Make sure we didn't instantiate the lazyGroupsConnection
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Support group check throws - continue anyway. */
|
/** Support group check throws - continue anyway. */
|
||||||
@Test
|
@Test
|
||||||
void getAllClientIdWithAccess_throwingGroupCheck_stillWorks() {
|
void getAllRegistrarIdWithAccess_throwingGroupCheck_stillWorks() {
|
||||||
when(groupsConnection.isMemberOfGroup(any(), any())).thenThrow(new RuntimeException("blah"));
|
when(groupsConnection.isMemberOfGroup(any(), any())).thenThrow(new RuntimeException("blah"));
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
USER, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
verify(groupsConnection).isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get());
|
verify(groupsConnection).isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get());
|
||||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
.containsExactly(CLIENT_ID_WITH_CONTACT, OWNER);
|
.containsExactly(REGISTRAR_ID_WITH_CONTACT, OWNER);
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +243,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_noAccess_isNotAdmin() {
|
void testGetRegistrarForUser_noAccess_isNotAdmin() {
|
||||||
expectGetRegistrarFailure(
|
expectGetRegistrarFailure(
|
||||||
REAL_CLIENT_ID_WITHOUT_CONTACT,
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT,
|
||||||
USER,
|
USER,
|
||||||
"user user@gmail.com doesn't have access to registrar NewRegistrar");
|
"user user@gmail.com doesn't have access to registrar NewRegistrar");
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
|
@ -261,7 +258,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
.setState(State.DISABLED)
|
.setState(State.DISABLED)
|
||||||
.build());
|
.build());
|
||||||
expectGetRegistrarFailure(
|
expectGetRegistrarFailure(
|
||||||
CLIENT_ID_WITH_CONTACT,
|
REGISTRAR_ID_WITH_CONTACT,
|
||||||
USER,
|
USER,
|
||||||
"user user@gmail.com doesn't have access to registrar TheRegistrar");
|
"user user@gmail.com doesn't have access to registrar TheRegistrar");
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
|
@ -271,7 +268,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_noAccess_isNotAdmin_notReal() {
|
void testGetRegistrarForUser_noAccess_isNotAdmin_notReal() {
|
||||||
expectGetRegistrarFailure(
|
expectGetRegistrarFailure(
|
||||||
OTE_CLIENT_ID_WITHOUT_CONTACT,
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT,
|
||||||
USER,
|
USER,
|
||||||
"user user@gmail.com doesn't have access to registrar OteRegistrar");
|
"user user@gmail.com doesn't have access to registrar OteRegistrar");
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
|
@ -281,7 +278,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_noUser() {
|
void testGetRegistrarForUser_noUser() {
|
||||||
expectGetRegistrarFailure(
|
expectGetRegistrarFailure(
|
||||||
CLIENT_ID_WITH_CONTACT,
|
REGISTRAR_ID_WITH_CONTACT,
|
||||||
NO_USER,
|
NO_USER,
|
||||||
"<logged-out user> doesn't have access to registrar TheRegistrar");
|
"<logged-out user> doesn't have access to registrar TheRegistrar");
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
|
@ -291,7 +288,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_inContacts_isNotAdmin() throws Exception {
|
void testGetRegistrarForUser_inContacts_isNotAdmin() throws Exception {
|
||||||
expectGetRegistrarSuccess(
|
expectGetRegistrarSuccess(
|
||||||
CLIENT_ID_WITH_CONTACT,
|
REGISTRAR_ID_WITH_CONTACT,
|
||||||
USER,
|
USER,
|
||||||
"user user@gmail.com has [OWNER] access to registrar TheRegistrar");
|
"user user@gmail.com has [OWNER] access to registrar TheRegistrar");
|
||||||
verify(lazyGroupsConnection).get();
|
verify(lazyGroupsConnection).get();
|
||||||
|
@ -301,7 +298,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_inContacts_isAdmin() throws Exception {
|
void testGetRegistrarForUser_inContacts_isAdmin() throws Exception {
|
||||||
expectGetRegistrarSuccess(
|
expectGetRegistrarSuccess(
|
||||||
CLIENT_ID_WITH_CONTACT,
|
REGISTRAR_ID_WITH_CONTACT,
|
||||||
GAE_ADMIN,
|
GAE_ADMIN,
|
||||||
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar TheRegistrar");
|
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar TheRegistrar");
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
|
@ -311,7 +308,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_notInContacts_isAdmin() throws Exception {
|
void testGetRegistrarForUser_notInContacts_isAdmin() throws Exception {
|
||||||
expectGetRegistrarSuccess(
|
expectGetRegistrarSuccess(
|
||||||
REAL_CLIENT_ID_WITHOUT_CONTACT,
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT,
|
||||||
GAE_ADMIN,
|
GAE_ADMIN,
|
||||||
"admin admin@gmail.com has [ADMIN] access to registrar NewRegistrar.");
|
"admin admin@gmail.com has [ADMIN] access to registrar NewRegistrar.");
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
|
@ -326,7 +323,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
.setState(State.DISABLED)
|
.setState(State.DISABLED)
|
||||||
.build());
|
.build());
|
||||||
expectGetRegistrarSuccess(
|
expectGetRegistrarSuccess(
|
||||||
REAL_CLIENT_ID_WITHOUT_CONTACT,
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT,
|
||||||
GAE_ADMIN,
|
GAE_ADMIN,
|
||||||
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar NewRegistrar.");
|
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar NewRegistrar.");
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
|
@ -336,7 +333,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_notInContacts_isAdmin_notReal() throws Exception {
|
void testGetRegistrarForUser_notInContacts_isAdmin_notReal() throws Exception {
|
||||||
expectGetRegistrarSuccess(
|
expectGetRegistrarSuccess(
|
||||||
OTE_CLIENT_ID_WITHOUT_CONTACT,
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT,
|
||||||
GAE_ADMIN,
|
GAE_ADMIN,
|
||||||
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar OteRegistrar.");
|
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar OteRegistrar.");
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
|
@ -346,9 +343,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetRegistrarForUser_doesntExist_isAdmin() {
|
void testGetRegistrarForUser_doesntExist_isAdmin() {
|
||||||
expectGetRegistrarFailure(
|
expectGetRegistrarFailure(
|
||||||
"BadClientId",
|
"BadRegistrarId", GAE_ADMIN, "Registrar BadRegistrarId does not exist");
|
||||||
GAE_ADMIN,
|
|
||||||
"Registrar BadClientId does not exist");
|
|
||||||
verifyNoInteractions(lazyGroupsConnection);
|
verifyNoInteractions(lazyGroupsConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +351,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
throws Exception {
|
throws Exception {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
authResult, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
// make sure loading the registrar succeeds and returns a value
|
// make sure loading the registrar succeeds and returns a value
|
||||||
assertThat(registrarAccessor.getRegistrar(registrarId)).isNotNull();
|
assertThat(registrarAccessor.getRegistrar(registrarId)).isNotNull();
|
||||||
|
@ -367,7 +362,7 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
String registrarId, AuthResult authResult, String message) {
|
String registrarId, AuthResult authResult, String message) {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
new AuthenticatedRegistrarAccessor(
|
new AuthenticatedRegistrarAccessor(
|
||||||
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
authResult, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
// make sure getRegistrar fails
|
// make sure getRegistrar fails
|
||||||
RegistrarAccessDeniedException exception =
|
RegistrarAccessDeniedException exception =
|
||||||
|
@ -378,27 +373,27 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
assertThat(exception).hasMessageThat().contains(message);
|
assertThat(exception).hasMessageThat().contains(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** guessClientIdForUser returns the first clientId in getAllClientIdWithRoles. */
|
/** guessRegistrarIdForUser returns the first registrarId in getAllRegistrarIdWithRoles. */
|
||||||
@Test
|
@Test
|
||||||
void testGuessClientIdForUser_hasAccess_returnsFirst() throws Exception {
|
void testGuessRegistrarIdForUser_hasAccess_returnsFirst() throws Exception {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
AuthenticatedRegistrarAccessor.createForTesting(
|
AuthenticatedRegistrarAccessor.createForTesting(
|
||||||
ImmutableSetMultimap.of(
|
ImmutableSetMultimap.of(
|
||||||
"clientId-1", OWNER,
|
"registrarId-1", OWNER,
|
||||||
"clientId-2", OWNER,
|
"registrarId-2", OWNER,
|
||||||
"clientId-2", ADMIN));
|
"registrarId-2", ADMIN));
|
||||||
|
|
||||||
assertThat(registrarAccessor.guessClientId()).isEqualTo("clientId-1");
|
assertThat(registrarAccessor.guessRegistrarId()).isEqualTo("registrarId-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If a user doesn't have access to any registrars, guess fails. */
|
/** If a user doesn't have access to any registrars, guess fails. */
|
||||||
@Test
|
@Test
|
||||||
void testGuessClientIdForUser_noAccess_fails() {
|
void testGuessRegistrarIdForUser_noAccess_fails() {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
|
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
|
||||||
|
|
||||||
RegistrarAccessDeniedException thrown =
|
RegistrarAccessDeniedException thrown =
|
||||||
assertThrows(RegistrarAccessDeniedException.class, registrarAccessor::guessClientId);
|
assertThrows(RegistrarAccessDeniedException.class, registrarAccessor::guessRegistrarId);
|
||||||
assertThat(thrown).hasMessageThat().isEqualTo("TestUserId isn't associated with any registrar");
|
assertThat(thrown).hasMessageThat().isEqualTo("TestUserId isn't associated with any registrar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,4 +404,75 @@ class AuthenticatedRegistrarAccessorTest {
|
||||||
.setDefault(HttpServletResponse.class, rsp)
|
.setDefault(HttpServletResponse.class, rsp)
|
||||||
.testAllPublicStaticMethods(AuthenticatedRegistrarAccessor.class);
|
.testAllPublicStaticMethods(AuthenticatedRegistrarAccessor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConsoleUser_admin() {
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setEmailAddress("email@email.com")
|
||||||
|
.setUserRoles(
|
||||||
|
new UserRoles.Builder().setIsAdmin(true).setGlobalRole(GlobalRole.FTE).build())
|
||||||
|
.build();
|
||||||
|
AuthResult authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
|
new AuthenticatedRegistrarAccessor(
|
||||||
|
authResult, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
|
// Admin access to all, and owner access to the non-real registrar and the admin registrar
|
||||||
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
|
.containsExactly(
|
||||||
|
REGISTRAR_ID_WITH_CONTACT, ADMIN,
|
||||||
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT, ADMIN,
|
||||||
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT, ADMIN,
|
||||||
|
OTE_REGISTRAR_ID_WITHOUT_CONTACT, OWNER,
|
||||||
|
ADMIN_REGISTRAR_ID, ADMIN,
|
||||||
|
ADMIN_REGISTRAR_ID, OWNER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConsoleUser_globalRole() {
|
||||||
|
// Users with global roles shouldn't necessarily have access to specific registrars if they're
|
||||||
|
// not admins
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setEmailAddress("email@email.com")
|
||||||
|
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_AGENT).build())
|
||||||
|
.build();
|
||||||
|
AuthResult authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
|
new AuthenticatedRegistrarAccessor(
|
||||||
|
authResult, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
|
||||||
|
// Explicit access to registrars is required for non-admins
|
||||||
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConsoleUser_registrarRoles() {
|
||||||
|
// Registrar employees should have OWNER access to their registrars
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setEmailAddress("email@email.com")
|
||||||
|
.setUserRoles(
|
||||||
|
new UserRoles.Builder()
|
||||||
|
.setRegistrarRoles(
|
||||||
|
ImmutableMap.of(
|
||||||
|
REGISTRAR_ID_WITH_CONTACT,
|
||||||
|
RegistrarRole.ACCOUNT_MANAGER,
|
||||||
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT,
|
||||||
|
RegistrarRole.ACCOUNT_MANAGER))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
AuthResult authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
|
new AuthenticatedRegistrarAccessor(
|
||||||
|
authResult, ADMIN_REGISTRAR_ID, SUPPORT_GROUP, lazyGroupsConnection);
|
||||||
|
assertThat(registrarAccessor.getAllRegistrarIdsWithRoles())
|
||||||
|
.containsExactly(
|
||||||
|
REGISTRAR_ID_WITH_CONTACT, OWNER,
|
||||||
|
REAL_REGISTRAR_ID_WITHOUT_CONTACT, OWNER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ class RequestAuthenticatorTest {
|
||||||
assertThat(authResult).isPresent();
|
assertThat(authResult).isPresent();
|
||||||
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(authResult.get().userAuthInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(authResult.get().userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isFalse();
|
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isFalse();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ class RequestAuthenticatorTest {
|
||||||
assertThat(authResult).isPresent();
|
assertThat(authResult).isPresent();
|
||||||
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(authResult.get().userAuthInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(authResult.get().userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ class RequestAuthenticatorTest {
|
||||||
assertThat(authResult).isPresent();
|
assertThat(authResult).isPresent();
|
||||||
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(authResult.get().userAuthInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(authResult.get().userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isTrue();
|
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isTrue();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ class RequestAuthenticatorTest {
|
||||||
assertThat(authResult).isPresent();
|
assertThat(authResult).isPresent();
|
||||||
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(authResult.get().userAuthInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(authResult.get().userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isFalse();
|
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isFalse();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes())
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes())
|
||||||
|
@ -303,7 +303,7 @@ class RequestAuthenticatorTest {
|
||||||
assertThat(authResult).isPresent();
|
assertThat(authResult).isPresent();
|
||||||
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(authResult.get().userAuthInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(authResult.get().userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isTrue();
|
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isTrue();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes())
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes())
|
||||||
|
@ -372,7 +372,7 @@ class RequestAuthenticatorTest {
|
||||||
assertThat(authResult).isPresent();
|
assertThat(authResult).isPresent();
|
||||||
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.USER);
|
||||||
assertThat(authResult.get().userAuthInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().user()).isEqualTo(testUser);
|
assertThat(authResult.get().userAuthInfo().get().appEngineUser()).hasValue(testUser);
|
||||||
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isFalse();
|
assertThat(authResult.get().userAuthInfo().get().isUserAdmin()).isFalse();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isPresent();
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo()).isPresent();
|
||||||
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes())
|
assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes())
|
||||||
|
|
|
@ -32,6 +32,8 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import google.registry.model.console.RegistrarRole;
|
||||||
|
import google.registry.model.console.UserRoles;
|
||||||
import google.registry.model.domain.RegistryLock;
|
import google.registry.model.domain.RegistryLock;
|
||||||
import google.registry.model.registrar.RegistrarPoc;
|
import google.registry.model.registrar.RegistrarPoc;
|
||||||
import google.registry.request.Action.Method;
|
import google.registry.request.Action.Method;
|
||||||
|
@ -83,6 +85,60 @@ final class RegistryLockGetActionTest {
|
||||||
Method.GET, response, accessor, authResult, Optional.of("TheRegistrar"));
|
Method.GET, response, accessor, authResult, Optional.of("TheRegistrar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_newConsoleUser() {
|
||||||
|
RegistryLock regularLock =
|
||||||
|
new RegistryLock.Builder()
|
||||||
|
.setRepoId("repoId")
|
||||||
|
.setDomainName("example.test")
|
||||||
|
.setRegistrarId("TheRegistrar")
|
||||||
|
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||||
|
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||||
|
.setLockCompletionTime(fakeClock.nowUtc())
|
||||||
|
.build();
|
||||||
|
saveRegistryLock(regularLock);
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setEmailAddress("johndoe@theregistrar.com")
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setUserRoles(
|
||||||
|
new UserRoles.Builder()
|
||||||
|
.setRegistrarRoles(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"TheRegistrar", RegistrarRole.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
action.authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
action.run();
|
||||||
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
assertThat(GSON.fromJson(response.getPayload(), Map.class))
|
||||||
|
.containsExactly(
|
||||||
|
"status",
|
||||||
|
"SUCCESS",
|
||||||
|
"message",
|
||||||
|
"Successful locks retrieval",
|
||||||
|
"results",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"lockEnabledForContact",
|
||||||
|
true,
|
||||||
|
"email",
|
||||||
|
"johndoe@theregistrar.com",
|
||||||
|
"clientId",
|
||||||
|
"TheRegistrar",
|
||||||
|
"locks",
|
||||||
|
ImmutableList.of(
|
||||||
|
new ImmutableMap.Builder<>()
|
||||||
|
.put("domainName", "example.test")
|
||||||
|
.put("lockedTime", "2000-06-08T22:00:00.000Z")
|
||||||
|
.put("lockedBy", "johndoe@theregistrar.com")
|
||||||
|
.put("isLockPending", false)
|
||||||
|
.put("isUnlockPending", false)
|
||||||
|
.put("userCanUnlock", true)
|
||||||
|
.build()))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_retrievesLocks() {
|
void testSuccess_retrievesLocks() {
|
||||||
RegistryLock expiredLock =
|
RegistryLock expiredLock =
|
||||||
|
|
|
@ -33,6 +33,8 @@ import com.google.appengine.api.users.User;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import google.registry.model.console.RegistrarRole;
|
||||||
|
import google.registry.model.console.UserRoles;
|
||||||
import google.registry.model.domain.Domain;
|
import google.registry.model.domain.Domain;
|
||||||
import google.registry.model.domain.RegistryLock;
|
import google.registry.model.domain.RegistryLock;
|
||||||
import google.registry.request.JsonActionRunner;
|
import google.registry.request.JsonActionRunner;
|
||||||
|
@ -222,6 +224,47 @@ final class RegistryLockPostActionTest {
|
||||||
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_consoleUser() throws Exception {
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setEmailAddress("johndoe@theregistrar.com")
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setUserRoles(
|
||||||
|
new UserRoles.Builder()
|
||||||
|
.setRegistrarRoles(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"TheRegistrar", RegistrarRole.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK))
|
||||||
|
.build())
|
||||||
|
.setRegistryLockPassword("hi")
|
||||||
|
.build();
|
||||||
|
AuthResult consoleAuthResult =
|
||||||
|
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
action = createAction(consoleAuthResult);
|
||||||
|
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||||
|
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_consoleUser_admin() throws Exception {
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setEmailAddress("johndoe@theregistrar.com")
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setUserRoles(new UserRoles.Builder().setIsAdmin(true).build())
|
||||||
|
.build();
|
||||||
|
AuthResult consoleAuthResult =
|
||||||
|
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
action = createAction(consoleAuthResult);
|
||||||
|
Map<String, Object> requestMapWithoutPassword =
|
||||||
|
ImmutableMap.of(
|
||||||
|
"isLock", true,
|
||||||
|
"registrarId", "TheRegistrar",
|
||||||
|
"domainName", "example.tld");
|
||||||
|
Map<String, ?> response = action.handleJsonRequest(requestMapWithoutPassword);
|
||||||
|
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFailure_noInput() {
|
void testFailure_noInput() {
|
||||||
Map<String, ?> response = action.handleJsonRequest(null);
|
Map<String, ?> response = action.handleJsonRequest(null);
|
||||||
|
@ -397,6 +440,33 @@ final class RegistryLockPostActionTest {
|
||||||
assertFailureWithMessage(response, "Domain example.tld is already unlocked");
|
assertFailureWithMessage(response, "Domain example.tld is already unlocked");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailure_consoleUser_wrongPassword_noAdmin() {
|
||||||
|
google.registry.model.console.User consoleUser =
|
||||||
|
new google.registry.model.console.User.Builder()
|
||||||
|
.setEmailAddress("johndoe@theregistrar.com")
|
||||||
|
.setGaiaId("gaiaId")
|
||||||
|
.setUserRoles(
|
||||||
|
new UserRoles.Builder()
|
||||||
|
.setRegistrarRoles(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"TheRegistrar", RegistrarRole.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK))
|
||||||
|
.build())
|
||||||
|
.setRegistryLockPassword("hi")
|
||||||
|
.build();
|
||||||
|
AuthResult consoleAuthResult =
|
||||||
|
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(consoleUser));
|
||||||
|
action = createAction(consoleAuthResult);
|
||||||
|
Map<String, ?> response =
|
||||||
|
action.handleJsonRequest(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"registrarId", "TheRegistrar",
|
||||||
|
"domainName", "example.tld",
|
||||||
|
"isLock", true,
|
||||||
|
"password", "badPassword"));
|
||||||
|
assertFailureWithMessage(response, "Incorrect registry lock password for user");
|
||||||
|
}
|
||||||
|
|
||||||
private ImmutableMap<String, Object> lockRequest() {
|
private ImmutableMap<String, Object> lockRequest() {
|
||||||
return fullRequest(true);
|
return fullRequest(true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue