Add console /registrars GET endpoint (#2050)

This commit is contained in:
Pavlo Tkach 2023-06-09 16:57:26 -04:00 committed by GitHub
parent 2415097105
commit 270fe06c34
8 changed files with 204 additions and 10 deletions

View file

@ -49,13 +49,11 @@ export class ContactService {
contacts: Contact[],
registrarId?: string
): Observable<Contact[]> {
return this.backend
.postContacts(registrarId || 'default', contacts)
.pipe(
tap((_) => {
this.contacts = contacts;
})
);
return this.backend.postContacts(registrarId || 'default', contacts).pipe(
tap((_) => {
this.contacts = contacts;
})
);
}
updateContact(index: number, contact: Contact) {

View file

@ -62,11 +62,20 @@ export class BackendService {
},
];
return this.http
.get<Contact[]>(`/console-api/settings/contacts?registrarId=${registrarId}`)
.pipe(catchError((err) => this.errorCatcher<Contact[]>(err, <Contact[]>mockData)));
.get<Contact[]>(
`/console-api/settings/contacts?registrarId=${registrarId}`
)
.pipe(
catchError((err) =>
this.errorCatcher<Contact[]>(err, <Contact[]>mockData)
)
);
}
postContacts(registrarId: string, contacts: Contact[]): Observable<Contact[]> {
postContacts(
registrarId: string,
contacts: Contact[]
): Observable<Contact[]> {
return this.http.post<Contact[]>(
`/console-api/settings/contacts?registrarId=${registrarId}`,
{ contacts }

View file

@ -22,6 +22,8 @@ public enum ConsolePermission {
EDIT_REGISTRAR_DETAILS,
/** Add, update, or remove other console users. */
MANAGE_USERS,
/** View registrars. */
VIEW_REGISTRARS,
/** Add, update, or remove registrars. */
MANAGE_REGISTRARS,
/** Manage related registrars, e.g. when one registrar owns another. */

View file

@ -27,6 +27,7 @@ public class ConsoleRoleDefinitions {
/** Permissions for a registry support agent. */
static final ImmutableSet<ConsolePermission> SUPPORT_AGENT_PERMISSIONS =
ImmutableSet.of(
ConsolePermission.VIEW_REGISTRARS,
ConsolePermission.VIEW_REGISTRAR_DETAILS,
ConsolePermission.EDIT_REGISTRAR_DETAILS,
ConsolePermission.MANAGE_USERS,

View file

@ -26,6 +26,7 @@ import google.registry.request.RequestComponentBuilder;
import google.registry.request.RequestModule;
import google.registry.request.RequestScope;
import google.registry.ui.server.console.ConsoleDomainGetAction;
import google.registry.ui.server.console.RegistrarsAction;
import google.registry.ui.server.console.settings.ContactAction;
import google.registry.ui.server.registrar.ConsoleOteSetupAction;
import google.registry.ui.server.registrar.ConsoleRegistrarCreatorAction;
@ -67,6 +68,8 @@ interface FrontendRequestComponent {
ContactAction contactAction();
RegistrarsAction registrarsAction();
@Subcomponent.Builder
abstract class Builder implements RequestComponentBuilder<FrontendRequestComponent> {
@Override public abstract Builder requestModule(RequestModule requestModule);

View file

@ -0,0 +1,68 @@
// Copyright 2023 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.ui.server.console;
import static google.registry.request.Action.Method.GET;
import com.google.api.client.http.HttpStatusCodes;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.gson.Gson;
import google.registry.model.console.ConsolePermission;
import google.registry.model.console.User;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
import google.registry.request.auth.AuthResult;
import google.registry.ui.server.registrar.JsonGetAction;
import javax.inject.Inject;
@Action(
service = Action.Service.DEFAULT,
path = RegistrarsAction.PATH,
method = {GET},
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
public class RegistrarsAction implements JsonGetAction {
static final String PATH = "/console-api/registrars";
private final AuthResult authResult;
private final Response response;
private final Gson gson;
@Inject
public RegistrarsAction(AuthResult authResult, Response response, Gson gson) {
this.authResult = authResult;
this.response = response;
this.gson = gson;
}
@Override
public void run() {
User user = authResult.userAuthInfo().get().consoleUser().get();
if (!user.getUserRoles().hasGlobalPermission(ConsolePermission.VIEW_REGISTRARS)) {
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
return;
}
ImmutableList<String> registrarIds =
Streams.stream(Registrar.loadAllCached())
.filter(r -> r.getType() == Registrar.Type.REAL)
.map(Registrar::getRegistrarId)
.collect(ImmutableList.toImmutableList());
response.setPayload(gson.toJson(registrarIds));
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
}
}

View file

@ -0,0 +1,112 @@
// Copyright 2023 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.ui.server.console;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.SqlHelper.saveRegistrar;
import com.google.api.client.http.HttpStatusCodes;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import google.registry.model.console.GlobalRole;
import google.registry.model.console.RegistrarRole;
import google.registry.model.console.User;
import google.registry.model.console.UserRoles;
import google.registry.model.registrar.Registrar;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.AuthSettings.AuthLevel;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.FakeResponse;
import google.registry.util.UtilsModule;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Tests for {@link google.registry.ui.server.console.RegistrarsAction}. */
class RegistrarsActionTest {
private static final Gson GSON = UtilsModule.provideGson();
private FakeResponse response;
@RegisterExtension
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@Test
void testSuccess_onlyRealRegistrars() {
Registrar registrar = persistNewRegistrar("registrarId");
registrar = registrar.asBuilder().setType(Registrar.Type.TEST).setIanaIdentifier(null).build();
persistResource(registrar);
RegistrarsAction action =
createAction(
AuthResult.create(
AuthLevel.USER,
UserAuthInfo.create(
createUser(
new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_LEAD).build()))));
action.run();
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
assertThat(response.getPayload()).isEqualTo("[\"NewRegistrar\",\"TheRegistrar\"]");
}
@Test
void testSuccess_getRegistrarIds() {
saveRegistrar("registrarId");
RegistrarsAction action =
createAction(
AuthResult.create(
AuthLevel.USER,
UserAuthInfo.create(
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))));
action.run();
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
assertThat(response.getPayload())
.isEqualTo("[\"NewRegistrar\",\"TheRegistrar\",\"registrarId\"]");
}
@Test
void testFailure_getRegistrarIds() {
saveRegistrar("registrarId");
RegistrarsAction action =
createAction(
AuthResult.create(
AuthLevel.USER,
UserAuthInfo.create(
createUser(
new UserRoles.Builder()
.setRegistrarRoles(
ImmutableMap.of(
"registrarId",
RegistrarRole.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK))
.build()))));
action.run();
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
}
private User createUser(UserRoles userRoles) {
return new User.Builder()
.setEmailAddress("email@email.com")
.setGaiaId("gaiaId")
.setUserRoles(userRoles)
.build();
}
private RegistrarsAction createAction(AuthResult authResult) {
response = new FakeResponse();
return new RegistrarsAction(authResult, response, GSON);
}
}

View file

@ -1,6 +1,7 @@
PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY
/_dr/epp EppTlsAction POST n INTERNAL,API APP PUBLIC
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
/console-api/registrars RegistrarsAction GET n API,LEGACY USER PUBLIC
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
/registrar ConsoleUiAction GET n INTERNAL,API,LEGACY NONE PUBLIC
/registrar-create ConsoleRegistrarCreatorAction POST,GET n INTERNAL,API,LEGACY NONE PUBLIC