Repository: firebase/firebase-admin-go
Pull request #412 (2020-11-09 16:29:41)

Add enableAnonymousUser param to CreateTenant and UpdateTenant
#411 
#372

"https://identitytoolkit.googleapis.com/v2beta1" does not support `enableAnonymousUser` param. use "https://identitytoolkit.googleapis.com/v2".

RELEASE NOTE: Allowed enabling of anonymous provider via tenant configuration

google-cla[bot]: 
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: **Please visit <https://cla.developers.google.com/> to sign.**

Once you've signed (or fixed any issues), please reply here with `@googlebot I signed it!` and we'll verify it.

----

#### What to do if you already signed the CLA

##### Individual signers

*   It's possible we don't have your GitHub username or you're using a different email address on your commit. Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).

##### Corporate signers

*   Your company has a Point of Contact who decides which employees are authorized to participate. Ask your POC to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the Google project maintainer to [go/cla#troubleshoot](http://go/cla#troubleshoot) ([Public version](https://opensource.google/docs/cla/#troubleshoot)).
*   The email used to register you as an authorized contributor must be the email used for the Git commit. Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).
*   The email used to register you as an authorized contributor must also be [attached to your GitHub account](https://github.com/settings/emails).
		

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Ffirebase%2Ffirebase-admin-go%2Fpull%2F412) for more info**.

<!-- need_sender_cla -->
sonatard: @googlebot I signed it!
sonatard: https://github.com/firebase/firebase-admin-go/issues/411#issuecomment-724946065

@bojeil-google @rsgowman How is the progress of this plan?
sonatard: @bojeil-google @rsgowman Is there any problem with this pull request? I'm having trouble because I need this feature.
hiranya911: This was proposed and added to the Node.js SDK: https://firebase.google.com/docs/reference/admin/node/admin.auth.Tenant#anonymoussigninenabled

I don't think it's been approved for the Go SDK yet.
sonatard: Node.js SDK was released 8 months ago.

https://github.com/firebase/firebase-admin-node/pull/802
https://github.com/firebase/firebase-admin-node/releases/tag/v9.5.0
sonatard: @lahirumaramba Thank you for your review !! I fixed it. 
lahirumaramba: Hi @sonatard Thank you for updating the PR!
It looks like there are some lint issues. Please take a look at https://github.com/firebase/firebase-admin-go/runs/5699483758?check_suite_focus=true

I think your changes to `go.sum` cause the other CI failures. You should be able to fix them by running `go mod download golang.org/x/lint` or by just excluding the changes to `go.sum` from this PR.
sonatard: @lahirumaramba I executed `go mod download golang.org/x/lint`. 
sonatard: @lahirumaramba I found CI failed. Is there anything that I need to do? Fix format?
lahirumaramba: Hi, @sonatard Thank you for addressing the PR feedback!
Could you fix the formatting issues, please? You should be able to see them locally if you run `gofmt -l -s .`. Thank you!
sonatard: @lahirumaramba I fixed format 👍 
sonatard: @lahirumaramba Thank you for your kind communication. I have had a very pleasant experience since the review began.
I’m so excited to release it!

Patch:
diff --git a/auth/auth.go b/auth/auth.go
index 8ef7715..b6505a2 100644
--- a/auth/auth.go
+++ b/auth/auth.go
@@ -144,10 +144,10 @@ func NewClient(ctx context.Context, conf *internal.AuthConfig) (*Client, error)
 		baseURL = fmt.Sprintf("http://%s/identitytoolkit.googleapis.com", authEmulatorHost)
 	}
 	idToolkitV1Endpoint := fmt.Sprintf("%s/v1", baseURL)
-	idToolkitV2Beta1Endpoint := fmt.Sprintf("%s/v2beta1", baseURL)
+	idToolkitV2Endpoint := fmt.Sprintf("%s/v2", baseURL)
 	userManagementEndpoint := idToolkitV1Endpoint
