diff --git a/gradle/core/build.gradle b/gradle/core/build.gradle index a7ffd3e60..21f520db8 100644 --- a/gradle/core/build.gradle +++ b/gradle/core/build.gradle @@ -341,12 +341,6 @@ task soyToJava { dir: "${javaDir}/google/registry/ui/soy/registrar", include: ['**/*.soy'])) - soyToJava('google.registry.ui.soy.otesetup', - "${generatedDir}/google/registry/ui/soy/otesetup", - fileTree( - dir: "${javaDir}/google/registry/ui/soy/otesetup", - include: ['**/*.soy'])) - soyToJava('google.registry.ui.soy', "${generatedDir}/google/registry/ui/soy", files { diff --git a/java/google/registry/config/RegistryConfig.java b/java/google/registry/config/RegistryConfig.java index a2299f917..f3bc7bf1d 100644 --- a/java/google/registry/config/RegistryConfig.java +++ b/java/google/registry/config/RegistryConfig.java @@ -1381,6 +1381,14 @@ public final class RegistryConfig { } } + /** Returns a singleton random string generator that uses digits only. */ + @Singleton + @Provides + @Config("digitOnlyStringGenerator") + public static StringGenerator provideDigitsOnlyStringGenerator(SecureRandom secureRandom) { + return new RandomStringGenerator(StringGenerator.Alphabets.DIGITS_ONLY, secureRandom); + } + /** Returns a singleton random string generator using Base58 encoding. */ @Singleton @Provides diff --git a/java/google/registry/env/common/default/WEB-INF/web.xml b/java/google/registry/env/common/default/WEB-INF/web.xml index bcbc77703..5861ad0c1 100644 --- a/java/google/registry/env/common/default/WEB-INF/web.xml +++ b/java/google/registry/env/common/default/WEB-INF/web.xml @@ -43,6 +43,12 @@ /registrar-ote-setup + + + frontend-servlet + /registrar-create + + diff --git a/java/google/registry/module/frontend/BUILD b/java/google/registry/module/frontend/BUILD index fc2d681fc..796bee607 100644 --- a/java/google/registry/module/frontend/BUILD +++ b/java/google/registry/module/frontend/BUILD @@ -21,7 +21,6 @@ java_library( "//java/google/registry/request:modules", "//java/google/registry/request/auth", "//java/google/registry/ui", - "//java/google/registry/ui/server/otesetup", "//java/google/registry/ui/server/registrar", "//java/google/registry/util", "@com_google_appengine_api_1_0_sdk", diff --git a/java/google/registry/module/frontend/FrontendRequestComponent.java b/java/google/registry/module/frontend/FrontendRequestComponent.java index 277f2d745..42743cb83 100644 --- a/java/google/registry/module/frontend/FrontendRequestComponent.java +++ b/java/google/registry/module/frontend/FrontendRequestComponent.java @@ -25,7 +25,8 @@ import google.registry.monitoring.whitebox.WhiteboxModule; import google.registry.request.RequestComponentBuilder; import google.registry.request.RequestModule; import google.registry.request.RequestScope; -import google.registry.ui.server.otesetup.ConsoleOteSetupAction; +import google.registry.ui.server.registrar.ConsoleOteSetupAction; +import google.registry.ui.server.registrar.ConsoleRegistrarCreatorAction; import google.registry.ui.server.registrar.ConsoleUiAction; import google.registry.ui.server.registrar.OteStatusAction; import google.registry.ui.server.registrar.RegistrarConsoleModule; @@ -43,6 +44,7 @@ import google.registry.ui.server.registrar.RegistrarSettingsAction; }) interface FrontendRequestComponent { ConsoleOteSetupAction consoleOteSetupAction(); + ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction(); ConsoleUiAction consoleUiAction(); EppConsoleAction eppConsoleAction(); EppTlsAction eppTlsAction(); diff --git a/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java b/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java index c1d080730..51ec7415b 100644 --- a/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java +++ b/java/google/registry/request/auth/AuthenticatedRegistrarAccessor.java @@ -329,7 +329,8 @@ public class AuthenticatedRegistrarAccessor { .load() .type(Registrar.class) .forEach(registrar -> { - if (!Registrar.Type.REAL.equals(registrar.getType())) { + if (registrar.getType() != Registrar.Type.REAL + || registrar.getState() == Registrar.State.PENDING) { builder.put(registrar.getClientId(), Role.OWNER); } builder.put(registrar.getClientId(), Role.ADMIN); diff --git a/java/google/registry/ui/server/otesetup/BUILD b/java/google/registry/ui/server/otesetup/BUILD deleted file mode 100644 index 4ce526598..000000000 --- a/java/google/registry/ui/server/otesetup/BUILD +++ /dev/null @@ -1,43 +0,0 @@ -package( - default_visibility = ["//visibility:public"], -) - -licenses(["notice"]) # Apache 2.0 - -java_library( - name = "otesetup", - srcs = glob(["*.java"]), - resources = [ - "//java/google/registry/ui/css:registrar_bin.css.js", - "//java/google/registry/ui/css:registrar_dbg.css.js", - ], - deps = [ - "//java/google/registry/config", - "//java/google/registry/export/sheet", - "//java/google/registry/flows", - "//java/google/registry/model", - "//java/google/registry/request", - "//java/google/registry/request/auth", - "//java/google/registry/security", - "//java/google/registry/ui/forms", - "//java/google/registry/ui/server", - "//java/google/registry/ui/soy:soy_java_wrappers", - "//java/google/registry/ui/soy/otesetup:soy_java_wrappers", - "//java/google/registry/util", - "//third_party/objectify:objectify-v4_1", - "@com_google_appengine_api_1_0_sdk", - "@com_google_auto_value", - "@com_google_code_findbugs_jsr305", - "@com_google_dagger", - "@com_google_flogger", - "@com_google_flogger_system_backend", - "@com_google_guava", - "@com_google_monitoring_client_metrics", - "@com_google_re2j", - "@io_bazel_rules_closure//closure/templates", - "@javax_inject", - "@javax_servlet_api", - "@joda_time", - "@org_joda_money", - ], -) diff --git a/java/google/registry/ui/server/otesetup/ConsoleOteSetupAction.java b/java/google/registry/ui/server/registrar/ConsoleOteSetupAction.java similarity index 95% rename from java/google/registry/ui/server/otesetup/ConsoleOteSetupAction.java rename to java/google/registry/ui/server/registrar/ConsoleOteSetupAction.java index ee553f345..96ad6b292 100644 --- a/java/google/registry/ui/server/otesetup/ConsoleOteSetupAction.java +++ b/java/google/registry/ui/server/registrar/ConsoleOteSetupAction.java @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -package google.registry.ui.server.otesetup; +package google.registry.ui.server.registrar; + import static com.google.common.base.Preconditions.checkState; import static com.google.common.net.HttpHeaders.LOCATION; import static com.google.common.net.HttpHeaders.X_FRAME_OPTIONS; @@ -44,7 +45,7 @@ import google.registry.request.auth.AuthenticatedRegistrarAccessor; import google.registry.security.XsrfTokenManager; import google.registry.ui.server.SendEmailUtils; import google.registry.ui.server.SoyTemplateUtils; -import google.registry.ui.soy.otesetup.ConsoleSoyInfo; +import google.registry.ui.soy.registrar.OteSetupConsoleSoyInfo; import google.registry.util.StringGenerator; import java.util.HashMap; import java.util.Optional; @@ -77,7 +78,7 @@ public final class ConsoleOteSetupAction implements Runnable { SoyTemplateUtils.createTofuSupplier( google.registry.ui.soy.ConsoleSoyInfo.getInstance(), google.registry.ui.soy.FormsSoyInfo.getInstance(), - google.registry.ui.soy.otesetup.ConsoleSoyInfo.getInstance()); + google.registry.ui.soy.registrar.OteSetupConsoleSoyInfo.getInstance()); @VisibleForTesting // webdriver and screenshot tests need this public static final Supplier CSS_RENAMING_MAP_SUPPLIER = @@ -145,7 +146,7 @@ public final class ConsoleOteSetupAction implements Runnable { response.setPayload( TOFU_SUPPLIER .get() - .newRenderer(ConsoleSoyInfo.WHOAREYOU) + .newRenderer(OteSetupConsoleSoyInfo.WHOAREYOU) .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) .setData(data) .render()); @@ -185,7 +186,7 @@ public final class ConsoleOteSetupAction implements Runnable { response.setPayload( TOFU_SUPPLIER .get() - .newRenderer(ConsoleSoyInfo.RESULT_SUCCESS) + .newRenderer(OteSetupConsoleSoyInfo.RESULT_SUCCESS) .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) .setData(data) .render()); @@ -196,7 +197,7 @@ public final class ConsoleOteSetupAction implements Runnable { response.setPayload( TOFU_SUPPLIER .get() - .newRenderer(ConsoleSoyInfo.FORM_PAGE) + .newRenderer(OteSetupConsoleSoyInfo.FORM_PAGE) .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) .setData(data) .render()); @@ -211,7 +212,7 @@ public final class ConsoleOteSetupAction implements Runnable { response.setPayload( TOFU_SUPPLIER .get() - .newRenderer(ConsoleSoyInfo.FORM_PAGE) + .newRenderer(OteSetupConsoleSoyInfo.FORM_PAGE) .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) .setData(data) .render()); diff --git a/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java b/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java new file mode 100644 index 000000000..de79bc103 --- /dev/null +++ b/java/google/registry/ui/server/registrar/ConsoleRegistrarCreatorAction.java @@ -0,0 +1,369 @@ +// Copyright 2018 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.registrar; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.ImmutableMap.toImmutableMap; +import static com.google.common.net.HttpHeaders.LOCATION; +import static com.google.common.net.HttpHeaders.X_FRAME_OPTIONS; +import static google.registry.model.common.GaeUserIdConverter.convertEmailAddressToGaeUserId; +import static google.registry.model.ofy.ObjectifyService.ofy; +import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; +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.common.annotations.VisibleForTesting; +import com.google.common.base.Ascii; +import com.google.common.base.Splitter; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableMap; +import com.google.common.flogger.FluentLogger; +import com.google.common.io.Resources; +import com.google.common.net.MediaType; +import com.google.template.soy.shared.SoyCssRenamingMap; +import com.google.template.soy.tofu.SoyTofu; +import google.registry.config.RegistryConfig.Config; +import google.registry.config.RegistryEnvironment; +import google.registry.model.registrar.Registrar; +import google.registry.model.registrar.RegistrarAddress; +import google.registry.model.registrar.RegistrarContact; +import google.registry.request.Action; +import google.registry.request.Action.Method; +import google.registry.request.Parameter; +import google.registry.request.RequestMethod; +import google.registry.request.Response; +import google.registry.request.auth.Auth; +import google.registry.request.auth.AuthResult; +import google.registry.request.auth.AuthenticatedRegistrarAccessor; +import google.registry.security.XsrfTokenManager; +import google.registry.ui.server.SendEmailUtils; +import google.registry.ui.server.SoyTemplateUtils; +import google.registry.ui.soy.registrar.RegistrarCreateConsoleSoyInfo; +import google.registry.util.StringGenerator; +import java.util.HashMap; +import java.util.Optional; +import java.util.stream.Stream; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import org.joda.money.CurrencyUnit; + +/** + * Action that serves Registrar creation page. + * + *

This Action does 2 things: - for GET, just returns the form that asks for the required + * information. - for POST, receives the information and creates the Registrar. + * + *

TODO(b/120201577): once we can have 2 different Actions with the same path (different + * Methods), separate this class to 2 Actions. + */ +@Action( + service = Action.Service.DEFAULT, + path = ConsoleRegistrarCreatorAction.PATH, + method = {Method.POST, Method.GET}, + auth = Auth.AUTH_PUBLIC) +public final class ConsoleRegistrarCreatorAction implements Runnable { + + private static final int PASSWORD_LENGTH = 16; + private static final int PASSCODE_LENGTH = 5; + + private static final FluentLogger logger = FluentLogger.forEnclosingClass(); + + public static final String PATH = "/registrar-create"; + + private static final Supplier TOFU_SUPPLIER = + SoyTemplateUtils.createTofuSupplier( + google.registry.ui.soy.ConsoleSoyInfo.getInstance(), + google.registry.ui.soy.FormsSoyInfo.getInstance(), + google.registry.ui.soy.registrar.RegistrarCreateConsoleSoyInfo.getInstance()); + + @VisibleForTesting // webdriver and screenshot tests need this + public static final Supplier CSS_RENAMING_MAP_SUPPLIER = + SoyTemplateUtils.createCssRenamingMapSupplier( + Resources.getResource("google/registry/ui/css/registrar_bin.css.js"), + Resources.getResource("google/registry/ui/css/registrar_dbg.css.js")); + + @Inject HttpServletRequest req; + @Inject @RequestMethod Method method; + @Inject Response response; + @Inject AuthenticatedRegistrarAccessor registrarAccessor; + @Inject UserService userService; + @Inject XsrfTokenManager xsrfTokenManager; + @Inject AuthResult authResult; + @Inject RegistryEnvironment registryEnvironment; + @Inject SendEmailUtils sendEmailUtils; + @Inject @Config("logoFilename") String logoFilename; + @Inject @Config("productName") String productName; + @Inject @Config("base58StringGenerator") StringGenerator passwordGenerator; + @Inject @Config("digitOnlyStringGenerator") StringGenerator passcodeGenerator; + @Inject @Parameter("clientId") Optional clientId; + @Inject @Parameter("name") Optional name; + @Inject @Parameter("billingAccount") Optional billingAccount; + @Inject @Parameter("ianaId") Optional ianaId; + @Inject @Parameter("referralEmail") Optional referralEmail; + @Inject @Parameter("driveId") Optional driveId; + @Inject @Parameter("email") Optional email; + + // Address fields, some of which are required and others are optional. + @Inject @Parameter("street1") Optional street1; + @Inject @Parameter("street2") Optional optionalStreet2; + @Inject @Parameter("street3") Optional optionalStreet3; + @Inject @Parameter("city") Optional city; + @Inject @Parameter("state") Optional optionalState; + @Inject @Parameter("zip") Optional optionalZip; + @Inject @Parameter("countryCode") Optional countryCode; + + @Inject @Parameter("password") Optional optionalPassword; + @Inject @Parameter("passcode") Optional optionalPasscode; + + @Inject ConsoleRegistrarCreatorAction() {} + + @Override + public void run() { + response.setHeader(X_FRAME_OPTIONS, "SAMEORIGIN"); // Disallow iframing. + response.setHeader("X-Ui-Compatible", "IE=edge"); // Ask IE not to be silly. + + logger.atInfo().log( + "User %s is accessing the Registrar creation page. Method= %s", + registrarAccessor.userIdForLogging(), method); + if (!authResult.userAuthInfo().isPresent()) { + response.setStatus(SC_MOVED_TEMPORARILY); + String location; + try { + location = userService.createLoginURL(req.getRequestURI()); + } catch (IllegalArgumentException e) { + // UserServiceImpl.createLoginURL() throws IllegalArgumentException if underlying API call + // returns an error code of NOT_ALLOWED. createLoginURL() assumes that the error is caused + // by an invalid URL. But in fact, the error can also occur if UserService doesn't have any + // user information, which happens when the request has been authenticated as internal. In + // this case, we want to avoid dying before we can send the redirect, so just redirect to + // the root path. + location = "/"; + } + response.setHeader(LOCATION, location); + return; + } + User user = authResult.userAuthInfo().get().user(); + + // Using HashMap to allow null values + HashMap data = new HashMap<>(); + data.put("logoFilename", logoFilename); + data.put("productName", productName); + data.put("username", user.getNickname()); + data.put("logoutUrl", userService.createLogoutURL(PATH)); + data.put("xsrfToken", xsrfTokenManager.generateToken(user.getEmail())); + response.setContentType(MediaType.HTML_UTF_8); + + if (!registrarAccessor.isAdmin()) { + response.setStatus(SC_FORBIDDEN); + response.setPayload( + TOFU_SUPPLIER + .get() + .newRenderer(RegistrarCreateConsoleSoyInfo.WHOAREYOU) + .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) + .setData(data) + .render()); + return; + } + switch (method) { + case POST: + runPost(data); + return; + case GET: + runGet(data); + return; + default: + return; + } + } + + private void checkPresent(Optional value, String name) { + checkState(value.isPresent(), "Missing value for %s", name); + } + + private static final Splitter LINE_SPLITTER = + Splitter.onPattern("\r?\n").trimResults().omitEmptyStrings(); + + private static final Splitter ENTRY_SPLITTER = + Splitter.on('=').trimResults().omitEmptyStrings().limit(2); + + private static ImmutableMap parseBillingAccount(String billingAccount) { + try { + return LINE_SPLITTER.splitToList(billingAccount).stream() + .map(ENTRY_SPLITTER::splitToList) + .peek( + list -> + checkState( + list.size() == 2, + "Can't parse line %s. The format should be [currency]=[account ID]", + list)) + .collect( + toImmutableMap( + list -> CurrencyUnit.of(Ascii.toUpperCase(list.get(0))), list -> list.get(1))); + } catch (Throwable e) { + throw new RuntimeException("Error parsing billing accounts - " + e.getMessage(), e); + } + } + + private void runPost(HashMap data) { + try { + + checkPresent(clientId, "clientId"); + checkPresent(name, "name"); + checkPresent(billingAccount, "billingAccount"); + checkPresent(ianaId, "ianaId"); + checkPresent(referralEmail, "referralEmail"); + checkPresent(driveId, "driveId"); + checkPresent(email, "email"); + checkPresent(street1, "street"); + checkPresent(city, "city"); + checkPresent(countryCode, "countryCode"); + + data.put("clientId", clientId.get()); + data.put("name", name.get()); + data.put("ianaId", ianaId.get()); + data.put("referralEmail", referralEmail.get()); + data.put("billingAccount", billingAccount.get()); + data.put("driveId", driveId.get()); + data.put("email", email.get()); + + data.put("street1", street1.get()); + optionalStreet2.ifPresent(street2 -> data.put("street2", street2)); + optionalStreet3.ifPresent(street3 -> data.put("street3", street3)); + data.put("city", city.get()); + optionalState.ifPresent(state -> data.put("state", state)); + optionalZip.ifPresent(zip -> data.put("zip", zip)); + data.put("countryCode", countryCode.get()); + + String gaeUserId = + checkNotNull( + convertEmailAddressToGaeUserId(email.get()), + "Email address %s is not associated with any GAE ID", + email.get()); + String password = optionalPassword.orElse(passwordGenerator.createString(PASSWORD_LENGTH)); + String phonePasscode = + optionalPasscode.orElse(passcodeGenerator.createString(PASSCODE_LENGTH)); + Registrar registrar = + new Registrar.Builder() + .setClientId(clientId.get()) + .setRegistrarName(name.get()) + .setBillingAccountMap(parseBillingAccount(billingAccount.get())) + .setIanaIdentifier(Long.valueOf(ianaId.get())) + .setIcannReferralEmail(referralEmail.get()) + .setDriveFolderId(driveId.get()) + .setType(Registrar.Type.REAL) + .setPassword(password) + .setPhonePasscode(phonePasscode) + .setState(Registrar.State.PENDING) + .setLocalizedAddress( + new RegistrarAddress.Builder() + .setStreet( + Stream.of(street1, optionalStreet2, optionalStreet3) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(toImmutableList())) + .setCity(city.get()) + .setState(optionalState.orElse(null)) + .setCountryCode(countryCode.get()) + .setZip(optionalZip.orElse(null)) + .build()) + .build(); + RegistrarContact contact = + new RegistrarContact.Builder() + .setParent(registrar) + .setName(email.get()) + .setEmailAddress(email.get()) + .setGaeUserId(gaeUserId) + .build(); + ofy() + .transact( + () -> { + checkState( + !Registrar.loadByClientId(registrar.getClientId()).isPresent(), + "Registrar with client ID %s already exists", + registrar.getClientId()); + ofy().save().entities(registrar, contact); + }); + data.put("password", password); + data.put("passcode", phonePasscode); + + sendExternalUpdates(); + response.setPayload( + TOFU_SUPPLIER + .get() + .newRenderer(RegistrarCreateConsoleSoyInfo.RESULT_SUCCESS) + .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) + .setData(data) + .render()); + } catch (Throwable e) { + logger.atWarning().withCause(e).log( + "Failed to create registrar. clientId: %s, data: %s", clientId.get(), data); + data.put("errorMessage", e.getMessage()); + response.setPayload( + TOFU_SUPPLIER + .get() + .newRenderer(RegistrarCreateConsoleSoyInfo.FORM_PAGE) + .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) + .setData(data) + .render()); + } + } + + private void runGet(HashMap data) { + // set the values to pre-fill, if given + data.put("clientId", clientId.orElse(null)); + data.put("name", name.orElse(null)); + data.put("ianaId", ianaId.orElse(null)); + data.put("referralEmail", referralEmail.orElse(null)); + data.put("driveId", driveId.orElse(null)); + data.put("email", email.orElse(null)); + + response.setPayload( + TOFU_SUPPLIER + .get() + .newRenderer(RegistrarCreateConsoleSoyInfo.FORM_PAGE) + .setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get()) + .setData(data) + .render()); + } + + private String toEmailLine(Optional value, String name) { + return String.format(" %s: %s\n", name, value.orElse(null)); + } + private void sendExternalUpdates() { + if (!sendEmailUtils.hasRecepients()) { + return; + } + String environment = Ascii.toLowerCase(String.valueOf(registryEnvironment)); + StringBuilder builder = new StringBuilder(); + builder + .append( + String.format( + "The following registrar was created in %s by %s:\n", + environment, registrarAccessor.userIdForLogging())) + .append(toEmailLine(clientId, "clientId")) + .append(toEmailLine(name, "name")) + .append(toEmailLine(billingAccount, "billingAccount")) + .append(toEmailLine(ianaId, "ianaId")) + .append(toEmailLine(referralEmail, "referralEmail")) + .append(toEmailLine(driveId, "driveId")) + .append(String.format("Gave user %s web access to the registrar\n", email.get())); + sendEmailUtils.sendEmail( + String.format("Registrar %s created in %s", clientId.get(), environment), + builder.toString()); + } +} diff --git a/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java b/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java index f4b7d55b1..70f695184 100644 --- a/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java +++ b/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java @@ -15,6 +15,7 @@ package google.registry.ui.server.registrar; +import static google.registry.request.RequestParameters.extractOptionalIntParameter; import static google.registry.request.RequestParameters.extractOptionalParameter; import static google.registry.request.RequestParameters.extractRequiredParameter; @@ -42,6 +43,36 @@ public final class RegistrarConsoleModule { return extractRequiredParameter(req, PARAM_CLIENT_ID); } + @Provides + @Parameter("ianaId") + static Optional provideOptionalIanaId(HttpServletRequest req) { + return extractOptionalIntParameter(req, "ianaId"); + } + + @Provides + @Parameter("billingAccount") + static Optional provideOptionalBillingAccount(HttpServletRequest req) { + return extractOptionalParameter(req, "billingAccount"); + } + + @Provides + @Parameter("name") + static Optional provideOptionalName(HttpServletRequest req) { + return extractOptionalParameter(req, "name"); + } + + @Provides + @Parameter("driveId") + static Optional provideOptionalDriveId(HttpServletRequest req) { + return extractOptionalParameter(req, "driveId"); + } + + @Provides + @Parameter("referralEmail") + static Optional provideOptionalReferralEmail(HttpServletRequest req) { + return extractOptionalParameter(req, "referralEmail"); + } + @Provides @Parameter("email") static Optional provideOptionalEmail(HttpServletRequest req) { @@ -54,9 +85,57 @@ public final class RegistrarConsoleModule { return extractRequiredParameter(req, "email"); } + @Provides + @Parameter("street1") + static Optional provideOptionalStreet1(HttpServletRequest req) { + return extractOptionalParameter(req, "street1"); + } + + @Provides + @Parameter("street2") + static Optional provideOptionalStreet2(HttpServletRequest req) { + return extractOptionalParameter(req, "street2"); + } + + @Provides + @Parameter("street3") + static Optional provideOptionalStreet3(HttpServletRequest req) { + return extractOptionalParameter(req, "street3"); + } + + @Provides + @Parameter("city") + static Optional provideOptionalCity(HttpServletRequest req) { + return extractOptionalParameter(req, "city"); + } + + @Provides + @Parameter("state") + static Optional provideOptionalState(HttpServletRequest req) { + return extractOptionalParameter(req, "state"); + } + + @Provides + @Parameter("zip") + static Optional provideOptionalZip(HttpServletRequest req) { + return extractOptionalParameter(req, "zip"); + } + + @Provides + @Parameter("countryCode") + static Optional provideOptionalCountryCode(HttpServletRequest req) { + return extractOptionalParameter(req, "countryCode"); + } + @Provides @Parameter("password") static Optional provideOptionalPassword(HttpServletRequest req) { return extractOptionalParameter(req, "password"); } + + @Provides + @Parameter("passcode") + static Optional provideOptionalPasscode(HttpServletRequest req) { + return extractOptionalParameter(req, "passcode"); + } } diff --git a/java/google/registry/ui/soy/otesetup/BUILD b/java/google/registry/ui/soy/otesetup/BUILD deleted file mode 100644 index f19b6651c..000000000 --- a/java/google/registry/ui/soy/otesetup/BUILD +++ /dev/null @@ -1,21 +0,0 @@ -package( - default_visibility = ["//java/google/registry:registry_project"], -) - -licenses(["notice"]) # Apache 2.0 - -load("@io_bazel_rules_closure//closure:defs.bzl", "closure_java_template_library", "closure_js_template_library") - -closure_js_template_library( - name = "otesetup", - srcs = glob(["*.soy"]), - data = ["//java/google/registry/ui/css:registrar_raw"], - globals = "//java/google/registry/ui:globals.txt", - deps = ["//java/google/registry/ui/soy"], -) - -closure_java_template_library( - name = "soy_java_wrappers", - srcs = glob(["*.soy"]), - java_package = "google.registry.ui.soy.otesetup", -) diff --git a/java/google/registry/ui/soy/registrar/BUILD b/java/google/registry/ui/soy/registrar/BUILD index f51b1ed6a..5481d63d4 100644 --- a/java/google/registry/ui/soy/registrar/BUILD +++ b/java/google/registry/ui/soy/registrar/BUILD @@ -8,7 +8,13 @@ load("@io_bazel_rules_closure//closure:defs.bzl", "closure_java_template_library closure_js_template_library( name = "registrar", - srcs = glob(["*.soy"]), + srcs = glob( + ["*.soy"], + exclude = [ + "OteSetupConsole.soy", + "RegistrarCreateConsole.soy", + ], + ), data = ["//java/google/registry/ui/css:registrar_raw"], globals = "//java/google/registry/ui:globals.txt", deps = ["//java/google/registry/ui/soy"], diff --git a/java/google/registry/ui/soy/otesetup/Console.soy b/java/google/registry/ui/soy/registrar/OteSetupConsole.soy similarity index 98% rename from java/google/registry/ui/soy/otesetup/Console.soy rename to java/google/registry/ui/soy/registrar/OteSetupConsole.soy index 81e306aa3..457bdcd26 100644 --- a/java/google/registry/ui/soy/otesetup/Console.soy +++ b/java/google/registry/ui/soy/registrar/OteSetupConsole.soy @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -{namespace registry.soy.registrar.console} +{namespace registry.soy.registrar.otesetup} /** @@ -35,7 +35,7 @@ {call registry.soy.console.googlebar data="all" /}