Enable Users and Domains actions, add email notification (#2700)
@@ -27,12 +27,10 @@ export const DISABLED_ELEMENTS_PER_ROLE = {
|
|||||||
NONE: [
|
NONE: [
|
||||||
RESTRICTED_ELEMENTS.REGISTRAR_ELEMENT,
|
RESTRICTED_ELEMENTS.REGISTRAR_ELEMENT,
|
||||||
RESTRICTED_ELEMENTS.OTE,
|
RESTRICTED_ELEMENTS.OTE,
|
||||||
RESTRICTED_ELEMENTS.USERS,
|
|
||||||
RESTRICTED_ELEMENTS.BULK_DELETE,
|
|
||||||
RESTRICTED_ELEMENTS.SUSPEND,
|
RESTRICTED_ELEMENTS.SUSPEND,
|
||||||
],
|
],
|
||||||
SUPPORT_LEAD: [RESTRICTED_ELEMENTS.USERS],
|
SUPPORT_LEAD: [],
|
||||||
SUPPORT_AGENT: [RESTRICTED_ELEMENTS.USERS],
|
SUPPORT_AGENT: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
|
|||||||
@@ -31,12 +31,14 @@ import com.google.api.services.directory.Directory;
|
|||||||
import com.google.api.services.directory.model.UserName;
|
import com.google.api.services.directory.model.UserName;
|
||||||
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.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import google.registry.config.RegistryConfig.Config;
|
import google.registry.config.RegistryConfig.Config;
|
||||||
import google.registry.model.console.ConsolePermission;
|
import google.registry.model.console.ConsolePermission;
|
||||||
import google.registry.model.console.RegistrarRole;
|
import google.registry.model.console.RegistrarRole;
|
||||||
import google.registry.model.console.User;
|
import google.registry.model.console.User;
|
||||||
import google.registry.model.console.UserRoles;
|
import google.registry.model.console.UserRoles;
|
||||||
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.request.Action;
|
import google.registry.request.Action;
|
||||||
import google.registry.request.Action.GkeService;
|
import google.registry.request.Action.GkeService;
|
||||||
@@ -44,6 +46,7 @@ import google.registry.request.HttpException.BadRequestException;
|
|||||||
import google.registry.request.Parameter;
|
import google.registry.request.Parameter;
|
||||||
import google.registry.request.auth.Auth;
|
import google.registry.request.auth.Auth;
|
||||||
import google.registry.tools.IamClient;
|
import google.registry.tools.IamClient;
|
||||||
|
import google.registry.util.DiffUtils;
|
||||||
import google.registry.util.StringGenerator;
|
import google.registry.util.StringGenerator;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -96,24 +99,14 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postHandler(User user) {
|
protected void postHandler(User user) {
|
||||||
// Temporary flag while testing
|
checkPermission(user, registrarId, ConsolePermission.MANAGE_USERS);
|
||||||
if (user.getUserRoles().isAdmin()) {
|
tm().transact(this::runPostInTransaction);
|
||||||
checkPermission(user, registrarId, ConsolePermission.MANAGE_USERS);
|
|
||||||
tm().transact(this::runPostInTransaction);
|
|
||||||
} else {
|
|
||||||
consoleApiParams.response().setStatus(SC_FORBIDDEN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void putHandler(User user) {
|
protected void putHandler(User user) {
|
||||||
// Temporary flag while testing
|
checkPermission(user, registrarId, ConsolePermission.MANAGE_USERS);
|
||||||
if (user.getUserRoles().isAdmin()) {
|
tm().transact(this::runUpdateInTransaction);
|
||||||
checkPermission(user, registrarId, ConsolePermission.MANAGE_USERS);
|
|
||||||
tm().transact(this::runUpdateInTransaction);
|
|
||||||
} else {
|
|
||||||
consoleApiParams.response().setStatus(SC_FORBIDDEN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -135,13 +128,8 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deleteHandler(User user) {
|
protected void deleteHandler(User user) {
|
||||||
// Temporary flag while testing
|
checkPermission(user, registrarId, ConsolePermission.MANAGE_USERS);
|
||||||
if (user.getUserRoles().isAdmin()) {
|
tm().transact(this::runDeleteInTransaction);
|
||||||
checkPermission(user, registrarId, ConsolePermission.MANAGE_USERS);
|
|
||||||
tm().transact(this::runDeleteInTransaction);
|
|
||||||
} else {
|
|
||||||
consoleApiParams.response().setStatus(SC_FORBIDDEN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runPostInTransaction() throws IOException {
|
private void runPostInTransaction() throws IOException {
|
||||||
@@ -163,6 +151,8 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
this.userData.get().emailAddress,
|
this.userData.get().emailAddress,
|
||||||
registrarId,
|
registrarId,
|
||||||
RegistrarRole.valueOf(this.userData.get().role));
|
RegistrarRole.valueOf(this.userData.get().role));
|
||||||
|
|
||||||
|
sendConfirmationEmail(registrarId, this.userData.get().emailAddress, "Added existing user");
|
||||||
consoleApiParams.response().setStatus(SC_OK);
|
consoleApiParams.response().setStatus(SC_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +176,7 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
VKey<User> key = VKey.create(User.class, email);
|
VKey<User> key = VKey.create(User.class, email);
|
||||||
tm().delete(key);
|
tm().delete(key);
|
||||||
User.revokeIapPermission(email, maybeGroupEmailAddress, cloudTasksUtils, null, iamClient);
|
User.revokeIapPermission(email, maybeGroupEmailAddress, cloudTasksUtils, null, iamClient);
|
||||||
|
sendConfirmationEmail(registrarId, email, "Deleted user");
|
||||||
}
|
}
|
||||||
|
|
||||||
consoleApiParams.response().setStatus(SC_OK);
|
consoleApiParams.response().setStatus(SC_OK);
|
||||||
@@ -232,7 +223,7 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
User.Builder builder = new User.Builder().setUserRoles(userRoles).setEmailAddress(newEmail);
|
User.Builder builder = new User.Builder().setUserRoles(userRoles).setEmailAddress(newEmail);
|
||||||
tm().put(builder.build());
|
tm().put(builder.build());
|
||||||
User.grantIapPermission(newEmail, maybeGroupEmailAddress, cloudTasksUtils, null, iamClient);
|
User.grantIapPermission(newEmail, maybeGroupEmailAddress, cloudTasksUtils, null, iamClient);
|
||||||
|
sendConfirmationEmail(registrarId, newEmail, "Created user");
|
||||||
consoleApiParams.response().setStatus(SC_CREATED);
|
consoleApiParams.response().setStatus(SC_CREATED);
|
||||||
consoleApiParams
|
consoleApiParams
|
||||||
.response()
|
.response()
|
||||||
@@ -251,6 +242,8 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
this.userData.get().emailAddress,
|
this.userData.get().emailAddress,
|
||||||
registrarId,
|
registrarId,
|
||||||
RegistrarRole.valueOf(this.userData.get().role));
|
RegistrarRole.valueOf(this.userData.get().role));
|
||||||
|
|
||||||
|
sendConfirmationEmail(registrarId, this.userData.get().emailAddress, "Updated user");
|
||||||
consoleApiParams.response().setStatus(SC_OK);
|
consoleApiParams.response().setStatus(SC_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,6 +308,20 @@ public class ConsoleUsersAction extends ConsoleApiAction {
|
|||||||
.collect(toImmutableList()));
|
.collect(toImmutableList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean sendConfirmationEmail(String registrarId, String emailAddress, String operation) {
|
||||||
|
Optional<Registrar> registrar = Registrar.loadByRegistrarId(registrarId);
|
||||||
|
if (registrar.isEmpty()) { // Shouldn't happen, but worth checking
|
||||||
|
setFailedResponse(
|
||||||
|
"Failed to send an email to registrar " + registrarId, SC_INTERNAL_SERVER_ERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sendExternalUpdates(
|
||||||
|
ImmutableMap.of("Console users updated", new DiffUtils.DiffPair(operation, emailAddress)),
|
||||||
|
registrar.get(),
|
||||||
|
ImmutableSet.of());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public record UserData(
|
public record UserData(
|
||||||
@Expose String emailAddress, @Expose String role, @Expose @Nullable String password) {}
|
@Expose String emailAddress, @Expose String role, @Expose @Nullable String password) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
package google.registry.ui.server.console.domains;
|
package google.registry.ui.server.console.domains;
|
||||||
|
|
||||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
|
||||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
@@ -81,11 +80,6 @@ public class ConsoleBulkDomainAction extends ConsoleApiAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postHandler(User user) {
|
protected void postHandler(User user) {
|
||||||
// Temporary flag while testing
|
|
||||||
if (!user.getUserRoles().isAdmin()) {
|
|
||||||
consoleApiParams.response().setStatus(SC_FORBIDDEN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JsonElement jsonPayload =
|
JsonElement jsonPayload =
|
||||||
optionalJsonPayload.orElseThrow(
|
optionalJsonPayload.orElseThrow(
|
||||||
() -> new IllegalArgumentException("Bulk action payload must be present"));
|
() -> new IllegalArgumentException("Bulk action payload must be present"));
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 75 KiB |