Repository: firebase/firebase-admin-java
Pull request #399 (2020-04-27 22:09:04)

Fix CreateRequest chaining and provider ID extraction.
This makes the base CreateRequest setters return the proper instance type, so that methods can be chained. This also makes it so that the provider ID can be parsed from the resource name.

A package private getProviderId() method was also added, which will be needed by the FirebaseUserManager class when the provider config operations are added there.

This work is part of adding multi-tenancy support (see issue #332).


Patch:
diff --git a/src/main/java/com/google/firebase/auth/OidcProviderConfig.java b/src/main/java/com/google/firebase/auth/OidcProviderConfig.java
index 0ad573a..7fc148e 100644
--- a/src/main/java/com/google/firebase/auth/OidcProviderConfig.java
+++ b/src/main/java/com/google/firebase/auth/OidcProviderConfig.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkArgument;
 import com.google.api.client.util.Key;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
+import com.google.firebase.auth.ProviderConfig.AbstractCreateRequest;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
@@ -31,7 +32,7 @@ import java.util.Map;
  *
  * <p>Instances of this class are immutable and thread safe.
  */
-public final class OidcProviderConfig extends AuthProviderConfig {
+public final class OidcProviderConfig extends ProviderConfig {
 
   @Key("clientId")
   private String clientId;
@@ -53,13 +54,13 @@ public final class OidcProviderConfig extends AuthProviderConfig {
    * <p>Set the initial attributes of the new provider by calling various setter methods available
    * in this class.
    */
-  public static final class CreateRequest extends AuthProviderConfig.CreateRequest {
+  public static final class CreateRequest extends AbstractCreateRequest<CreateRequest> {
 
     /**
      * Creates a new {@link CreateRequest}, which can be used to create a new OIDC Auth provider.
      *
      * <p>The returned object should be passed to
-     * {@link TenantAwareFirebaseAuth#createProviderConfig(CreateRequest)} to register the provider
+     * {@link AbstractFirebaseAuth#createOidcProviderConfig(CreateRequest)} to register the provider
      * information persistently.
      */
     public CreateRequest() { }
@@ -90,5 +91,9 @@ public final class OidcProviderConfig extends AuthProviderConfig {
       properties.put("issuer", issuer);
       return this;
     }
+
+    CreateRequest getThis() {
+      return this;
+    }
   }
 }
diff --git a/src/main/java/com/google/firebase/auth/AuthProviderConfig.java b/src/main/java/com/google/firebase/auth/ProviderConfig.java
similarity index 79%
rename from src/main/java/com/google/firebase/auth/AuthProviderConfig.java
rename to src/main/java/com/google/firebase/auth/ProviderConfig.java
index 9f301fe..07820ff 100644
--- a/src/main/java/com/google/firebase/auth/AuthProviderConfig.java
+++ b/src/main/java/com/google/firebase/auth/ProviderConfig.java
@@ -27,10 +27,10 @@ import java.util.Map;
 /**
  * The base class for Auth providers.
  */
-public abstract class AuthProviderConfig {
+public abstract class ProviderConfig {
 
   @Key("name")
-  private String providerId;
+  private String resourceName;
 
   @Key("displayName")
   private String displayName;
@@ -39,7 +39,7 @@ public abstract class AuthProviderConfig {
   private boolean enabled;
 
   public String getProviderId() {
-    return providerId;
+    return resourceName.substring(resourceName.lastIndexOf("/") + 1);
   }
 
   public String getDisplayName() {
@@ -56,20 +56,25 @@ public abstract class AuthProviderConfig {
    * <p>Set the initial attributes of the new provider by calling various setter methods available
    * in this class.
    */
-  public abstract static class CreateRequest {
+  public abstract static class AbstractCreateRequest<T extends AbstractCreateRequest<T>> {
 
     final Map<String,Object> properties = new HashMap<>();
+    String providerId;
 
     /**
      * Sets the ID for the new provider.
      *
      * @param providerId a non-null, non-empty provider ID string.
      */
-    public CreateRequest setProviderId(String providerId) {
+    public T setProviderId(String providerId) {
       checkArgument(
           !Strings.isNullOrEmpty(providerId), "provider ID name must not be null or empty");
-      properties.put("name", providerId);
-      return this;
+      this.providerId = providerId;
+      return getThis();
+    }
+
+    String getProviderId() {
+      return providerId;
     }
 
     /**
@@ -77,10 +82,10 @@ public abstract class AuthProviderConfig {
      *
      * @param displayName a non-null, non-empty display name string.
      */
-    public CreateRequest setDisplayName(String displayName) {
+    public T setDisplayName(String displayName) {
       checkArgument(!Strings.isNullOrEmpty(displayName), "display name must not be null or empty");
       properties.put("displayName", displayName);
-      return this;
+      return getThis();
     }
 
     /**
@@ -88,13 +93,15 @@ public abstract class AuthProviderConfig {
      *
      * @param enabled a boolean indicating whether the user can sign in with the provider
      */
-    public CreateRequest setEnabled(boolean enabled) {
+    public T setEnabled(boolean enabled) {
       properties.put("enabled", enabled);
-      return this;
+      return getThis();
     }
 
     Map<String, Object> getProperties() {
       return ImmutableMap.copyOf(properties);
     }
+
+    abstract T getThis();
   }
 }
diff --git a/src/main/java/com/google/firebase/auth/Tenant.java b/src/main/java/com/google/firebase/auth/Tenant.java
index 6641a04..c5024e1 100644
--- a/src/main/java/com/google/firebase/auth/Tenant.java
+++ b/src/main/java/com/google/firebase/auth/Tenant.java
@@ -31,9 +31,6 @@ import java.util.Map;
  */
 public final class Tenant {
 
-  // Lazily initialized from 'resourceName'.
-  private String tenantId;
-
   @Key("name")
   private String resourceName;
 
@@ -47,10 +44,7 @@ public final class Tenant {
   private boolean emailLinkSignInEnabled;
 
   public String getTenantId() {
-    if (tenantId == null) {
-      tenantId = resourceName.substring(resourceName.lastIndexOf("/") + 1);
-    }
-    return tenantId;
+    return resourceName.substring(resourceName.lastIndexOf("/") + 1);
   }
 
   public String getDisplayName() {


Test patch:
diff --git a/src/test/java/com/google/firebase/auth/OidcProviderConfigTest.java b/src/test/java/com/google/firebase/auth/OidcProviderConfigTest.java
index 1532665..e5cd94a 100644
--- a/src/test/java/com/google/firebase/auth/OidcProviderConfigTest.java
+++ b/src/test/java/com/google/firebase/auth/OidcProviderConfigTest.java
@@ -16,9 +16,60 @@
 
 package com.google.firebase.auth;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.api.client.googleapis.util.Utils;
+import com.google.api.client.json.JsonFactory;
+import java.io.IOException;
+import java.util.Map;
 import org.junit.Test;
 
 public class OidcProviderConfigTest {
+
+  private static final JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
+
+  private static final String OIDC_JSON_STRING =
+      "{"
+        + "\"name\":\"projects/projectId/oauthIdpConfigs/oidc.provider-id\","
+        + "\"displayName\":\"DISPLAY_NAME\","
+        + "\"enabled\":true,"
+        + "\"clientId\":\"CLIENT_ID\","
+        + "\"issuer\":\"https://oidc.com/issuer\""
+        + "}";
+
+  @Test
+  public void testJsonSerialization() throws IOException {
+    OidcProviderConfig config = jsonFactory.fromString(OIDC_JSON_STRING, OidcProviderConfig.class);
+
+    assertEquals(config.getProviderId(), "oidc.provider-id");
+    assertEquals(config.getDisplayName(), "DISPLAY_NAME");
+    assertTrue(config.isEnabled());
+    assertEquals(config.getClientId(), "CLIENT_ID");
+    assertEquals(config.getIssuer(), "https://oidc.com/issuer");
+  }
+
+  @Test
+  public void testCreateRequest() throws IOException {
+    OidcProviderConfig.CreateRequest createRequest = new OidcProviderConfig.CreateRequest();
+    createRequest
+      .setProviderId("oidc.provider-id")
+      .setDisplayName("DISPLAY_NAME")
+      .setEnabled(false)
+      .setClientId("CLIENT_ID")
+      .setIssuer("https://oidc.com/issuer");
+
+    assertEquals("oidc.provider-id", createRequest.getProviderId());
+    Map<String,Object> properties = createRequest.getProperties();
+    assertEquals(properties.size(), 4);
+    assertEquals("DISPLAY_NAME", (String) properties.get("displayName"));
+    assertFalse((boolean) properties.get("enabled"));
+    assertEquals("CLIENT_ID", (String) properties.get("clientId"));
+    assertEquals("https://oidc.com/issuer", (String) properties.get("issuer"));
+  }
+
   @Test(expected = IllegalArgumentException.class)
   public void testInvalidIssuerUrl() {
     new OidcProviderConfig.CreateRequest().setIssuer("not a valid url");