-	providerConfigEndpoint := idToolkitV2Beta1Endpoint
-	tenantMgtEndpoint := idToolkitV2Beta1Endpoint
+	providerConfigEndpoint := idToolkitV2Endpoint
+	tenantMgtEndpoint := idToolkitV2Endpoint
 
 	base := &baseClient{
 		userManagementEndpoint: userManagementEndpoint,
diff --git a/auth/tenant_mgt.go b/auth/tenant_mgt.go
index 802926e..9212a8e 100644
--- a/auth/tenant_mgt.go
+++ b/auth/tenant_mgt.go
@@ -47,6 +47,7 @@ type Tenant struct {
 	DisplayName           string `json:"displayName"`
 	AllowPasswordSignUp   bool   `json:"allowPasswordSignup"`
 	EnableEmailLinkSignIn bool   `json:"enableEmailLinkSignin"`
+	EnableAnonymousUsers  bool   `json:"enableAnonymousUser"`
 }
 
 // TenantClient is used for managing users, configuring SAML/OIDC providers, and generating email
@@ -216,6 +217,7 @@ const (
 	tenantDisplayNameKey     = "displayName"
 	allowPasswordSignUpKey   = "allowPasswordSignup"
 	enableEmailLinkSignInKey = "enableEmailLinkSignin"
+	enableAnonymousUser      = "enableAnonymousUser"
 )
 
 // TenantToCreate represents the options used to create a new tenant.
@@ -240,6 +242,11 @@ func (t *TenantToCreate) EnableEmailLinkSignIn(enable bool) *TenantToCreate {
 	return t.set(enableEmailLinkSignInKey, enable)
 }
 
+// EnableAnonymousUsers enables or disables anonymous authentication.
+func (t *TenantToCreate) EnableAnonymousUsers(enable bool) *TenantToCreate {
+	return t.set(enableAnonymousUser, enable)
+}
+
 func (t *TenantToCreate) set(key string, value interface{}) *TenantToCreate {
 	t.ensureParams().Set(key, value)
 	return t
@@ -275,6 +282,11 @@ func (t *TenantToUpdate) EnableEmailLinkSignIn(enable bool) *TenantToUpdate {
 	return t.set(enableEmailLinkSignInKey, enable)
 }
 
+// EnableAnonymousUsers enables or disables anonymous authentication.
+func (t *TenantToUpdate) EnableAnonymousUsers(enable bool) *TenantToUpdate {
+	return t.set(enableAnonymousUser, enable)
+}
+
 func (t *TenantToUpdate) set(key string, value interface{}) *TenantToUpdate {
 	if t.params == nil {
 		t.params = make(nestedMap)


Test patch:
diff --git a/auth/auth_test.go b/auth/auth_test.go
index 634345a..30fbde8 100644
--- a/auth/auth_test.go
+++ b/auth/auth_test.go
@@ -36,11 +36,11 @@ import (
 )
 
 const (
-	credEnvVar                      = "GOOGLE_APPLICATION_CREDENTIALS"
-	testProjectID                   = "mock-project-id"
-	testVersion                     = "test-version"
-	defaultIDToolkitV1Endpoint      = "https://identitytoolkit.googleapis.com/v1"
-	defaultIDToolkitV2Beta1Endpoint = "https://identitytoolkit.googleapis.com/v2beta1"
+	credEnvVar                 = "GOOGLE_APPLICATION_CREDENTIALS"
+	testProjectID              = "mock-project-id"
+	testVersion                = "test-version"
+	defaultIDToolkitV1Endpoint = "https://identitytoolkit.googleapis.com/v1"
+	defaultIDToolkitV2Endpoint = "https://identitytoolkit.googleapis.com/v2"
 )
 
 var (
@@ -291,7 +291,7 @@ func TestNewClientExplicitNoAuth(t *testing.T) {
 func TestNewClientEmulatorHostEnvVar(t *testing.T) {
 	emulatorHost := "localhost:9099"
 	idToolkitV1Endpoint := "http://localhost:9099/identitytoolkit.googleapis.com/v1"
-	idToolkitV2Beta1Endpoint := "http://localhost:9099/identitytoolkit.googleapis.com/v2beta1"
+	idToolkitV2Endpoint := "http://localhost:9099/identitytoolkit.googleapis.com/v2"
 
 	os.Setenv(emulatorHostEnvVar, emulatorHost)
 	defer os.Unsetenv(emulatorHostEnvVar)
@@ -305,11 +305,11 @@ func TestNewClientEmulatorHostEnvVar(t *testing.T) {
 	if baseClient.userManagementEndpoint != idToolkitV1Endpoint {
 		t.Errorf("baseClient.userManagementEndpoint = %q; want = %q", baseClient.userManagementEndpoint, idToolkitV1Endpoint)
 	}
-	if baseClient.providerConfigEndpoint != idToolkitV2Beta1Endpoint {
-		t.Errorf("baseClient.providerConfigEndpoint = %q; want = %q", baseClient.providerConfigEndpoint, idToolkitV2Beta1Endpoint)
+	if baseClient.providerConfigEndpoint != idToolkitV2Endpoint {
+		t.Errorf("baseClient.providerConfigEndpoint = %q; want = %q", baseClient.providerConfigEndpoint, idToolkitV2Endpoint)
 	}
-	if baseClient.tenantMgtEndpoint != idToolkitV2Beta1Endpoint {
-		t.Errorf("baseClient.tenantMgtEndpoint = %q; want = %q", baseClient.tenantMgtEndpoint, idToolkitV2Beta1Endpoint)
+	if baseClient.tenantMgtEndpoint != idToolkitV2Endpoint {
+		t.Errorf("baseClient.tenantMgtEndpoint = %q; want = %q", baseClient.tenantMgtEndpoint, idToolkitV2Endpoint)
 	}
 	if _, ok := baseClient.signer.(emulatedSigner); !ok {
 		t.Errorf("baseClient.signer = %#v; want = %#v", baseClient.signer, emulatedSigner{})
@@ -1427,11 +1427,11 @@ func checkBaseClient(client *Client, wantProjectID string) error {
 	if baseClient.userManagementEndpoint != defaultIDToolkitV1Endpoint {
 		return fmt.Errorf("userManagementEndpoint = %q; want = %q", baseClient.userManagementEndpoint, defaultIDToolkitV1Endpoint)
 	}
-	if baseClient.providerConfigEndpoint != defaultIDToolkitV2Beta1Endpoint {
-		return fmt.Errorf("providerConfigEndpoint = %q; want = %q", baseClient.providerConfigEndpoint, defaultIDToolkitV2Beta1Endpoint)
+	if baseClient.providerConfigEndpoint != defaultIDToolkitV2Endpoint {
+		return fmt.Errorf("providerConfigEndpoint = %q; want = %q", baseClient.providerConfigEndpoint, defaultIDToolkitV2Endpoint)
 	}
-	if baseClient.tenantMgtEndpoint != defaultIDToolkitV2Beta1Endpoint {
-		return fmt.Errorf("providerConfigEndpoint = %q; want = %q", baseClient.providerConfigEndpoint, defaultIDToolkitV2Beta1Endpoint)
+	if baseClient.tenantMgtEndpoint != defaultIDToolkitV2Endpoint {
+		return fmt.Errorf("providerConfigEndpoint = %q; want = %q", baseClient.providerConfigEndpoint, defaultIDToolkitV2Endpoint)
 	}
 	if baseClient.projectID != wantProjectID {
 		return fmt.Errorf("projectID = %q; want = %q", baseClient.projectID, wantProjectID)
diff --git a/auth/tenant_mgt_test.go b/auth/tenant_mgt_test.go
index c6ce090..1e9e2b9 100644
--- a/auth/tenant_mgt_test.go
+++ b/auth/tenant_mgt_test.go
@@ -1084,14 +1084,16 @@ const tenantResponse = `{
     "name":"projects/mock-project-id/tenants/tenantID",
     "displayName": "Test Tenant",
     "allowPasswordSignup": true,
-    "enableEmailLinkSignin": true
+    "enableEmailLinkSignin": true,
+    "enableAnonymousUser": true
 }`
 
 const tenantResponse2 = `{
     "name":"projects/mock-project-id/tenants/tenantID2",
     "displayName": "Test Tenant 2",
     "allowPasswordSignup": true,
-    "enableEmailLinkSignin": true
+    "enableEmailLinkSignin": true,
+    "enableAnonymousUser": true
 }`
 
 const tenantNotFoundResponse = `{
@@ -1105,6 +1107,7 @@ var testTenant = &Tenant{
 	DisplayName:           "Test Tenant",
 	AllowPasswordSignUp:   true,
 	EnableEmailLinkSignIn: true,
+	EnableAnonymousUsers:  true,
 }
 
 var testTenant2 = &Tenant{
@@ -1112,6 +1115,7 @@ var testTenant2 = &Tenant{
 	DisplayName:           "Test Tenant 2",
 	AllowPasswordSignUp:   true,
 	EnableEmailLinkSignIn: true,
+	EnableAnonymousUsers:  true,
 }
 
 func TestTenant(t *testing.T) {
@@ -1177,7 +1181,8 @@ func TestCreateTenant(t *testing.T) {
 	options := (&TenantToCreate{}).
 		DisplayName(testTenant.DisplayName).
 		AllowPasswordSignUp(testTenant.AllowPasswordSignUp).
-		EnableEmailLinkSignIn(testTenant.EnableEmailLinkSignIn)
+		EnableEmailLinkSignIn(testTenant.EnableEmailLinkSignIn).
+		EnableAnonymousUsers(testTenant.EnableAnonymousUsers)
 	tenant, err := client.TenantManager.CreateTenant(context.Background(), options)
 	if err != nil {
 		t.Fatal(err)
@@ -1191,6 +1196,7 @@ func TestCreateTenant(t *testing.T) {
 		"displayName":           testTenant.DisplayName,
 		"allowPasswordSignup":   testTenant.AllowPasswordSignUp,
 		"enableEmailLinkSignin": testTenant.EnableEmailLinkSignIn,
+		"enableAnonymousUser":   testTenant.EnableAnonymousUsers,
 	}
 	if err := checkCreateTenantRequest(s, wantBody); err != nil {
 		t.Fatal(err)
@@ -1225,7 +1231,8 @@ func TestCreateTenantZeroValues(t *testing.T) {
 	options := (&TenantToCreate{}).
 		DisplayName("").
 		AllowPasswordSignUp(false).
-		EnableEmailLinkSignIn(false)
+		EnableEmailLinkSignIn(false).
+		EnableAnonymousUsers(false)
 	tenant, err := client.TenantManager.CreateTenant(context.Background(), options)
 	if err != nil {
 		t.Fatal(err)
@@ -1239,6 +1246,7 @@ func TestCreateTenantZeroValues(t *testing.T) {
 		"displayName":           "",
 		"allowPasswordSignup":   false,
 		"enableEmailLinkSignin": false,
+		"enableAnonymousUser":   false,
 	}
 	if err := checkCreateTenantRequest(s, wantBody); err != nil {
 		t.Fatal(err)
@@ -1274,7 +1282,8 @@ func TestUpdateTenant(t *testing.T) {
 	options := (&TenantToUpdate{}).
 		DisplayName(testTenant.DisplayName).
 		AllowPasswordSignUp(testTenant.AllowPasswordSignUp).
-		EnableEmailLinkSignIn(testTenant.EnableEmailLinkSignIn)
+		EnableEmailLinkSignIn(testTenant.EnableEmailLinkSignIn).
+		EnableAnonymousUsers(testTenant.EnableAnonymousUsers)
 	tenant, err := client.TenantManager.UpdateTenant(context.Background(), "tenantID", options)
 	if err != nil {
 		t.Fatal(err)
@@ -1288,8 +1297,9 @@ func TestUpdateTenant(t *testing.T) {
 		"displayName":           testTenant.DisplayName,
 		"allowPasswordSignup":   testTenant.AllowPasswordSignUp,
 		"enableEmailLinkSignin": testTenant.EnableEmailLinkSignIn,
+		"enableAnonymousUser":   testTenant.EnableAnonymousUsers,
 	}
-	wantMask := []string{"allowPasswordSignup", "displayName", "enableEmailLinkSignin"}
+	wantMask := []string{"allowPasswordSignup", "displayName", "enableAnonymousUser", "enableEmailLinkSignin"}
 	if err := checkUpdateTenantRequest(s, wantBody, wantMask); err != nil {
 		t.Fatal(err)
 	}
@@ -1327,7 +1337,8 @@ func TestUpdateTenantZeroValues(t *testing.T) {
 	options := (&TenantToUpdate{}).
 		DisplayName("").
 		AllowPasswordSignUp(false).
-		EnableEmailLinkSignIn(false)
+		EnableEmailLinkSignIn(false).
+		EnableAnonymousUsers(false)
 	tenant, err := client.TenantManager.UpdateTenant(context.Background(), "tenantID", options)
 	if err != nil {
 		t.Fatal(err)
@@ -1341,8 +1352,9 @@ func TestUpdateTenantZeroValues(t *testing.T) {
 		"displayName":           "",
 		"allowPasswordSignup":   false,
 		"enableEmailLinkSignin": false,
+		"enableAnonymousUser":   false,
 	}
-	wantMask := []string{"allowPasswordSignup", "displayName", "enableEmailLinkSignin"}
+	wantMask := []string{"allowPasswordSignup", "displayName", "enableAnonymousUser", "enableEmailLinkSignin"}
 	if err := checkUpdateTenantRequest(s, wantBody, wantMask); err != nil {
 		t.Fatal(err)
 	}
diff --git a/integration/auth/tenant_mgt_test.go b/integration/auth/tenant_mgt_test.go
index 381bb61..190a29f 100644
--- a/integration/auth/tenant_mgt_test.go
+++ b/integration/auth/tenant_mgt_test.go
@@ -31,12 +31,14 @@ func TestTenantManager(t *testing.T) {
 		DisplayName:           "admin-go-tenant",
 		AllowPasswordSignUp:   true,
 		EnableEmailLinkSignIn: true,
+		EnableAnonymousUsers:  true,
 	}
 
 	req := (&auth.TenantToCreate{}).
 		DisplayName("admin-go-tenant").
 		AllowPasswordSignUp(true).
-		EnableEmailLinkSignIn(true)
+		EnableEmailLinkSignIn(true).
+		EnableAnonymousUsers(true)
 	created, err := client.TenantManager.CreateTenant(context.Background(), req)
 	if err != nil {
 		t.Fatalf("CreateTenant() = %v", err)
@@ -129,11 +131,13 @@ func TestTenantManager(t *testing.T) {
 			DisplayName:           "updated-go-tenant",
 			AllowPasswordSignUp:   false,
 			EnableEmailLinkSignIn: false,
+			EnableAnonymousUsers:  false,
 		}
 		req := (&auth.TenantToUpdate{}).
 			DisplayName("updated-go-tenant").
 			AllowPasswordSignUp(false).
-			EnableEmailLinkSignIn(false)
+			EnableEmailLinkSignIn(false).
+			EnableAnonymousUsers(false)
 		tenant, err := client.TenantManager.UpdateTenant(context.Background(), id, req)
 		if err != nil {
 			t.Fatalf("UpdateTenant() = %v", err)