From bef28d2e34b4125301885350f81489b2ffe241c3 Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Tue, 11 Jul 2023 11:49:16 -0400 Subject: [PATCH] Remove internal auth mechanism (#2066) It was used by cron job and task queues, which now use OIDC-based auth. Also renamed and consolidated auth enums to make them easier to understand. Ultimately we should get rid of the AuthMethod part as OIDC will be the only auth method used. Based on the updated routing map: Backend and tools: the only change is that INTERNAL is removed from allowed auth methods. Should be an no-op. Pubapi: INTERNAL is removed from allowed auth. For endpoints that only allowed INTERNAL before, API and LEGACY become the allowed methods. However this should not affect anything because regardless of which auth method is ultimately used, the required auth level is always NONE for pubapi endpoints. Therefore any auth result is discarded anyway. Frontend: INTERNAL is removed. RegistryLockVerifyAction has lowered its required auth level to NONE because it extends HtmlAction, which can redirect the user to login if necessary. All other endpoints extending HtmlAction require NONE, so it's better to keep things consistent. --- .../batch/CannedScriptExecutionAction.java | 2 +- .../batch/CheckPackagesComplianceAction.java | 2 +- .../batch/DeleteExpiredDomainsAction.java | 2 +- .../batch/DeleteLoadTestDataAction.java | 2 +- .../batch/DeleteProberDataAction.java | 2 +- .../batch/ExpandBillingRecurrencesAction.java | 2 +- .../registry/batch/RelockDomainAction.java | 2 +- .../ResaveAllEppResourcesPipelineAction.java | 2 +- .../registry/batch/ResaveEntityAction.java | 2 +- ...ingCertificateNotificationEmailAction.java | 2 +- .../registry/batch/WipeOutCloudSqlAction.java | 2 +- .../batch/WipeOutContactHistoryPiiAction.java | 2 +- .../google/registry/cron/TldFanoutAction.java | 2 +- .../registry/dns/PublishDnsUpdatesAction.java | 2 +- .../dns/ReadDnsRefreshRequestsAction.java | 2 +- .../google/registry/dns/RefreshDnsAction.java | 2 +- .../dns/RefreshDnsOnHostRenameAction.java | 2 +- .../export/ExportDomainListsAction.java | 2 +- .../export/ExportPremiumTermsAction.java | 2 +- .../export/ExportReservedTermsAction.java | 2 +- .../export/SyncGroupMembersAction.java | 2 +- .../sheet/SyncRegistrarsSheetAction.java | 2 +- .../google/registry/flows/CheckApiAction.java | 2 +- .../google/registry/flows/EppTlsAction.java | 2 +- .../google/registry/flows/EppToolAction.java | 2 +- .../registry/loadtest/LoadTestAction.java | 2 +- .../registry/rdap/RdapAutnumAction.java | 2 +- .../google/registry/rdap/RdapHelpAction.java | 2 +- .../google/registry/rdap/RdapIpAction.java | 2 +- .../registry/rdap/RdapNameserverAction.java | 2 +- .../rdap/RdapNameserverSearchAction.java | 2 +- .../UpdateRegistrarRdapBaseUrlsAction.java | 2 +- .../google/registry/rde/BrdaCopyAction.java | 2 +- .../google/registry/rde/RdeReportAction.java | 2 +- .../google/registry/rde/RdeStagingAction.java | 2 +- .../google/registry/rde/RdeUploadAction.java | 2 +- .../billing/CopyDetailReportsAction.java | 2 +- .../billing/GenerateInvoicesAction.java | 2 +- .../billing/PublishInvoicesAction.java | 2 +- .../icann/IcannReportingStagingAction.java | 2 +- .../icann/IcannReportingUploadAction.java | 2 +- .../spec11/GenerateSpec11ReportAction.java | 2 +- .../spec11/PublishSpec11ReportAction.java | 2 +- ...EngineInternalAuthenticationMechanism.java | 62 -------- .../google/registry/request/auth/Auth.java | 58 ++++---- .../registry/request/auth/AuthSettings.java | 8 +- .../request/auth/RequestAuthenticator.java | 82 +++-------- .../registry/tmch/NordnUploadAction.java | 2 +- .../registry/tmch/NordnVerifyAction.java | 2 +- .../google/registry/tmch/TmchCrlAction.java | 2 +- .../google/registry/tmch/TmchDnlAction.java | 2 +- .../google/registry/tmch/TmchSmdrlAction.java | 2 +- .../tools/server/CreateGroupsAction.java | 2 +- .../tools/server/GenerateZoneFilesAction.java | 2 +- .../tools/server/ListDomainsAction.java | 2 +- .../tools/server/ListHostsAction.java | 2 +- .../tools/server/ListPremiumListsAction.java | 2 +- .../tools/server/ListRegistrarsAction.java | 2 +- .../tools/server/ListReservedListsAction.java | 2 +- .../registry/tools/server/ListTldsAction.java | 2 +- .../server/RefreshDnsForAllDomainsAction.java | 6 +- .../tools/server/VerifyOteAction.java | 2 +- .../ui/server/registrar/ConsoleUiAction.java | 2 +- .../ui/server/registrar/HtmlAction.java | 2 +- .../registrar/RegistryLockVerifyAction.java | 2 +- .../google/registry/whois/WhoisAction.java | 2 +- .../registry/whois/WhoisHttpAction.java | 2 +- .../registry/rdap/RdapActionBaseTest.java | 2 +- .../registry/request/RequestHandlerTest.java | 52 +------ .../google/registry/request/RouterTest.java | 18 +-- .../auth/RequestAuthenticatorTest.java | 138 +++++------------- .../module/backend/backend_routing.txt | 76 +++++----- .../module/frontend/frontend_routing.txt | 26 ++-- .../registry/module/pubapi/pubapi_routing.txt | 26 ++-- .../registry/module/tools/tools_routing.txt | 24 +-- 75 files changed, 237 insertions(+), 465 deletions(-) delete mode 100644 core/src/main/java/google/registry/request/auth/AppEngineInternalAuthenticationMechanism.java diff --git a/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java b/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java index c1fceb2e5..2558f4a4b 100644 --- a/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java +++ b/core/src/main/java/google/registry/batch/CannedScriptExecutionAction.java @@ -52,7 +52,7 @@ import javax.mail.internet.InternetAddress; path = "/_dr/task/executeCannedScript", method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class CannedScriptExecutionAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/batch/CheckPackagesComplianceAction.java b/core/src/main/java/google/registry/batch/CheckPackagesComplianceAction.java index 5e5945cdc..43b0a0100 100644 --- a/core/src/main/java/google/registry/batch/CheckPackagesComplianceAction.java +++ b/core/src/main/java/google/registry/batch/CheckPackagesComplianceAction.java @@ -41,7 +41,7 @@ import org.joda.time.Days; @Action( service = Service.BACKEND, path = CheckPackagesComplianceAction.PATH, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class CheckPackagesComplianceAction implements Runnable { public static final String PATH = "/_dr/task/checkPackagesCompliance"; diff --git a/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java b/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java index b46885857..01d681ee5 100644 --- a/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java +++ b/core/src/main/java/google/registry/batch/DeleteExpiredDomainsAction.java @@ -69,7 +69,7 @@ import org.joda.time.Duration; @Action( service = Action.Service.BACKEND, path = DeleteExpiredDomainsAction.PATH, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class DeleteExpiredDomainsAction implements Runnable { public static final String PATH = "/_dr/task/deleteExpiredDomains"; diff --git a/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java b/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java index c8f2307af..95a1fb0ff 100644 --- a/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteLoadTestDataAction.java @@ -56,7 +56,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/task/deleteLoadTestData", method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class DeleteLoadTestDataAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java index d5fabeb3c..929e70555 100644 --- a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java @@ -58,7 +58,7 @@ import org.joda.time.Duration; service = Action.Service.BACKEND, path = "/_dr/task/deleteProberData", method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class DeleteProberDataAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/batch/ExpandBillingRecurrencesAction.java b/core/src/main/java/google/registry/batch/ExpandBillingRecurrencesAction.java index 107ade955..d24105585 100644 --- a/core/src/main/java/google/registry/batch/ExpandBillingRecurrencesAction.java +++ b/core/src/main/java/google/registry/batch/ExpandBillingRecurrencesAction.java @@ -52,7 +52,7 @@ import org.joda.time.DateTime; @Action( service = Action.Service.BACKEND, path = "/_dr/task/expandBillingRecurrences", - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class ExpandBillingRecurrencesAction implements Runnable { public static final String PARAM_START_TIME = "startTime"; diff --git a/core/src/main/java/google/registry/batch/RelockDomainAction.java b/core/src/main/java/google/registry/batch/RelockDomainAction.java index dc8d1b7a3..63a13a218 100644 --- a/core/src/main/java/google/registry/batch/RelockDomainAction.java +++ b/core/src/main/java/google/registry/batch/RelockDomainAction.java @@ -53,7 +53,7 @@ import org.joda.time.Duration; path = RelockDomainAction.PATH, method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class RelockDomainAction implements Runnable { public static final String PATH = "/_dr/task/relockDomain"; diff --git a/core/src/main/java/google/registry/batch/ResaveAllEppResourcesPipelineAction.java b/core/src/main/java/google/registry/batch/ResaveAllEppResourcesPipelineAction.java index 69477f870..bca5eef79 100644 --- a/core/src/main/java/google/registry/batch/ResaveAllEppResourcesPipelineAction.java +++ b/core/src/main/java/google/registry/batch/ResaveAllEppResourcesPipelineAction.java @@ -55,7 +55,7 @@ import javax.inject.Inject; @Action( service = Action.Service.BACKEND, path = ResaveAllEppResourcesPipelineAction.PATH, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class ResaveAllEppResourcesPipelineAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/batch/ResaveEntityAction.java b/core/src/main/java/google/registry/batch/ResaveEntityAction.java index fc74a2d81..7fcb4505d 100644 --- a/core/src/main/java/google/registry/batch/ResaveEntityAction.java +++ b/core/src/main/java/google/registry/batch/ResaveEntityAction.java @@ -40,7 +40,7 @@ import org.joda.time.DateTime; @Action( service = Action.Service.BACKEND, path = ResaveEntityAction.PATH, - auth = Auth.AUTH_INTERNAL_OR_ADMIN, + auth = Auth.AUTH_API_ADMIN, method = Method.POST) public class ResaveEntityAction implements Runnable { diff --git a/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java b/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java index 6e977f87e..0cb67a869 100644 --- a/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java +++ b/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java @@ -53,7 +53,7 @@ import org.joda.time.format.DateTimeFormatter; @Action( service = Action.Service.BACKEND, path = SendExpiringCertificateNotificationEmailAction.PATH, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class SendExpiringCertificateNotificationEmailAction implements Runnable { public static final String PATH = "/_dr/task/sendExpiringCertificateNotificationEmail"; diff --git a/core/src/main/java/google/registry/batch/WipeOutCloudSqlAction.java b/core/src/main/java/google/registry/batch/WipeOutCloudSqlAction.java index bbbec41fe..a3e9baacf 100644 --- a/core/src/main/java/google/registry/batch/WipeOutCloudSqlAction.java +++ b/core/src/main/java/google/registry/batch/WipeOutCloudSqlAction.java @@ -44,7 +44,7 @@ import javax.inject.Inject; @Action( service = Action.Service.BACKEND, path = "/_dr/task/wipeOutCloudSql", - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class WipeOutCloudSqlAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/batch/WipeOutContactHistoryPiiAction.java b/core/src/main/java/google/registry/batch/WipeOutContactHistoryPiiAction.java index 5ff58cbb2..48406591e 100644 --- a/core/src/main/java/google/registry/batch/WipeOutContactHistoryPiiAction.java +++ b/core/src/main/java/google/registry/batch/WipeOutContactHistoryPiiAction.java @@ -51,7 +51,7 @@ import org.joda.time.DateTime; @Action( service = Service.BACKEND, path = WipeOutContactHistoryPiiAction.PATH, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class WipeOutContactHistoryPiiAction implements Runnable { public static final String PATH = "/_dr/task/wipeOutContactHistoryPii"; diff --git a/core/src/main/java/google/registry/cron/TldFanoutAction.java b/core/src/main/java/google/registry/cron/TldFanoutAction.java index 6073cf74f..714008354 100644 --- a/core/src/main/java/google/registry/cron/TldFanoutAction.java +++ b/core/src/main/java/google/registry/cron/TldFanoutAction.java @@ -81,7 +81,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/cron/fanout", automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class TldFanoutAction implements Runnable { /** A set of control params to TldFanoutAction that aren't passed down to the executing action. */ diff --git a/core/src/main/java/google/registry/dns/PublishDnsUpdatesAction.java b/core/src/main/java/google/registry/dns/PublishDnsUpdatesAction.java index ff8199073..0a5a762dd 100644 --- a/core/src/main/java/google/registry/dns/PublishDnsUpdatesAction.java +++ b/core/src/main/java/google/registry/dns/PublishDnsUpdatesAction.java @@ -76,7 +76,7 @@ import org.joda.time.Duration; path = PublishDnsUpdatesAction.PATH, method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class PublishDnsUpdatesAction implements Runnable, Callable { public static final String PATH = "/_dr/task/publishDnsUpdates"; diff --git a/core/src/main/java/google/registry/dns/ReadDnsRefreshRequestsAction.java b/core/src/main/java/google/registry/dns/ReadDnsRefreshRequestsAction.java index 0e4cf5338..257cd4bc1 100644 --- a/core/src/main/java/google/registry/dns/ReadDnsRefreshRequestsAction.java +++ b/core/src/main/java/google/registry/dns/ReadDnsRefreshRequestsAction.java @@ -64,7 +64,7 @@ import org.joda.time.Duration; path = "/_dr/task/readDnsRefreshRequests", automaticallyPrintOk = true, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ReadDnsRefreshRequestsAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/dns/RefreshDnsAction.java b/core/src/main/java/google/registry/dns/RefreshDnsAction.java index aeaeec3cf..36f0e914b 100644 --- a/core/src/main/java/google/registry/dns/RefreshDnsAction.java +++ b/core/src/main/java/google/registry/dns/RefreshDnsAction.java @@ -38,7 +38,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/dnsRefresh", automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class RefreshDnsAction implements Runnable { private final Clock clock; diff --git a/core/src/main/java/google/registry/dns/RefreshDnsOnHostRenameAction.java b/core/src/main/java/google/registry/dns/RefreshDnsOnHostRenameAction.java index e70d1f913..cebc181f5 100644 --- a/core/src/main/java/google/registry/dns/RefreshDnsOnHostRenameAction.java +++ b/core/src/main/java/google/registry/dns/RefreshDnsOnHostRenameAction.java @@ -37,7 +37,7 @@ import org.joda.time.DateTime; service = Service.BACKEND, path = PATH, method = Action.Method.POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class RefreshDnsOnHostRenameAction implements Runnable { public static final String QUEUE_HOST_RENAME = "async-host-rename"; diff --git a/core/src/main/java/google/registry/export/ExportDomainListsAction.java b/core/src/main/java/google/registry/export/ExportDomainListsAction.java index dca294617..7cb2fc224 100644 --- a/core/src/main/java/google/registry/export/ExportDomainListsAction.java +++ b/core/src/main/java/google/registry/export/ExportDomainListsAction.java @@ -49,7 +49,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/task/exportDomainLists", method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class ExportDomainListsAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/export/ExportPremiumTermsAction.java b/core/src/main/java/google/registry/export/ExportPremiumTermsAction.java index 31ed8ebcd..580da742b 100644 --- a/core/src/main/java/google/registry/export/ExportPremiumTermsAction.java +++ b/core/src/main/java/google/registry/export/ExportPremiumTermsAction.java @@ -48,7 +48,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/task/exportPremiumTerms", method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class ExportPremiumTermsAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/export/ExportReservedTermsAction.java b/core/src/main/java/google/registry/export/ExportReservedTermsAction.java index c9588e447..46263c61b 100644 --- a/core/src/main/java/google/registry/export/ExportReservedTermsAction.java +++ b/core/src/main/java/google/registry/export/ExportReservedTermsAction.java @@ -37,7 +37,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/task/exportReservedTerms", method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class ExportReservedTermsAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/export/SyncGroupMembersAction.java b/core/src/main/java/google/registry/export/SyncGroupMembersAction.java index 07b7a6b3d..5df979dea 100644 --- a/core/src/main/java/google/registry/export/SyncGroupMembersAction.java +++ b/core/src/main/java/google/registry/export/SyncGroupMembersAction.java @@ -55,7 +55,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = "/_dr/task/syncGroupMembers", method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class SyncGroupMembersAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java b/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java index fdb099327..edc79371b 100644 --- a/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java +++ b/core/src/main/java/google/registry/export/sheet/SyncRegistrarsSheetAction.java @@ -57,7 +57,7 @@ import org.joda.time.Duration; service = Action.Service.BACKEND, path = SyncRegistrarsSheetAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class SyncRegistrarsSheetAction implements Runnable { private enum Result { diff --git a/core/src/main/java/google/registry/flows/CheckApiAction.java b/core/src/main/java/google/registry/flows/CheckApiAction.java index 64a3248dd..7f27a58f5 100644 --- a/core/src/main/java/google/registry/flows/CheckApiAction.java +++ b/core/src/main/java/google/registry/flows/CheckApiAction.java @@ -69,7 +69,7 @@ import org.joda.time.DateTime; * user controlled, lest it open an XSS vector. Do not modify this to return the domain name in the * response. */ -@Action(service = Action.Service.PUBAPI, path = "/check", auth = Auth.AUTH_PUBLIC_ANONYMOUS) +@Action(service = Action.Service.PUBAPI, path = "/check", auth = Auth.AUTH_PUBLIC) public class CheckApiAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/flows/EppTlsAction.java b/core/src/main/java/google/registry/flows/EppTlsAction.java index 3d42cc562..a1f63cae6 100644 --- a/core/src/main/java/google/registry/flows/EppTlsAction.java +++ b/core/src/main/java/google/registry/flows/EppTlsAction.java @@ -29,7 +29,7 @@ import javax.servlet.http.HttpSession; service = Action.Service.DEFAULT, path = "/_dr/epp", method = Method.POST, - auth = Auth.AUTH_PUBLIC_OR_INTERNAL) + auth = Auth.AUTH_API_PUBLIC) public class EppTlsAction implements Runnable { @Inject @Payload byte[] inputXmlBytes; diff --git a/core/src/main/java/google/registry/flows/EppToolAction.java b/core/src/main/java/google/registry/flows/EppToolAction.java index 1129e6bf9..e096f3ae7 100644 --- a/core/src/main/java/google/registry/flows/EppToolAction.java +++ b/core/src/main/java/google/registry/flows/EppToolAction.java @@ -33,7 +33,7 @@ import javax.servlet.http.HttpServletRequest; service = Action.Service.TOOLS, path = EppToolAction.PATH, method = Method.POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class EppToolAction implements Runnable { public static final String PATH = "/_dr/epptool"; diff --git a/core/src/main/java/google/registry/loadtest/LoadTestAction.java b/core/src/main/java/google/registry/loadtest/LoadTestAction.java index cbc40b76c..cb4be932e 100644 --- a/core/src/main/java/google/registry/loadtest/LoadTestAction.java +++ b/core/src/main/java/google/registry/loadtest/LoadTestAction.java @@ -58,7 +58,7 @@ import org.joda.time.DateTime; path = LoadTestAction.PATH, method = Action.Method.POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class LoadTestAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/rdap/RdapAutnumAction.java b/core/src/main/java/google/registry/rdap/RdapAutnumAction.java index e55b6b730..2293811a8 100644 --- a/core/src/main/java/google/registry/rdap/RdapAutnumAction.java +++ b/core/src/main/java/google/registry/rdap/RdapAutnumAction.java @@ -35,7 +35,7 @@ import javax.inject.Inject; path = "/rdap/autnum/", method = {GET, HEAD}, isPrefix = true, - auth = Auth.AUTH_PUBLIC_ANONYMOUS) + auth = Auth.AUTH_PUBLIC) public class RdapAutnumAction extends RdapActionBase { @Inject RdapAutnumAction() { diff --git a/core/src/main/java/google/registry/rdap/RdapHelpAction.java b/core/src/main/java/google/registry/rdap/RdapHelpAction.java index fff04281b..bf7163699 100644 --- a/core/src/main/java/google/registry/rdap/RdapHelpAction.java +++ b/core/src/main/java/google/registry/rdap/RdapHelpAction.java @@ -33,7 +33,7 @@ import javax.inject.Inject; path = "/rdap/help", method = {GET, HEAD}, isPrefix = true, - auth = Auth.AUTH_PUBLIC_ANONYMOUS) + auth = Auth.AUTH_PUBLIC) public class RdapHelpAction extends RdapActionBase { /** The help path for the RDAP terms of service. */ diff --git a/core/src/main/java/google/registry/rdap/RdapIpAction.java b/core/src/main/java/google/registry/rdap/RdapIpAction.java index 590fedd76..220918409 100644 --- a/core/src/main/java/google/registry/rdap/RdapIpAction.java +++ b/core/src/main/java/google/registry/rdap/RdapIpAction.java @@ -35,7 +35,7 @@ import javax.inject.Inject; path = "/rdap/ip/", method = {GET, HEAD}, isPrefix = true, - auth = Auth.AUTH_PUBLIC_ANONYMOUS) + auth = Auth.AUTH_PUBLIC) public class RdapIpAction extends RdapActionBase { @Inject RdapIpAction() { diff --git a/core/src/main/java/google/registry/rdap/RdapNameserverAction.java b/core/src/main/java/google/registry/rdap/RdapNameserverAction.java index d5bee577c..ac45c5a43 100644 --- a/core/src/main/java/google/registry/rdap/RdapNameserverAction.java +++ b/core/src/main/java/google/registry/rdap/RdapNameserverAction.java @@ -38,7 +38,7 @@ import javax.inject.Inject; path = "/rdap/nameserver/", method = {GET, HEAD}, isPrefix = true, - auth = Auth.AUTH_PUBLIC_ANONYMOUS) + auth = Auth.AUTH_PUBLIC) public class RdapNameserverAction extends RdapActionBase { @Inject public RdapNameserverAction() { diff --git a/core/src/main/java/google/registry/rdap/RdapNameserverSearchAction.java b/core/src/main/java/google/registry/rdap/RdapNameserverSearchAction.java index d1eb7c2c5..1f1bd9796 100644 --- a/core/src/main/java/google/registry/rdap/RdapNameserverSearchAction.java +++ b/core/src/main/java/google/registry/rdap/RdapNameserverSearchAction.java @@ -59,7 +59,7 @@ import javax.inject.Inject; service = Action.Service.PUBAPI, path = "/rdap/nameservers", method = {GET, HEAD}, - auth = Auth.AUTH_PUBLIC_ANONYMOUS) + auth = Auth.AUTH_PUBLIC) public class RdapNameserverSearchAction extends RdapSearchActionBase { public static final String PATH = "/rdap/nameservers"; diff --git a/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java b/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java index bbc80f129..a330e85ff 100644 --- a/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java +++ b/core/src/main/java/google/registry/rdap/UpdateRegistrarRdapBaseUrlsAction.java @@ -49,7 +49,7 @@ import org.apache.commons.csv.CSVRecord; service = Action.Service.BACKEND, path = "/_dr/task/updateRegistrarRdapBaseUrls", automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable { private static final GenericUrl RDAP_IDS_URL = diff --git a/core/src/main/java/google/registry/rde/BrdaCopyAction.java b/core/src/main/java/google/registry/rde/BrdaCopyAction.java index fb454df42..25c653b8e 100644 --- a/core/src/main/java/google/registry/rde/BrdaCopyAction.java +++ b/core/src/main/java/google/registry/rde/BrdaCopyAction.java @@ -66,7 +66,7 @@ import org.joda.time.DateTime; path = BrdaCopyAction.PATH, method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class BrdaCopyAction implements Runnable { public static final String PATH = "/_dr/task/brdaCopy"; diff --git a/core/src/main/java/google/registry/rde/RdeReportAction.java b/core/src/main/java/google/registry/rde/RdeReportAction.java index a2faed9ec..5ff9bef1f 100644 --- a/core/src/main/java/google/registry/rde/RdeReportAction.java +++ b/core/src/main/java/google/registry/rde/RdeReportAction.java @@ -56,7 +56,7 @@ import org.joda.time.Duration; service = Action.Service.BACKEND, path = RdeReportAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class RdeReportAction implements Runnable, EscrowTask { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/rde/RdeStagingAction.java b/core/src/main/java/google/registry/rde/RdeStagingAction.java index 120126f13..ff1ae8ceb 100644 --- a/core/src/main/java/google/registry/rde/RdeStagingAction.java +++ b/core/src/main/java/google/registry/rde/RdeStagingAction.java @@ -207,7 +207,7 @@ import org.joda.time.Duration; service = Action.Service.BACKEND, path = RdeStagingAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class RdeStagingAction implements Runnable { public static final String PATH = "/_dr/task/rdeStaging"; diff --git a/core/src/main/java/google/registry/rde/RdeUploadAction.java b/core/src/main/java/google/registry/rde/RdeUploadAction.java index 042796b4e..523ea97e5 100644 --- a/core/src/main/java/google/registry/rde/RdeUploadAction.java +++ b/core/src/main/java/google/registry/rde/RdeUploadAction.java @@ -87,7 +87,7 @@ import org.joda.time.Duration; service = Action.Service.BACKEND, path = RdeUploadAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class RdeUploadAction implements Runnable, EscrowTask { public static final String PATH = "/_dr/task/rdeUpload"; diff --git a/core/src/main/java/google/registry/reporting/billing/CopyDetailReportsAction.java b/core/src/main/java/google/registry/reporting/billing/CopyDetailReportsAction.java index f95a4bed3..b768931c9 100644 --- a/core/src/main/java/google/registry/reporting/billing/CopyDetailReportsAction.java +++ b/core/src/main/java/google/registry/reporting/billing/CopyDetailReportsAction.java @@ -47,7 +47,7 @@ import javax.inject.Inject; service = Action.Service.BACKEND, path = CopyDetailReportsAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class CopyDetailReportsAction implements Runnable { public static final String PATH = "/_dr/task/copyDetailReports"; diff --git a/core/src/main/java/google/registry/reporting/billing/GenerateInvoicesAction.java b/core/src/main/java/google/registry/reporting/billing/GenerateInvoicesAction.java index dd553c4f9..c18786a49 100644 --- a/core/src/main/java/google/registry/reporting/billing/GenerateInvoicesAction.java +++ b/core/src/main/java/google/registry/reporting/billing/GenerateInvoicesAction.java @@ -54,7 +54,7 @@ import org.joda.time.YearMonth; service = Action.Service.BACKEND, path = GenerateInvoicesAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class GenerateInvoicesAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/reporting/billing/PublishInvoicesAction.java b/core/src/main/java/google/registry/reporting/billing/PublishInvoicesAction.java index 3ea8031a8..4db12d281 100644 --- a/core/src/main/java/google/registry/reporting/billing/PublishInvoicesAction.java +++ b/core/src/main/java/google/registry/reporting/billing/PublishInvoicesAction.java @@ -52,7 +52,7 @@ import org.joda.time.YearMonth; service = Action.Service.BACKEND, path = PublishInvoicesAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class PublishInvoicesAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/reporting/icann/IcannReportingStagingAction.java b/core/src/main/java/google/registry/reporting/icann/IcannReportingStagingAction.java index 1d5a86cb9..a5ed560a1 100644 --- a/core/src/main/java/google/registry/reporting/icann/IcannReportingStagingAction.java +++ b/core/src/main/java/google/registry/reporting/icann/IcannReportingStagingAction.java @@ -67,7 +67,7 @@ import org.joda.time.format.DateTimeFormat; service = Action.Service.BACKEND, path = IcannReportingStagingAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class IcannReportingStagingAction implements Runnable { static final String PATH = "/_dr/task/icannReportingStaging"; diff --git a/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java b/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java index 1c73cf64f..9f43f6f26 100644 --- a/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java +++ b/core/src/main/java/google/registry/reporting/icann/IcannReportingUploadAction.java @@ -70,7 +70,7 @@ import org.joda.time.Duration; service = Action.Service.BACKEND, path = IcannReportingUploadAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class IcannReportingUploadAction implements Runnable { static final String PATH = "/_dr/task/icannReportingUpload"; diff --git a/core/src/main/java/google/registry/reporting/spec11/GenerateSpec11ReportAction.java b/core/src/main/java/google/registry/reporting/spec11/GenerateSpec11ReportAction.java index 2a6af1776..d92ba0f4a 100644 --- a/core/src/main/java/google/registry/reporting/spec11/GenerateSpec11ReportAction.java +++ b/core/src/main/java/google/registry/reporting/spec11/GenerateSpec11ReportAction.java @@ -53,7 +53,7 @@ import org.joda.time.LocalDate; service = Action.Service.BACKEND, path = GenerateSpec11ReportAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class GenerateSpec11ReportAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/reporting/spec11/PublishSpec11ReportAction.java b/core/src/main/java/google/registry/reporting/spec11/PublishSpec11ReportAction.java index 6cc9eba8c..f3a91328e 100644 --- a/core/src/main/java/google/registry/reporting/spec11/PublishSpec11ReportAction.java +++ b/core/src/main/java/google/registry/reporting/spec11/PublishSpec11ReportAction.java @@ -59,7 +59,7 @@ import org.json.JSONException; service = Action.Service.BACKEND, path = PublishSpec11ReportAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class PublishSpec11ReportAction implements Runnable { static final String PATH = "/_dr/task/publishSpec11"; diff --git a/core/src/main/java/google/registry/request/auth/AppEngineInternalAuthenticationMechanism.java b/core/src/main/java/google/registry/request/auth/AppEngineInternalAuthenticationMechanism.java deleted file mode 100644 index 5b0421133..000000000 --- a/core/src/main/java/google/registry/request/auth/AppEngineInternalAuthenticationMechanism.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 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.request.auth; - -import static google.registry.request.auth.AuthSettings.AuthLevel.APP; -import static google.registry.request.auth.AuthSettings.AuthLevel.NONE; - -import com.google.appengine.api.users.UserService; -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; - -/** - * Authentication mechanism which uses the X-AppEngine-QueueName header set by App Engine for - * internal requests. - * - *

Task queue push task requests set this header value to the actual queue name. Cron requests - * set this header value to __cron, since that's actually the name of the hidden queue used for cron - * requests. Cron also sets the header X-AppEngine-Cron, which we could check, but it's simpler just - * to check the one. - * - *

App Engine allows app admins to set these headers for testing purposes. Because of this, we - * also need to verify that the current user is null, indicating that there is no user, to prevent - * access by someone with "admin" privileges. If the user is an admin, UserService presumably must - * return a User object. - * - *

See task - * handler request header documentation - */ -public class AppEngineInternalAuthenticationMechanism implements AuthenticationMechanism { - - // As defined in the App Engine request header documentation. - private static final String QUEUE_NAME_HEADER = "X-AppEngine-QueueName"; - - private UserService userService; - - @Inject - public AppEngineInternalAuthenticationMechanism(UserService userService) { - this.userService = userService; - } - - @Override - public AuthResult authenticate(HttpServletRequest request) { - if (request.getHeader(QUEUE_NAME_HEADER) == null || userService.getCurrentUser() != null) { - return AuthResult.create(NONE); - } else { - return AuthResult.create(APP); - } - } -} diff --git a/core/src/main/java/google/registry/request/auth/Auth.java b/core/src/main/java/google/registry/request/auth/Auth.java index ead0c7b17..3acc4d32c 100644 --- a/core/src/main/java/google/registry/request/auth/Auth.java +++ b/core/src/main/java/google/registry/request/auth/Auth.java @@ -15,63 +15,65 @@ package google.registry.request.auth; import com.google.common.collect.ImmutableList; +import google.registry.flows.EppTlsAction; +import google.registry.flows.TlsCredentials; import google.registry.request.auth.AuthSettings.AuthLevel; import google.registry.request.auth.AuthSettings.AuthMethod; import google.registry.request.auth.AuthSettings.UserPolicy; +import google.registry.ui.server.registrar.HtmlAction; +import google.registry.ui.server.registrar.JsonGetAction; /** Enum used to configure authentication settings for Actions. */ public enum Auth { /** - * Allows anyone access, doesn't attempt to authenticate user. - * - *

Will never return absent(), but only authenticates access from App Engine task-queues. For - * everyone else - returns NOT_AUTHENTICATED. - */ - AUTH_PUBLIC_ANONYMOUS(ImmutableList.of(AuthMethod.INTERNAL), AuthLevel.NONE, UserPolicy.PUBLIC), - - /** - * Allows anyone to access, does attempt to authenticate user. + * Allows anyone to access. * *

If a user is logged in, will authenticate (and return) them. Otherwise, access is still * granted, but NOT_AUTHENTICATED is returned. * - *

Will never return absent(). + *

This is used for public HTML endpoints like RDAP, the check API, and web WHOIS. + * + *

User-facing legacy console endpoints (those that extend {@link HtmlAction}) also use it. + * They need to allow requests from signed-out users so that they can redirect users to the login + * page. After a user is logged in, they check if the user actually has access to the specific + * console using {@link AuthenticatedRegistrarAccessor}. + * + * @see HtmlAction */ AUTH_PUBLIC( - ImmutableList.of(AuthMethod.INTERNAL, AuthMethod.API, AuthMethod.LEGACY), - AuthLevel.NONE, - UserPolicy.PUBLIC), + ImmutableList.of(AuthMethod.API, AuthMethod.LEGACY), AuthLevel.NONE, UserPolicy.PUBLIC), /** * Allows anyone to access, as long as they are logged in. * - *

Does not allow access from App Engine task-queues. + *

This is used by legacy registrar console programmatic endpoints (those that extend {@link + * JsonGetAction}, which are accessed via XHR requests sent from a logged-in user when performing + * actions on the console. */ AUTH_PUBLIC_LOGGED_IN( ImmutableList.of(AuthMethod.API, AuthMethod.LEGACY), AuthLevel.USER, UserPolicy.PUBLIC), /** - * Allows anyone to access, as long as they use OAuth to authenticate. + * Allows any client to access, as long as they are logged in via API-based authentication + * mechanisms. * - *

Also allows access from App Engine task-queue. Note that OAuth client ID still needs to be - * allow-listed in the config file for OAuth-based authentication to succeed. + *

This is used by the proxy to access Nomulus endpoints. The proxy service account does NOT + * have admin privileges. For EPP, we handle client authentication within {@link EppTlsAction}, + * using {@link TlsCredentials}. For WHOIS, anyone connecting to the proxy can access. + * + *

Note that the proxy service account DOES need to be allow-listed in the {@code + * auth.allowedServiceAccountEmails} field in the config YAML file in order for OIDC-based + * authentication to pass. */ - AUTH_PUBLIC_OR_INTERNAL( - ImmutableList.of(AuthMethod.INTERNAL, AuthMethod.API), AuthLevel.APP, UserPolicy.PUBLIC), - - /** Allows only admins or App Engine task-queue access. */ - AUTH_INTERNAL_OR_ADMIN( - ImmutableList.of(AuthMethod.INTERNAL, AuthMethod.API), AuthLevel.APP, UserPolicy.ADMIN), + AUTH_API_PUBLIC(ImmutableList.of(AuthMethod.API), AuthLevel.APP, UserPolicy.PUBLIC), /** - * Allows only App Engine task-queue access. + * Allows only admins to access. * - *

In general, prefer AUTH_INTERNAL_OR_ADMIN. This level of access should be reserved for - * endpoints that have some sensitivity (it was introduced to mitigate a remote-shell - * vulnerability). + *

This applies to the majority of the endpoints. */ - AUTH_INTERNAL_ONLY(ImmutableList.of(AuthMethod.INTERNAL), AuthLevel.APP, UserPolicy.IGNORED); + AUTH_API_ADMIN(ImmutableList.of(AuthMethod.API), AuthLevel.APP, UserPolicy.ADMIN); private final AuthSettings authSettings; diff --git a/core/src/main/java/google/registry/request/auth/AuthSettings.java b/core/src/main/java/google/registry/request/auth/AuthSettings.java index 3b41d4bfa..5448ae8c0 100644 --- a/core/src/main/java/google/registry/request/auth/AuthSettings.java +++ b/core/src/main/java/google/registry/request/auth/AuthSettings.java @@ -42,9 +42,6 @@ public abstract class AuthSettings { /** Available methods for authentication. */ public enum AuthMethod { - /** App Engine internal authentication. Must always be provided as the first method. */ - INTERNAL, - /** Authentication methods suitable for API-style access, such as OAuth 2. */ API, @@ -55,7 +52,7 @@ public abstract class AuthSettings { /** * Authentication level. * - *

Used by {@link Auth} to specify what authentication is required, and by {@link AuthResult}) + *

Used by {@link Auth} to specify what authentication is required, and by {@link AuthResult} * to specify what authentication was found. These are a series of levels, from least to most * authentication required. The lowest level of requirement, NONE, can be satisfied by any level * of authentication, while the highest level, USER, can only be satisfied by the authentication @@ -92,9 +89,6 @@ public abstract class AuthSettings { /** User authorization policy options. */ public enum UserPolicy { - /** This action ignores end users; the only configured auth method must be INTERNAL. */ - IGNORED, - /** No user policy is enforced; anyone can access this action. */ PUBLIC, diff --git a/core/src/main/java/google/registry/request/auth/RequestAuthenticator.java b/core/src/main/java/google/registry/request/auth/RequestAuthenticator.java index 1c02c533c..10747dd6f 100644 --- a/core/src/main/java/google/registry/request/auth/RequestAuthenticator.java +++ b/core/src/main/java/google/registry/request/auth/RequestAuthenticator.java @@ -15,13 +15,15 @@ package google.registry.request.auth; import static com.google.common.base.Preconditions.checkArgument; +import static google.registry.request.auth.AuthSettings.AuthLevel.APP; +import static google.registry.request.auth.AuthSettings.AuthLevel.NONE; +import static google.registry.request.auth.AuthSettings.AuthLevel.USER; +import static google.registry.request.auth.AuthSettings.UserPolicy.ADMIN; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; import com.google.common.flogger.FluentLogger; -import google.registry.request.auth.AuthSettings.AuthLevel; import google.registry.request.auth.AuthSettings.AuthMethod; -import google.registry.request.auth.AuthSettings.UserPolicy; import java.util.Optional; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; @@ -29,7 +31,6 @@ import javax.servlet.http.HttpServletRequest; /** Top-level authentication/authorization class; calls authentication mechanisms as needed. */ public class RequestAuthenticator { - private final AppEngineInternalAuthenticationMechanism appEngineInternalAuthenticationMechanism; private final ImmutableList apiAuthenticationMechanisms; private final LegacyAuthenticationMechanism legacyAuthenticationMechanism; @@ -37,10 +38,8 @@ public class RequestAuthenticator { @Inject public RequestAuthenticator( - AppEngineInternalAuthenticationMechanism appEngineInternalAuthenticationMechanism, ImmutableList apiAuthenticationMechanisms, LegacyAuthenticationMechanism legacyAuthenticationMechanism) { - this.appEngineInternalAuthenticationMechanism = appEngineInternalAuthenticationMechanism; this.apiAuthenticationMechanisms = apiAuthenticationMechanisms; this.legacyAuthenticationMechanism = legacyAuthenticationMechanism; } @@ -58,42 +57,19 @@ public class RequestAuthenticator { public Optional authorize(AuthSettings auth, HttpServletRequest req) { logger.atInfo().log("Action requires auth: %s", auth); AuthResult authResult = authenticate(auth, req); - switch (auth.minimumLevel()) { - case NONE: - // Any authentication result is ok. - break; - case APP: - if (!authResult.isAuthenticated()) { - logger.atWarning().log("Not authorized; no authentication found."); - return Optional.empty(); - } - break; - case USER: - if (authResult.authLevel() != AuthLevel.USER) { - logger.atWarning().log("Not authorized; no authenticated user."); - // TODO(mountford): change this so that the caller knows to return a more helpful error - return Optional.empty(); - } - break; + if (auth.minimumLevel() == APP && !authResult.isAuthenticated()) { + logger.atWarning().log("Not authorized; no authentication found."); + return Optional.empty(); + } else if (auth.minimumLevel() == USER && authResult.authLevel() != USER) { + logger.atWarning().log("Not authorized; no authenticated user."); + return Optional.empty(); } - switch (auth.userPolicy()) { - case IGNORED: - if (authResult.authLevel() == AuthLevel.USER) { - logger.atWarning().log("Not authorized; user policy is IGNORED, but a user was found."); - return Optional.empty(); - } - break; - case PUBLIC: - // Any user auth result is okay. - break; - case ADMIN: - if (authResult.userAuthInfo().isPresent() - && !authResult.userAuthInfo().get().isUserAdmin()) { - logger.atWarning().log( - "Not authorized; user policy is ADMIN, but the user was not an admin."); - return Optional.empty(); - } - break; + if (auth.userPolicy() == ADMIN + && authResult.userAuthInfo().isPresent() + && !authResult.userAuthInfo().get().isUserAdmin()) { + logger.atWarning().log( + "Not authorized; user policy is ADMIN, but the user was not an admin."); + return Optional.empty(); } return Optional.of(authResult); } @@ -110,18 +86,8 @@ public class RequestAuthenticator { for (AuthMethod authMethod : auth.methods()) { AuthResult authResult; switch (authMethod) { - // App Engine internal authentication, using the queue name header - case INTERNAL: - // checkAuthConfig will have insured that the user policy is not USER. - authResult = appEngineInternalAuthenticationMechanism.authenticate(req); - if (authResult.isAuthenticated()) { - logger.atInfo().log("Authenticated via internal auth: %s", authResult); - return authResult; - } - break; - // API-based user authentication mechanisms, such as OAuth + // API-based user authentication mechanisms, such as OAuth and OIDC. case API: - // checkAuthConfig will have insured that the user policy is not IGNORED. for (AuthenticationMechanism authMechanism : apiAuthenticationMechanisms) { authResult = authMechanism.authenticate(req); if (authResult.isAuthenticated()) { @@ -133,7 +99,6 @@ public class RequestAuthenticator { break; // Legacy authentication via UserService case LEGACY: - // checkAuthConfig will have insured that the user policy is not IGNORED. authResult = legacyAuthenticationMechanism.authenticate(req); if (authResult.isAuthenticated()) { logger.atInfo().log("Authenticated via legacy auth: %s", authResult); @@ -151,15 +116,10 @@ public class RequestAuthenticator { ImmutableList authMethods = ImmutableList.copyOf(auth.methods()); checkArgument(!authMethods.isEmpty(), "Must specify at least one auth method"); checkArgument( - Ordering.explicit(AuthMethod.INTERNAL, AuthMethod.API, AuthMethod.LEGACY) - .isStrictlyOrdered(authMethods), - "Auth methods must be unique and strictly in order - INTERNAL, API, LEGACY"); + Ordering.explicit(AuthMethod.API, AuthMethod.LEGACY).isStrictlyOrdered(authMethods), + "Auth methods must be unique and strictly in order - API, LEGACY"); checkArgument( - !(authMethods.contains(AuthMethod.INTERNAL) && auth.minimumLevel().equals(AuthLevel.USER)), - "Actions with INTERNAL auth method may not require USER auth level"); - checkArgument( - !(auth.userPolicy().equals(UserPolicy.IGNORED) - && !authMethods.equals(ImmutableList.of(AuthMethod.INTERNAL))), - "Actions with auth methods beyond INTERNAL must not specify the IGNORED user policy"); + (auth.minimumLevel() != NONE) || (auth.userPolicy() != ADMIN), + "Actions with minimal auth level at NONE should not specify ADMIN user policy"); } } diff --git a/core/src/main/java/google/registry/tmch/NordnUploadAction.java b/core/src/main/java/google/registry/tmch/NordnUploadAction.java index 31962b1de..cde875796 100644 --- a/core/src/main/java/google/registry/tmch/NordnUploadAction.java +++ b/core/src/main/java/google/registry/tmch/NordnUploadAction.java @@ -69,7 +69,7 @@ import org.joda.time.Duration; path = NordnUploadAction.PATH, method = Action.Method.POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class NordnUploadAction implements Runnable { static final String PATH = "/_dr/task/nordnUpload"; diff --git a/core/src/main/java/google/registry/tmch/NordnVerifyAction.java b/core/src/main/java/google/registry/tmch/NordnVerifyAction.java index 5257637ac..294bdf053 100644 --- a/core/src/main/java/google/registry/tmch/NordnVerifyAction.java +++ b/core/src/main/java/google/registry/tmch/NordnVerifyAction.java @@ -54,7 +54,7 @@ import javax.inject.Inject; path = NordnVerifyAction.PATH, method = Action.Method.POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class NordnVerifyAction implements Runnable { static final String PATH = "/_dr/task/nordnVerify"; diff --git a/core/src/main/java/google/registry/tmch/TmchCrlAction.java b/core/src/main/java/google/registry/tmch/TmchCrlAction.java index dcddba1d1..666a97d45 100644 --- a/core/src/main/java/google/registry/tmch/TmchCrlAction.java +++ b/core/src/main/java/google/registry/tmch/TmchCrlAction.java @@ -32,7 +32,7 @@ import javax.inject.Inject; path = "/_dr/task/tmchCrl", method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class TmchCrlAction implements Runnable { @Inject Marksdb marksdb; diff --git a/core/src/main/java/google/registry/tmch/TmchDnlAction.java b/core/src/main/java/google/registry/tmch/TmchDnlAction.java index 1dd325318..ae0353008 100644 --- a/core/src/main/java/google/registry/tmch/TmchDnlAction.java +++ b/core/src/main/java/google/registry/tmch/TmchDnlAction.java @@ -35,7 +35,7 @@ import org.bouncycastle.openpgp.PGPException; path = "/_dr/task/tmchDnl", method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class TmchDnlAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tmch/TmchSmdrlAction.java b/core/src/main/java/google/registry/tmch/TmchSmdrlAction.java index ece110366..7644e3736 100644 --- a/core/src/main/java/google/registry/tmch/TmchSmdrlAction.java +++ b/core/src/main/java/google/registry/tmch/TmchSmdrlAction.java @@ -34,7 +34,7 @@ import org.bouncycastle.openpgp.PGPException; path = "/_dr/task/tmchSmdrl", method = POST, automaticallyPrintOk = true, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class TmchSmdrlAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tools/server/CreateGroupsAction.java b/core/src/main/java/google/registry/tools/server/CreateGroupsAction.java index 70a953dfd..49f83dc89 100644 --- a/core/src/main/java/google/registry/tools/server/CreateGroupsAction.java +++ b/core/src/main/java/google/registry/tools/server/CreateGroupsAction.java @@ -43,7 +43,7 @@ import javax.inject.Inject; service = Action.Service.TOOLS, path = CreateGroupsAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class CreateGroupsAction implements Runnable { public static final String PATH = "/_dr/admin/createGroups"; diff --git a/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java b/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java index d8d5bef48..071ce620b 100644 --- a/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java +++ b/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java @@ -65,7 +65,7 @@ import org.joda.time.Duration; service = Action.Service.TOOLS, path = GenerateZoneFilesAction.PATH, method = POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonAction { private static final FluentLogger log = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tools/server/ListDomainsAction.java b/core/src/main/java/google/registry/tools/server/ListDomainsAction.java index a74eaba67..51994b8bf 100644 --- a/core/src/main/java/google/registry/tools/server/ListDomainsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListDomainsAction.java @@ -39,7 +39,7 @@ import javax.inject.Inject; service = Action.Service.TOOLS, path = ListDomainsAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ListDomainsAction extends ListObjectsAction { /** An App Engine limitation on how many subqueries can be used in a single query. */ diff --git a/core/src/main/java/google/registry/tools/server/ListHostsAction.java b/core/src/main/java/google/registry/tools/server/ListHostsAction.java index d0e2bb524..64d046672 100644 --- a/core/src/main/java/google/registry/tools/server/ListHostsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListHostsAction.java @@ -34,7 +34,7 @@ import org.joda.time.DateTime; service = Action.Service.TOOLS, path = ListHostsAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ListHostsAction extends ListObjectsAction { public static final String PATH = "/_dr/admin/list/hosts"; diff --git a/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java b/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java index 74bd6633f..f2fa31c2c 100644 --- a/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListPremiumListsAction.java @@ -35,7 +35,7 @@ import javax.inject.Inject; service = Action.Service.TOOLS, path = ListPremiumListsAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ListPremiumListsAction extends ListObjectsAction { public static final String PATH = "/_dr/admin/list/premiumLists"; diff --git a/core/src/main/java/google/registry/tools/server/ListRegistrarsAction.java b/core/src/main/java/google/registry/tools/server/ListRegistrarsAction.java index d8e9fe475..ca43d6685 100644 --- a/core/src/main/java/google/registry/tools/server/ListRegistrarsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListRegistrarsAction.java @@ -30,7 +30,7 @@ import javax.inject.Inject; service = Action.Service.TOOLS, path = ListRegistrarsAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ListRegistrarsAction extends ListObjectsAction { public static final String PATH = "/_dr/admin/list/registrars"; diff --git a/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java b/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java index 6e99d2330..0c6846e7a 100644 --- a/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListReservedListsAction.java @@ -33,7 +33,7 @@ import javax.inject.Inject; service = Action.Service.TOOLS, path = ListReservedListsAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ListReservedListsAction extends ListObjectsAction { public static final String PATH = "/_dr/admin/list/reservedLists"; diff --git a/core/src/main/java/google/registry/tools/server/ListTldsAction.java b/core/src/main/java/google/registry/tools/server/ListTldsAction.java index 2dfb29f80..ce8d5fe78 100644 --- a/core/src/main/java/google/registry/tools/server/ListTldsAction.java +++ b/core/src/main/java/google/registry/tools/server/ListTldsAction.java @@ -34,7 +34,7 @@ import org.joda.time.DateTime; service = Action.Service.TOOLS, path = ListTldsAction.PATH, method = {GET, POST}, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public final class ListTldsAction extends ListObjectsAction { public static final String PATH = "/_dr/admin/list/tlds"; diff --git a/core/src/main/java/google/registry/tools/server/RefreshDnsForAllDomainsAction.java b/core/src/main/java/google/registry/tools/server/RefreshDnsForAllDomainsAction.java index d3275b6a0..2002a299d 100644 --- a/core/src/main/java/google/registry/tools/server/RefreshDnsForAllDomainsAction.java +++ b/core/src/main/java/google/registry/tools/server/RefreshDnsForAllDomainsAction.java @@ -46,17 +46,13 @@ import org.joda.time.Duration; * are responsible for enqueuing refresh tasks for subordinate hosts. So this action thus refreshes * DNS for everything applicable under all TLDs under management. * - *

Because there are no auth settings in the {@link Action} annotation, this command can only be - * run internally, or by pretending to be internal by setting the X-AppEngine-QueueName header, - * which only admin users can do. - * *

You may pass in a {@code batchSize} for the batched read of domains from the database. This is * recommended to be somewhere between 200 and 500. The default value is 250. */ @Action( service = Action.Service.TOOLS, path = "/_dr/task/refreshDnsForAllDomains", - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class RefreshDnsForAllDomainsAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/tools/server/VerifyOteAction.java b/core/src/main/java/google/registry/tools/server/VerifyOteAction.java index 8583c8ddc..6aafde4de 100644 --- a/core/src/main/java/google/registry/tools/server/VerifyOteAction.java +++ b/core/src/main/java/google/registry/tools/server/VerifyOteAction.java @@ -37,7 +37,7 @@ import javax.inject.Inject; service = Action.Service.TOOLS, path = VerifyOteAction.PATH, method = Action.Method.POST, - auth = Auth.AUTH_INTERNAL_OR_ADMIN) + auth = Auth.AUTH_API_ADMIN) public class VerifyOteAction implements Runnable, JsonAction { public static final String PATH = "/_dr/admin/verifyOte"; diff --git a/core/src/main/java/google/registry/ui/server/registrar/ConsoleUiAction.java b/core/src/main/java/google/registry/ui/server/registrar/ConsoleUiAction.java index 859271609..b9a244266 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/ConsoleUiAction.java +++ b/core/src/main/java/google/registry/ui/server/registrar/ConsoleUiAction.java @@ -124,7 +124,7 @@ public final class ConsoleUiAction extends HtmlAction { // requireFeeExtension) - to make sure the user indeed has access to the guessed registrar. // // Note that not doing so (and just passing the "clientId" as given) isn't a security issue - // since we double check the access to the registrar on any read / update request. We have to + // since we double-check the access to the registrar on any read / update request. We have to // - since the access might get revoked between the initial page load and the request! (also // because the requests come from the browser, and can easily be faked) registrarAccessor.getRegistrar(clientId); diff --git a/core/src/main/java/google/registry/ui/server/registrar/HtmlAction.java b/core/src/main/java/google/registry/ui/server/registrar/HtmlAction.java index e878be9ef..ca32133d2 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/HtmlAction.java +++ b/core/src/main/java/google/registry/ui/server/registrar/HtmlAction.java @@ -37,7 +37,7 @@ import javax.servlet.http.HttpServletRequest; * Handles some of the nitty-gritty of responding to requests that should return HTML, including * login, redirects, analytics, and some headers. * - * If the user is not logged in, this will redirect to the login URL. + *

If the user is not logged in, this will redirect to the login URL. */ public abstract class HtmlAction implements Runnable { diff --git a/core/src/main/java/google/registry/ui/server/registrar/RegistryLockVerifyAction.java b/core/src/main/java/google/registry/ui/server/registrar/RegistryLockVerifyAction.java index c0e31ae57..00216a1a2 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/RegistryLockVerifyAction.java +++ b/core/src/main/java/google/registry/ui/server/registrar/RegistryLockVerifyAction.java @@ -34,7 +34,7 @@ import javax.inject.Inject; @Action( service = Action.Service.DEFAULT, path = RegistryLockVerifyAction.PATH, - auth = Auth.AUTH_PUBLIC_LOGGED_IN) + auth = Auth.AUTH_PUBLIC) public final class RegistryLockVerifyAction extends HtmlAction { public static final String PATH = "/registry-lock-verify"; diff --git a/core/src/main/java/google/registry/whois/WhoisAction.java b/core/src/main/java/google/registry/whois/WhoisAction.java index 4e66c84a2..81f6d28df 100644 --- a/core/src/main/java/google/registry/whois/WhoisAction.java +++ b/core/src/main/java/google/registry/whois/WhoisAction.java @@ -51,7 +51,7 @@ import org.joda.time.DateTime; service = Action.Service.PUBAPI, path = "/_dr/whois", method = POST, - auth = Auth.AUTH_PUBLIC_OR_INTERNAL) + auth = Auth.AUTH_API_PUBLIC) public class WhoisAction implements Runnable { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); diff --git a/core/src/main/java/google/registry/whois/WhoisHttpAction.java b/core/src/main/java/google/registry/whois/WhoisHttpAction.java index 4dfbbc825..fc2c6c3f0 100644 --- a/core/src/main/java/google/registry/whois/WhoisHttpAction.java +++ b/core/src/main/java/google/registry/whois/WhoisHttpAction.java @@ -97,7 +97,7 @@ import org.joda.time.Duration; service = Action.Service.PUBAPI, path = WhoisHttpAction.PATH, isPrefix = true, - auth = Auth.AUTH_PUBLIC_ANONYMOUS) + auth = Auth.AUTH_PUBLIC) public final class WhoisHttpAction implements Runnable { public static final String PATH = "/whois/"; diff --git a/core/src/test/java/google/registry/rdap/RdapActionBaseTest.java b/core/src/test/java/google/registry/rdap/RdapActionBaseTest.java index 171f63f7f..47c2dcb20 100644 --- a/core/src/test/java/google/registry/rdap/RdapActionBaseTest.java +++ b/core/src/test/java/google/registry/rdap/RdapActionBaseTest.java @@ -47,7 +47,7 @@ class RdapActionBaseTest extends RdapActionBaseTestCase runTest(UserService userService, AuthSettings auth) { - return createRequestAuthenticator(userService) - .authorize(auth, req); + return createRequestAuthenticator(userService).authorize(auth, req); } @Test @@ -134,48 +120,6 @@ class RequestAuthenticatorTest { assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.NONE); } - @Test - void testNoAuthNeeded_internalFound() { - when(req.getHeader("X-AppEngine-QueueName")).thenReturn("__cron"); - - Optional authResult = runTest(mockUserService, AUTH_NONE); - - verifyNoInteractions(mockUserService); - assertThat(authResult).isPresent(); - assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.APP); - assertThat(authResult.get().userAuthInfo()).isEmpty(); - } - - @Test - void testInternalAuth_notInvokedInternally() { - Optional authResult = runTest(mockUserService, AUTH_INTERNAL_OR_ADMIN); - - verifyNoInteractions(mockUserService); - assertThat(authResult).isEmpty(); - } - - @Test - void testInternalAuth_success() { - when(req.getHeader("X-AppEngine-QueueName")).thenReturn("__cron"); - - Optional authResult = runTest(mockUserService, AUTH_INTERNAL_OR_ADMIN); - - verifyNoInteractions(mockUserService); - assertThat(authResult).isPresent(); - assertThat(authResult.get().authLevel()).isEqualTo(AuthLevel.APP); - assertThat(authResult.get().userAuthInfo()).isEmpty(); - } - - @Test - void testInternalAuth_failForAdminUser() { - when(req.getHeader("X-AppEngine-QueueName")).thenReturn("__cron"); - fakeUserService.setUser(testUser, true /* isAdmin */); - - Optional authResult = runTest(fakeUserService, AUTH_INTERNAL_OR_ADMIN); - - assertThat(authResult).isEmpty(); - } - @Test void testAnyUserAnyMethod_notLoggedIn() { Optional authResult = runTest(fakeUserService, AUTH_ANY_USER_ANY_METHOD); @@ -280,9 +224,9 @@ class RequestAuthenticatorTest { assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes()) .containsAtLeast("test-scope1", "test-scope2"); assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().oauthClientId()) - .isEqualTo("test-client-id"); + .isEqualTo("test-client-id"); assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().rawAccessToken()) - .isEqualTo("TOKEN"); + .isEqualTo("TOKEN"); } @Test @@ -303,9 +247,9 @@ class RequestAuthenticatorTest { assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes()) .containsAtLeast("test-scope1", "test-scope2"); assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().oauthClientId()) - .isEqualTo("test-client-id"); + .isEqualTo("test-client-id"); assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().rawAccessToken()) - .isEqualTo("TOKEN"); + .isEqualTo("TOKEN"); } @Test @@ -372,9 +316,9 @@ class RequestAuthenticatorTest { assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().authorizedScopes()) .containsAtLeast("test-scope1", "test-scope2", "test-scope3"); assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().oauthClientId()) - .isEqualTo("test-client-id"); + .isEqualTo("test-client-id"); assertThat(authResult.get().userAuthInfo().get().oauthTokenInfo().get().rawAccessToken()) - .isEqualTo("TOKEN"); + .isEqualTo("TOKEN"); } @Test @@ -387,7 +331,7 @@ class RequestAuthenticatorTest { } @Test - void testCheckAuthConfig_NoMethods_failure() { + void testCheckAuthConfig_noMethods_failure() { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, @@ -396,14 +340,25 @@ class RequestAuthenticatorTest { } @Test - void testCheckAuthConfig_WrongMethodOrdering_failure() { + void testCheckAuthConfig_wrongMethodOrdering_failure() { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, () -> RequestAuthenticator.checkAuthConfig(AUTH_WRONG_METHOD_ORDERING)); assertThat(thrown) .hasMessageThat() - .contains("Auth methods must be unique and strictly in order - INTERNAL, API, LEGACY"); + .contains("Auth methods must be unique and strictly in order - API, LEGACY"); + } + + @Test + void testCheckAuthConfig_noneAuthLevelRequiresAdmin_failure() { + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> RequestAuthenticator.checkAuthConfig(AUTH_NONE_REQUIRES_ADMIN)); + assertThat(thrown) + .hasMessageThat() + .contains("Actions with minimal auth level at NONE should not specify ADMIN user policy"); } @Test @@ -414,29 +369,6 @@ class RequestAuthenticatorTest { () -> RequestAuthenticator.checkAuthConfig(AUTH_DUPLICATE_METHODS)); assertThat(thrown) .hasMessageThat() - .contains("Auth methods must be unique and strictly in order - INTERNAL, API, LEGACY"); - } - - @Test - void testCheckAuthConfig_InternalWithUser_failure() { - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> RequestAuthenticator.checkAuthConfig(AUTH_INTERNAL_WITH_USER)); - assertThat(thrown) - .hasMessageThat() - .contains("Actions with INTERNAL auth method may not require USER auth level"); - } - - @Test - void testCheckAuthConfig_WronglyIgnoringUser_failure() { - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> RequestAuthenticator.checkAuthConfig(AUTH_WRONGLY_IGNORING_USER)); - assertThat(thrown) - .hasMessageThat() - .contains( - "Actions with auth methods beyond INTERNAL must not specify the IGNORED user policy"); + .contains("Auth methods must be unique and strictly in order - API, LEGACY"); } } diff --git a/core/src/test/resources/google/registry/module/backend/backend_routing.txt b/core/src/test/resources/google/registry/module/backend/backend_routing.txt index 49fc24c1f..de7797ae0 100644 --- a/core/src/test/resources/google/registry/module/backend/backend_routing.txt +++ b/core/src/test/resources/google/registry/module/backend/backend_routing.txt @@ -1,39 +1,39 @@ PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY -/_dr/cron/fanout TldFanoutAction GET y INTERNAL,API APP ADMIN -/_dr/dnsRefresh RefreshDnsAction GET y INTERNAL,API APP ADMIN -/_dr/task/brdaCopy BrdaCopyAction POST y INTERNAL,API APP ADMIN -/_dr/task/copyDetailReports CopyDetailReportsAction POST n INTERNAL,API APP ADMIN -/_dr/task/deleteExpiredDomains DeleteExpiredDomainsAction GET n INTERNAL,API APP ADMIN -/_dr/task/deleteLoadTestData DeleteLoadTestDataAction POST n INTERNAL,API APP ADMIN -/_dr/task/deleteProberData DeleteProberDataAction POST n INTERNAL,API APP ADMIN -/_dr/task/executeCannedScript CannedScriptExecutionAction POST y INTERNAL,API APP ADMIN -/_dr/task/expandBillingRecurrences ExpandBillingRecurrencesAction GET n INTERNAL,API APP ADMIN -/_dr/task/exportDomainLists ExportDomainListsAction POST n INTERNAL,API APP ADMIN -/_dr/task/exportPremiumTerms ExportPremiumTermsAction POST n INTERNAL,API APP ADMIN -/_dr/task/exportReservedTerms ExportReservedTermsAction POST n INTERNAL,API APP ADMIN -/_dr/task/generateInvoices GenerateInvoicesAction POST n INTERNAL,API APP ADMIN -/_dr/task/generateSpec11 GenerateSpec11ReportAction POST n INTERNAL,API APP ADMIN -/_dr/task/icannReportingStaging IcannReportingStagingAction POST n INTERNAL,API APP ADMIN -/_dr/task/icannReportingUpload IcannReportingUploadAction POST n INTERNAL,API APP ADMIN -/_dr/task/nordnUpload NordnUploadAction POST y INTERNAL,API APP ADMIN -/_dr/task/nordnVerify NordnVerifyAction POST y INTERNAL,API APP ADMIN -/_dr/task/publishDnsUpdates PublishDnsUpdatesAction POST y INTERNAL,API APP ADMIN -/_dr/task/publishInvoices PublishInvoicesAction POST n INTERNAL,API APP ADMIN -/_dr/task/publishSpec11 PublishSpec11ReportAction POST n INTERNAL,API APP ADMIN -/_dr/task/rdeReport RdeReportAction POST n INTERNAL,API APP ADMIN -/_dr/task/rdeStaging RdeStagingAction GET,POST n INTERNAL,API APP ADMIN -/_dr/task/rdeUpload RdeUploadAction POST n INTERNAL,API APP ADMIN -/_dr/task/readDnsRefreshRequests ReadDnsRefreshRequestsAction POST y INTERNAL,API APP ADMIN -/_dr/task/refreshDnsOnHostRename RefreshDnsOnHostRenameAction POST n INTERNAL,API APP ADMIN -/_dr/task/relockDomain RelockDomainAction POST y INTERNAL,API APP ADMIN -/_dr/task/resaveAllEppResourcesPipeline ResaveAllEppResourcesPipelineAction GET n INTERNAL,API APP ADMIN -/_dr/task/resaveEntity ResaveEntityAction POST n INTERNAL,API APP ADMIN -/_dr/task/sendExpiringCertificateNotificationEmail SendExpiringCertificateNotificationEmailAction GET n INTERNAL,API APP ADMIN -/_dr/task/syncGroupMembers SyncGroupMembersAction POST n INTERNAL,API APP ADMIN -/_dr/task/syncRegistrarsSheet SyncRegistrarsSheetAction POST n INTERNAL,API APP ADMIN -/_dr/task/tmchCrl TmchCrlAction POST y INTERNAL,API APP ADMIN -/_dr/task/tmchDnl TmchDnlAction POST y INTERNAL,API APP ADMIN -/_dr/task/tmchSmdrl TmchSmdrlAction POST y INTERNAL,API APP ADMIN -/_dr/task/updateRegistrarRdapBaseUrls UpdateRegistrarRdapBaseUrlsAction GET y INTERNAL,API APP ADMIN -/_dr/task/wipeOutCloudSql WipeOutCloudSqlAction GET n INTERNAL,API APP ADMIN -/_dr/task/wipeOutContactHistoryPii WipeOutContactHistoryPiiAction GET n INTERNAL,API APP ADMIN +/_dr/cron/fanout TldFanoutAction GET y API APP ADMIN +/_dr/dnsRefresh RefreshDnsAction GET y API APP ADMIN +/_dr/task/brdaCopy BrdaCopyAction POST y API APP ADMIN +/_dr/task/copyDetailReports CopyDetailReportsAction POST n API APP ADMIN +/_dr/task/deleteExpiredDomains DeleteExpiredDomainsAction GET n API APP ADMIN +/_dr/task/deleteLoadTestData DeleteLoadTestDataAction POST n API APP ADMIN +/_dr/task/deleteProberData DeleteProberDataAction POST n API APP ADMIN +/_dr/task/executeCannedScript CannedScriptExecutionAction POST y API APP ADMIN +/_dr/task/expandBillingRecurrences ExpandBillingRecurrencesAction GET n API APP ADMIN +/_dr/task/exportDomainLists ExportDomainListsAction POST n API APP ADMIN +/_dr/task/exportPremiumTerms ExportPremiumTermsAction POST n API APP ADMIN +/_dr/task/exportReservedTerms ExportReservedTermsAction POST n API APP ADMIN +/_dr/task/generateInvoices GenerateInvoicesAction POST n API APP ADMIN +/_dr/task/generateSpec11 GenerateSpec11ReportAction POST n API APP ADMIN +/_dr/task/icannReportingStaging IcannReportingStagingAction POST n API APP ADMIN +/_dr/task/icannReportingUpload IcannReportingUploadAction POST n API APP ADMIN +/_dr/task/nordnUpload NordnUploadAction POST y API APP ADMIN +/_dr/task/nordnVerify NordnVerifyAction POST y API APP ADMIN +/_dr/task/publishDnsUpdates PublishDnsUpdatesAction POST y API APP ADMIN +/_dr/task/publishInvoices PublishInvoicesAction POST n API APP ADMIN +/_dr/task/publishSpec11 PublishSpec11ReportAction POST n API APP ADMIN +/_dr/task/rdeReport RdeReportAction POST n API APP ADMIN +/_dr/task/rdeStaging RdeStagingAction GET,POST n API APP ADMIN +/_dr/task/rdeUpload RdeUploadAction POST n API APP ADMIN +/_dr/task/readDnsRefreshRequests ReadDnsRefreshRequestsAction POST y API APP ADMIN +/_dr/task/refreshDnsOnHostRename RefreshDnsOnHostRenameAction POST n API APP ADMIN +/_dr/task/relockDomain RelockDomainAction POST y API APP ADMIN +/_dr/task/resaveAllEppResourcesPipeline ResaveAllEppResourcesPipelineAction GET n API APP ADMIN +/_dr/task/resaveEntity ResaveEntityAction POST n API APP ADMIN +/_dr/task/sendExpiringCertificateNotificationEmail SendExpiringCertificateNotificationEmailAction GET n API APP ADMIN +/_dr/task/syncGroupMembers SyncGroupMembersAction POST n API APP ADMIN +/_dr/task/syncRegistrarsSheet SyncRegistrarsSheetAction POST n API APP ADMIN +/_dr/task/tmchCrl TmchCrlAction POST y API APP ADMIN +/_dr/task/tmchDnl TmchDnlAction POST y API APP ADMIN +/_dr/task/tmchSmdrl TmchSmdrlAction POST y API APP ADMIN +/_dr/task/updateRegistrarRdapBaseUrls UpdateRegistrarRdapBaseUrlsAction GET y API APP ADMIN +/_dr/task/wipeOutCloudSql WipeOutCloudSqlAction GET n API APP ADMIN +/_dr/task/wipeOutContactHistoryPii WipeOutContactHistoryPiiAction GET n API APP ADMIN diff --git a/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt b/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt index 2dd94f983..863b2e757 100644 --- a/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt +++ b/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt @@ -1,13 +1,13 @@ -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 -/registrar-ote-setup ConsoleOteSetupAction POST,GET n INTERNAL,API,LEGACY NONE PUBLIC -/registrar-ote-status OteStatusAction POST n API,LEGACY USER PUBLIC -/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC -/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC -/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC -/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY USER PUBLIC +PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY +/_dr/epp EppTlsAction POST n 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 API,LEGACY NONE PUBLIC +/registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC +/registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC +/registrar-ote-status OteStatusAction POST n API,LEGACY USER PUBLIC +/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC +/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC +/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC +/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY NONE PUBLIC diff --git a/core/src/test/resources/google/registry/module/pubapi/pubapi_routing.txt b/core/src/test/resources/google/registry/module/pubapi/pubapi_routing.txt index 089d67c16..10d924c9e 100644 --- a/core/src/test/resources/google/registry/module/pubapi/pubapi_routing.txt +++ b/core/src/test/resources/google/registry/module/pubapi/pubapi_routing.txt @@ -1,13 +1,13 @@ -PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY -/_dr/whois WhoisAction POST n INTERNAL,API APP PUBLIC -/check CheckApiAction GET n INTERNAL NONE PUBLIC -/rdap/autnum/(*) RdapAutnumAction GET,HEAD n INTERNAL NONE PUBLIC -/rdap/domain/(*) RdapDomainAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC -/rdap/domains RdapDomainSearchAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC -/rdap/entities RdapEntitySearchAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC -/rdap/entity/(*) RdapEntityAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC -/rdap/help(*) RdapHelpAction GET,HEAD n INTERNAL NONE PUBLIC -/rdap/ip/(*) RdapIpAction GET,HEAD n INTERNAL NONE PUBLIC -/rdap/nameserver/(*) RdapNameserverAction GET,HEAD n INTERNAL NONE PUBLIC -/rdap/nameservers RdapNameserverSearchAction GET,HEAD n INTERNAL NONE PUBLIC -/whois/(*) WhoisHttpAction GET n INTERNAL NONE PUBLIC +PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY +/_dr/whois WhoisAction POST n API APP PUBLIC +/check CheckApiAction GET n API,LEGACY NONE PUBLIC +/rdap/autnum/(*) RdapAutnumAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/domain/(*) RdapDomainAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/domains RdapDomainSearchAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/entities RdapEntitySearchAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/entity/(*) RdapEntityAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/help(*) RdapHelpAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/ip/(*) RdapIpAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/nameserver/(*) RdapNameserverAction GET,HEAD n API,LEGACY NONE PUBLIC +/rdap/nameservers RdapNameserverSearchAction GET,HEAD n API,LEGACY NONE PUBLIC +/whois/(*) WhoisHttpAction GET n API,LEGACY NONE PUBLIC diff --git a/core/src/test/resources/google/registry/module/tools/tools_routing.txt b/core/src/test/resources/google/registry/module/tools/tools_routing.txt index 1fa3170fb..161524c60 100644 --- a/core/src/test/resources/google/registry/module/tools/tools_routing.txt +++ b/core/src/test/resources/google/registry/module/tools/tools_routing.txt @@ -1,13 +1,13 @@ PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY -/_dr/admin/createGroups CreateGroupsAction POST n INTERNAL,API APP ADMIN -/_dr/admin/list/domains ListDomainsAction GET,POST n INTERNAL,API APP ADMIN -/_dr/admin/list/hosts ListHostsAction GET,POST n INTERNAL,API APP ADMIN -/_dr/admin/list/premiumLists ListPremiumListsAction GET,POST n INTERNAL,API APP ADMIN -/_dr/admin/list/registrars ListRegistrarsAction GET,POST n INTERNAL,API APP ADMIN -/_dr/admin/list/reservedLists ListReservedListsAction GET,POST n INTERNAL,API APP ADMIN -/_dr/admin/list/tlds ListTldsAction GET,POST n INTERNAL,API APP ADMIN -/_dr/admin/verifyOte VerifyOteAction POST n INTERNAL,API APP ADMIN -/_dr/epptool EppToolAction POST n INTERNAL,API APP ADMIN -/_dr/loadtest LoadTestAction POST y INTERNAL,API APP ADMIN -/_dr/task/generateZoneFiles GenerateZoneFilesAction POST n INTERNAL,API APP ADMIN -/_dr/task/refreshDnsForAllDomains RefreshDnsForAllDomainsAction GET n INTERNAL,API APP ADMIN +/_dr/admin/createGroups CreateGroupsAction POST n API APP ADMIN +/_dr/admin/list/domains ListDomainsAction GET,POST n API APP ADMIN +/_dr/admin/list/hosts ListHostsAction GET,POST n API APP ADMIN +/_dr/admin/list/premiumLists ListPremiumListsAction GET,POST n API APP ADMIN +/_dr/admin/list/registrars ListRegistrarsAction GET,POST n API APP ADMIN +/_dr/admin/list/reservedLists ListReservedListsAction GET,POST n API APP ADMIN +/_dr/admin/list/tlds ListTldsAction GET,POST n API APP ADMIN +/_dr/admin/verifyOte VerifyOteAction POST n API APP ADMIN +/_dr/epptool EppToolAction POST n API APP ADMIN +/_dr/loadtest LoadTestAction POST y API APP ADMIN +/_dr/task/generateZoneFiles GenerateZoneFilesAction POST n API APP ADMIN +/_dr/task/refreshDnsForAllDomains RefreshDnsForAllDomainsAction GET n API APP ADMIN