diff --git a/src/main/java/com/google/firebase/auth/AbstractFirebaseAuth.java b/src/main/java/com/google/firebase/auth/AbstractFirebaseAuth.java index 97d8ec340..c4ee36434 100644 --- a/src/main/java/com/google/firebase/auth/AbstractFirebaseAuth.java +++ b/src/main/java/com/google/firebase/auth/AbstractFirebaseAuth.java @@ -1242,6 +1242,49 @@ protected SamlProviderConfig execute() throws FirebaseAuthException { }; } + /** + * Gets the SAML provider Auth config corresponding to the specified provider ID. + * + * @param providerId A provider ID string. + * @return An {@link OidcProviderConfig} instance. + * @throws IllegalArgumentException If the provider ID string is null or empty, or is not prefixed + * with 'saml'. + * @throws FirebaseAuthException If an error occurs while retrieving the provider config. + */ + public SamlProviderConfig getSamlProviderConfig(@NonNull String providerId) + throws FirebaseAuthException { + return getSamlProviderConfigOp(providerId).call(); + } + + /** + * Similar to {@link #getSamlProviderConfig(String)} but performs the operation asynchronously. + * Page size will be limited to 100 provider configs. + * + * @param providerId A provider ID string. + * @return An {@code ApiFuture} which will complete successfully with an + * {@link SamlProviderConfig} instance. If an error occurs while retrieving the provider + * config or if the specified provider ID does not exist, the future throws a + * {@link FirebaseAuthException}. + * @throws IllegalArgumentException If the provider ID string is null or empty, or is not prefixed + * with 'saml'. + */ + public ApiFuture getSamlProviderConfigAsync(@NonNull String providerId) { + return getSamlProviderConfigOp(providerId).callAsync(firebaseApp); + } + + private CallableOperation + getSamlProviderConfigOp(final String providerId) { + checkNotDestroyed(); + SamlProviderConfig.checkSamlProviderId(providerId); + final FirebaseUserManager userManager = getUserManager(); + return new CallableOperation() { + @Override + protected SamlProviderConfig execute() throws FirebaseAuthException { + return userManager.getSamlProviderConfig(providerId); + } + }; + } + /** * Deletes the SAML Auth provider config identified by the specified provider ID. * diff --git a/src/main/java/com/google/firebase/auth/FirebaseUserManager.java b/src/main/java/com/google/firebase/auth/FirebaseUserManager.java index 9bdc59cb5..1d57c4156 100644 --- a/src/main/java/com/google/firebase/auth/FirebaseUserManager.java +++ b/src/main/java/com/google/firebase/auth/FirebaseUserManager.java @@ -349,6 +349,11 @@ OidcProviderConfig getOidcProviderConfig(String providerId) throws FirebaseAuthE return sendRequest("GET", url, null, OidcProviderConfig.class); } + SamlProviderConfig getSamlProviderConfig(String providerId) throws FirebaseAuthException { + GenericUrl url = new GenericUrl(idpConfigMgtBaseUrl + getSamlUrlSuffix(providerId)); + return sendRequest("GET", url, null, SamlProviderConfig.class); + } + ListOidcProviderConfigsResponse listOidcProviderConfigs(int maxResults, String pageToken) throws FirebaseAuthException { ImmutableMap.Builder builder = diff --git a/src/test/java/com/google/firebase/auth/FirebaseAuthIT.java b/src/test/java/com/google/firebase/auth/FirebaseAuthIT.java index a6e4dd512..a34b7d48a 100644 --- a/src/test/java/com/google/firebase/auth/FirebaseAuthIT.java +++ b/src/test/java/com/google/firebase/auth/FirebaseAuthIT.java @@ -563,7 +563,7 @@ public void testGenerateSignInWithEmailLink() throws Exception { @Test public void testOidcProviderConfigLifecycle() throws Exception { - // Create config provider + // Create provider config String providerId = "oidc.provider-id"; OidcProviderConfig config = temporaryProviderConfig.createOidcProviderConfig( new OidcProviderConfig.CreateRequest() @@ -578,7 +578,7 @@ public void testOidcProviderConfigLifecycle() throws Exception { assertEquals("ClientId", config.getClientId()); assertEquals("https://oidc.com/issuer", config.getIssuer()); - // Get config provider + // Get provider config config = auth.getOidcProviderConfigAsync(providerId).get(); assertEquals(providerId, config.getProviderId()); assertEquals("DisplayName", config.getDisplayName()); @@ -586,7 +586,7 @@ public void testOidcProviderConfigLifecycle() throws Exception { assertEquals("ClientId", config.getClientId()); assertEquals("https://oidc.com/issuer", config.getIssuer()); - // Update config provider + // Update provider config OidcProviderConfig.UpdateRequest updateRequest = new OidcProviderConfig.UpdateRequest(providerId) .setDisplayName("NewDisplayName") @@ -600,7 +600,7 @@ public void testOidcProviderConfigLifecycle() throws Exception { assertEquals("NewClientId", config.getClientId()); assertEquals("https://oidc.com/new-issuer", config.getIssuer()); - // Delete config provider + // Delete provider config temporaryProviderConfig.deleteOidcProviderConfig(providerId); ProviderConfigTestUtils.assertOidcProviderConfigDoesNotExist(auth, providerId); } @@ -676,7 +676,7 @@ public void onSuccess(ListProviderConfigsPage result) { @Test public void testSamlProviderConfigLifecycle() throws Exception { - // Create config provider + // Create provider config String providerId = "saml.provider-id"; SamlProviderConfig config = temporaryProviderConfig.createSamlProviderConfig( new SamlProviderConfig.CreateRequest() @@ -698,14 +698,21 @@ public void testSamlProviderConfigLifecycle() throws Exception { assertEquals("RP_ENTITY_ID", config.getRpEntityId()); assertEquals("https://projectId.firebaseapp.com/__/auth/handler", config.getCallbackUrl()); - // TODO(micahstairs): Once implemented, add tests for getting and updating the SAML provider - // config. + config = auth.getSamlProviderConfig(providerId); + assertEquals(providerId, config.getProviderId()); + assertEquals("DisplayName", config.getDisplayName()); + assertTrue(config.isEnabled()); + assertEquals("IDP_ENTITY_ID", config.getIdpEntityId()); + assertEquals("https://example.com/login", config.getSsoUrl()); + assertEquals(ImmutableList.of("certificate1", "certificate2"), config.getX509Certificates()); + assertEquals("RP_ENTITY_ID", config.getRpEntityId()); + assertEquals("https://projectId.firebaseapp.com/__/auth/handler", config.getCallbackUrl()); - // Delete config provider - temporaryProviderConfig.deleteSamlProviderConfig(providerId); + // TODO(micahstairs): Once implemented, add tests for updating the SAML provider config. - // TODO(micahstairs): Once the operation to get a SAML config is implemented, add an assertion - // that the SAML provider does not exist. + // Delete provider config + temporaryProviderConfig.deleteSamlProviderConfig(providerId); + ProviderConfigTestUtils.assertSamlProviderConfigDoesNotExist(auth, providerId); } private Map parseLinkParameters(String link) throws Exception { diff --git a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java index 84307d309..3bbe66f43 100644 --- a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java +++ b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java @@ -1944,6 +1944,75 @@ public void testTenantAwareCreateSamlProvider() throws Exception { checkUrl(interceptor, "POST", TENANTS_BASE_URL + "/TENANT_ID/inboundSamlConfigs"); } + @Test + public void testGetSamlProviderConfig() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("saml.json")); + + SamlProviderConfig config = + FirebaseAuth.getInstance().getSamlProviderConfig("saml.provider-id"); + + checkSamlProviderConfig(config, "saml.provider-id"); + checkRequestHeaders(interceptor); + checkUrl(interceptor, "GET", PROJECT_BASE_URL + "/inboundSamlConfigs/saml.provider-id"); + } + + @Test + public void testGetSamlProviderConfigMissingId() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("saml.json")); + + try { + FirebaseAuth.getInstance().getSamlProviderConfig(null); + fail("No error thrown for missing provider ID."); + } catch (IllegalArgumentException e) { + // Expected. + } + } + + @Test + public void testGetSamlProviderConfigInvalidId() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("saml.json")); + + try { + FirebaseAuth.getInstance().getSamlProviderConfig("oidc.invalid-saml-provider-id"); + fail("No error thrown for invalid provider ID."); + } catch (IllegalArgumentException e) { + // Expected. + } + } + + @Test + public void testGetSamlProviderConfigWithNotFoundError() throws Exception { + TestResponseInterceptor interceptor = + initializeAppForUserManagementWithStatusCode(404, + "{\"error\": {\"message\": \"CONFIGURATION_NOT_FOUND\"}}"); + try { + FirebaseAuth.getInstance().getSamlProviderConfig("saml.provider-id"); + fail("No error thrown for invalid response"); + } catch (FirebaseAuthException e) { + assertEquals(FirebaseUserManager.CONFIGURATION_NOT_FOUND_ERROR, e.getErrorCode()); + } + checkUrl(interceptor, "GET", PROJECT_BASE_URL + "/inboundSamlConfigs/saml.provider-id"); + } + + @Test + public void testGetTenantAwareSamlProviderConfig() throws Exception { + TestResponseInterceptor interceptor = initializeAppForTenantAwareUserManagement( + "TENANT_ID", + TestUtils.loadResource("saml.json")); + TenantAwareFirebaseAuth tenantAwareAuth = + FirebaseAuth.getInstance().getTenantManager().getAuthForTenant("TENANT_ID"); + + SamlProviderConfig config = tenantAwareAuth.getSamlProviderConfig("saml.provider-id"); + + checkSamlProviderConfig(config, "saml.provider-id"); + checkRequestHeaders(interceptor); + String expectedUrl = TENANTS_BASE_URL + "/TENANT_ID/inboundSamlConfigs/saml.provider-id"; + checkUrl(interceptor, "GET", expectedUrl); + } + @Test public void testDeleteSamlProviderConfig() throws Exception { TestResponseInterceptor interceptor = initializeAppForUserManagement("{}"); diff --git a/src/test/java/com/google/firebase/auth/ProviderConfigTestUtils.java b/src/test/java/com/google/firebase/auth/ProviderConfigTestUtils.java index 52263335a..262c48f37 100644 --- a/src/test/java/com/google/firebase/auth/ProviderConfigTestUtils.java +++ b/src/test/java/com/google/firebase/auth/ProviderConfigTestUtils.java @@ -40,6 +40,18 @@ static void assertOidcProviderConfigDoesNotExist( } } + static void assertSamlProviderConfigDoesNotExist( + AbstractFirebaseAuth firebaseAuth, String providerId) throws Exception { + try { + firebaseAuth.getSamlProviderConfigAsync(providerId).get(); + fail("No error thrown for getting a deleted SAML provider config."); + } catch (ExecutionException e) { + assertTrue(e.getCause() instanceof FirebaseAuthException); + assertEquals(FirebaseUserManager.CONFIGURATION_NOT_FOUND_ERROR, + ((FirebaseAuthException) e.getCause()).getErrorCode()); + } + } + /** * Creates temporary provider configs for testing, and deletes them at the end of each test case. */ diff --git a/src/test/java/com/google/firebase/auth/TenantAwareFirebaseAuthIT.java b/src/test/java/com/google/firebase/auth/TenantAwareFirebaseAuthIT.java index 48a0c7d18..51b5d5461 100644 --- a/src/test/java/com/google/firebase/auth/TenantAwareFirebaseAuthIT.java +++ b/src/test/java/com/google/firebase/auth/TenantAwareFirebaseAuthIT.java @@ -262,7 +262,7 @@ public void testVerifyTokenWithWrongTenantAwareClient() throws Exception { @Test public void testOidcProviderConfigLifecycle() throws Exception { - // Create config provider + // Create provider config String providerId = "oidc.provider-id"; OidcProviderConfig config = temporaryProviderConfig.createOidcProviderConfig( @@ -277,14 +277,14 @@ public void testOidcProviderConfigLifecycle() throws Exception { assertEquals("ClientId", config.getClientId()); assertEquals("https://oidc.com/issuer", config.getIssuer()); - // Get config provider + // Get provider config config = tenantAwareAuth.getOidcProviderConfigAsync(providerId).get(); assertEquals(providerId, config.getProviderId()); assertEquals("DisplayName", config.getDisplayName()); assertEquals("ClientId", config.getClientId()); assertEquals("https://oidc.com/issuer", config.getIssuer()); - // Update config provider + // Update provider config OidcProviderConfig.UpdateRequest updateRequest = new OidcProviderConfig.UpdateRequest(providerId) .setDisplayName("NewDisplayName") @@ -298,7 +298,7 @@ public void testOidcProviderConfigLifecycle() throws Exception { assertEquals("NewClientId", config.getClientId()); assertEquals("https://oidc.com/new-issuer", config.getIssuer()); - // Delete config provider + // Delete provider config temporaryProviderConfig.deleteOidcProviderConfig(providerId); ProviderConfigTestUtils.assertOidcProviderConfigDoesNotExist(tenantAwareAuth, providerId); } @@ -337,7 +337,7 @@ public void testListOidcProviderConfigs() throws Exception { @Test public void testSamlProviderConfigLifecycle() throws Exception { - // Create config provider + // Create provider config String providerId = "saml.provider-id"; SamlProviderConfig config = temporaryProviderConfig.createSamlProviderConfig( new SamlProviderConfig.CreateRequest() @@ -359,14 +359,21 @@ public void testSamlProviderConfigLifecycle() throws Exception { assertEquals("RP_ENTITY_ID", config.getRpEntityId()); assertEquals("https://projectId.firebaseapp.com/__/auth/handler", config.getCallbackUrl()); - // TODO(micahstairs): Once implemented, add tests for getting and updating the SAML provider - // config. + config = tenantAwareAuth.getSamlProviderConfig(providerId); + assertEquals(providerId, config.getProviderId()); + assertEquals("DisplayName", config.getDisplayName()); + assertTrue(config.isEnabled()); + assertEquals("IDP_ENTITY_ID", config.getIdpEntityId()); + assertEquals("https://example.com/login", config.getSsoUrl()); + assertEquals(ImmutableList.of("certificate1", "certificate2"), config.getX509Certificates()); + assertEquals("RP_ENTITY_ID", config.getRpEntityId()); + assertEquals("https://projectId.firebaseapp.com/__/auth/handler", config.getCallbackUrl()); - // Delete config provider - temporaryProviderConfig.deleteSamlProviderConfig(providerId); + // TODO(micahstairs): Once implemented, add tests for updating the SAML provider config. - // TODO(micahstairs): Once the operation to get a SAML config is implemented, add an assertion - // that the SAML provider does not exist. + // Delete provider config + temporaryProviderConfig.deleteSamlProviderConfig(providerId); + ProviderConfigTestUtils.assertSamlProviderConfigDoesNotExist(tenantAwareAuth, providerId); } private String randomPhoneNumber() {