Skip to content

Commit 9b51e14

Browse files
authored
Release Version 2.3.0 (#57)
* Documentation fix md file (#43) * Clarify certificate download comment * Fix Link * Adding User Management utils, including Custom Claims in the auth package. (#42) Adding the user management go SDK. This includes the customClaims and the iterator over all users. (as well as Create, Update, Delete User, and GetUser (by UID, Phone or Email)) Proposal : go/firebase-go-user-mgt Code snippets: https://firebase-dot-devsite.googleplex.com/docs/auth/admin/manage-users https://firebase-dot-devsite.googleplex.com/docs/auth/admin/custom-claims TODO: clean up the case of an http.DefaultClient when there are no options. * Minor improvements to user management code (#44) * some changes to auth * Implemented a reusable HTTP client API * Added test cases * Comment clean up * Simplified the usage by adding HTTPClient * Using the old ctx import * Support for arbitrary entity types in the request * Renamed fields; Added documentation * Removing a redundant else case * initial * more integration tests * set custom - still needs guessing the type for unmarshaling. * tests * server * server * . * json * json * move testdata * get * tests * updated to param struct of pointers to call create and update * Comments * cleanup * cleanup * cleanup * cleanup minor test changes * Changing the iteraator pattern * last page iterator test fix * clean up tests next. * make the fetch tidier * fetch cleanup * cc change * custom claims * newline * adding error propagation to makeExportedUser * remove trivial claims map type * list users test data * rename p ptr, and remove the with... options for the iterator * rename p ptr * some unit tests * adding integration tests for custom claims * NO ERROR * unit tests * comments hkj * addressing comments * delete unneeded json file * phone NUMBER * typo * remove cc from create * refactor param structs * remove package ptr * test refactor * cleanup comments * cleanup debug.test * Adding back the default http client * fix httpClient for tests * creds * creds * fix default http client * cleanupPrintfs * disable * Reanme payload vars * Revert newHTTPKeySource function * add back defaultClient in newClient * reenable testNewHTTPClientNoOpts) * reverting keysource tests) * Take the httpClient from the keysource * Removethe +1 second for the token timestamp. * Adding tests * White spaces * Redesign the error validators * prepare returns an error. * cleanup * dissolve * dissolve * clean tests * split integration tests * addressing comments * addressing comments opt branch/ BEFORE hc change * Removing the defaultClient from the NewClient, and extracting the NewClient creation outside of KeySource * closer from echoServer * cleanup + 500 error unit test * unify error messages * Refactor stop side effect for params preparation * +1 to timestamp for flakiness * removing +1 * disallow defaultClient * whitespaces * http default * add TODO * Code clean up and refactoring * Refactored integration tests (#46) * Refactored integration tests * Minor cleanup * Auth Unit Test Improvements (#45) * Cleaning up new auth tests * More updates to tests; Dissolved commonParams type * More test updates * More argument validation for auth * Fixed a bug in enable/disable user; Added more tests; Cleaned up unit tests * Removed debug file * Create the 5th user in the integration tests for user management. (#47) * Bump version to 2.2.0 (#49) * Adding version, stat counter header and test (#50) * Adding version to the header for the stat counter + tests * bump version to 2.2.1 * Adding comment for manual cleanup * Auth Package Internal Cleanup (#53) * Release v2.2.1 (#51) * Adding version, stat counter header and test (#50) * Adding version to the header for the stat counter + tests * bump version to 2.2.1 * Adding comment for manual cleanup * Experimental auth cleanup * Using a mock token source in tests * Further cleaning up the test cases * Implemented IID Delete API (#41) * Implemented IID Delete API * Cleaned up code * Updated test case * Updating comments * Improved error handling * Fixing malformed error messages due to extra format placeholders; Using the recommended Go error message format (no caps or punctuation) * Bumped version to 2.3.0 (#56)
1 parent 6f93c0d commit 9b51e14

File tree

12 files changed

+481
-62
lines changed

12 files changed

+481
-62
lines changed

auth/auth.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"encoding/pem"
2323
"errors"
2424
"fmt"
25-
"net/http"
2625
"strings"
2726

2827
"firebase.google.com/go/internal"
@@ -102,6 +101,7 @@ func NewClient(ctx context.Context, c *internal.AuthConfig) (*Client, error) {
102101
}
103102
email = svcAcct.ClientEmail
104103
}
104+
105105
var snr signer
106106
if email != "" && pk != nil {
107107
snr = serviceAcctSigner{email: email, pk: pk}
@@ -111,21 +111,15 @@ func NewClient(ctx context.Context, c *internal.AuthConfig) (*Client, error) {
111111
return nil, err
112112
}
113113
}
114-
hc := http.DefaultClient
115-
if len(c.Opts) > 0 { // TODO: fix the default when len = 0
116-
hc, _, err = transport.NewHTTPClient(ctx, c.Opts...)
117-
if err != nil {
118-
return nil, err
119-
}
120-
}
121-
ks, err := newHTTPKeySource(googleCertURL, hc)
114+
115+
hc, _, err := transport.NewHTTPClient(ctx, c.Opts...)
122116
if err != nil {
123117
return nil, err
124118
}
125119

126120
return &Client{
127121
hc: &internal.HTTPClient{Client: hc},
128-
ks: ks,
122+
ks: newHTTPKeySource(googleCertURL, hc),
129123
projectID: c.ProjectID,
130124
snr: snr,
131125
url: idToolKitURL,

auth/auth_test.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,17 @@ var testIDToken string
4141
var testGetUserResponse []byte
4242
var testListUsersResponse []byte
4343

44+
var defaultTestOpts = []option.ClientOption{
45+
option.WithCredentialsFile("../testdata/service_account.json"),
46+
}
47+
4448
func TestMain(m *testing.M) {
4549
var (
4650
err error
4751
ks keySource
4852
ctx context.Context
4953
creds *google.DefaultCredentials
54+
opts []option.ClientOption
5055
)
5156
if appengine.IsDevAppServer() {
5257
aectx, aedone, err := aetest.NewContext()
@@ -62,8 +67,8 @@ func TestMain(m *testing.M) {
6267
}
6368
} else {
6469
ctx = context.Background()
65-
opt := option.WithCredentialsFile("../testdata/service_account.json")
66-
creds, err = transport.Creds(ctx, opt)
70+
opts = defaultTestOpts
71+
creds, err = transport.Creds(ctx, opts...)
6772
if err != nil {
6873
log.Fatalln(err)
6974
}
@@ -72,7 +77,7 @@ func TestMain(m *testing.M) {
7277
}
7378
client, err = NewClient(ctx, &internal.AuthConfig{
7479
Creds: creds,
75-
Opts: []option.ClientOption{option.WithCredentialsFile("../testdata/service_account.json")},
80+
Opts: opts,
7681
ProjectID: "mock-project-id",
7782
})
7883
if err != nil {
@@ -170,7 +175,9 @@ func TestCustomTokenError(t *testing.T) {
170175
}
171176

172177
func TestCustomTokenInvalidCredential(t *testing.T) {
173-
s, err := NewClient(context.Background(), &internal.AuthConfig{})
178+
// AuthConfig with nil Creds
179+
conf := &internal.AuthConfig{Opts: defaultTestOpts}
180+
s, err := NewClient(context.Background(), conf)
174181
if err != nil {
175182
t.Fatal(err)
176183
}
@@ -237,7 +244,9 @@ func TestVerifyIDTokenError(t *testing.T) {
237244
}
238245

239246
func TestNoProjectID(t *testing.T) {
240-
c, err := NewClient(context.Background(), &internal.AuthConfig{})
247+
// AuthConfig with empty ProjectID
248+
conf := &internal.AuthConfig{Opts: defaultTestOpts}
249+
c, err := NewClient(context.Background(), conf)
241250
if err != nil {
242251
t.Fatal(err)
243252
}

auth/crypto.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ type httpKeySource struct {
7575
Mutex *sync.Mutex
7676
}
7777

78-
func newHTTPKeySource(uri string, hc *http.Client) (*httpKeySource, error) {
78+
func newHTTPKeySource(uri string, hc *http.Client) *httpKeySource {
7979
return &httpKeySource{
8080
KeyURI: uri,
8181
HTTPClient: hc,
8282
Clock: systemClock{},
8383
Mutex: &sync.Mutex{},
84-
}, nil
84+
}
8585
}
8686

8787
// Keys returns the RSA Public Keys hosted at this key source's URI. Refreshes the data if

auth/crypto_test.go

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,8 @@ func TestHTTPKeySource(t *testing.T) {
8383
if err != nil {
8484
t.Fatal(err)
8585
}
86-
ks, err := newHTTPKeySource("http://mock.url", http.DefaultClient)
87-
if err != nil {
88-
t.Fatal(err)
89-
}
9086

87+
ks := newHTTPKeySource("http://mock.url", http.DefaultClient)
9188
if ks.HTTPClient == nil {
9289
t.Errorf("HTTPClient = nil; want non-nil")
9390
}
@@ -105,11 +102,7 @@ func TestHTTPKeySourceWithClient(t *testing.T) {
105102
}
106103

107104
hc, rc := newTestHTTPClient(data)
108-
ks, err := newHTTPKeySource("http://mock.url", hc)
109-
if err != nil {
110-
t.Fatal(err)
111-
}
112-
105+
ks := newHTTPKeySource("http://mock.url", hc)
113106
if ks.HTTPClient != hc {
114107
t.Errorf("HTTPClient = %v; want %v", ks.HTTPClient, hc)
115108
}
@@ -120,23 +113,15 @@ func TestHTTPKeySourceWithClient(t *testing.T) {
120113

121114
func TestHTTPKeySourceEmptyResponse(t *testing.T) {
122115
hc, _ := newTestHTTPClient([]byte(""))
123-
ks, err := newHTTPKeySource("http://mock.url", hc)
124-
if err != nil {
125-
t.Fatal(err)
126-
}
127-
116+
ks := newHTTPKeySource("http://mock.url", hc)
128117
if keys, err := ks.Keys(); keys != nil || err == nil {
129118
t.Errorf("Keys() = (%v, %v); want = (nil, error)", keys, err)
130119
}
131120
}
132121

133122
func TestHTTPKeySourceIncorrectResponse(t *testing.T) {
134123
hc, _ := newTestHTTPClient([]byte("{\"foo\": 1}"))
135-
ks, err := newHTTPKeySource("http://mock.url", hc)
136-
if err != nil {
137-
t.Fatal(err)
138-
}
139-
124+
ks := newHTTPKeySource("http://mock.url", hc)
140125
if keys, err := ks.Keys(); keys != nil || err == nil {
141126
t.Errorf("Keys() = (%v, %v); want = (nil, error)", keys, err)
142127
}
@@ -148,11 +133,7 @@ func TestHTTPKeySourceTransportError(t *testing.T) {
148133
Err: errors.New("transport error"),
149134
},
150135
}
151-
ks, err := newHTTPKeySource("http://mock.url", hc)
152-
if err != nil {
153-
t.Fatal(err)
154-
}
155-
136+
ks := newHTTPKeySource("http://mock.url", hc)
156137
if keys, err := ks.Keys(); keys != nil || err == nil {
157138
t.Errorf("Keys() = (%v, %v); want = (nil, error)", keys, err)
158139
}

auth/user_mgt_test.go

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ import (
2525
"testing"
2626

2727
"firebase.google.com/go/internal"
28+
2829
"golang.org/x/net/context"
30+
"golang.org/x/oauth2"
2931
"google.golang.org/api/iterator"
32+
"google.golang.org/api/option"
3033
)
3134

3235
var testUser = &UserRecord{
@@ -621,24 +624,17 @@ func TestMakeExportedUser(t *testing.T) {
621624
}
622625

623626
func TestHTTPError(t *testing.T) {
624-
s := mockAuthServer{}
625-
s.Srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
626-
s.Req = append(s.Req, r)
627-
w.WriteHeader(500)
628-
w.Header().Set("Content-Type", "application/json")
629-
w.Write([]byte(`{"error":"test"}`))
630-
}))
627+
s := echoServer([]byte(`{"error":"test"}`), t)
631628
defer s.Close()
629+
s.Status = 500
632630

633-
client, err := NewClient(context.Background(), &internal.AuthConfig{})
634-
if err != nil {
635-
t.Fatal()
631+
u, err := s.Client.GetUser(context.Background(), "some uid")
632+
if u != nil || err == nil {
633+
t.Fatalf("GetUser() = (%v, %v); want = (nil, error)", u, err)
636634
}
637-
client.url = s.Srv.URL + "/"
638635

639636
want := `http error status: 500; reason: {"error":"test"}`
640-
_, err = client.GetUser(context.Background(), "some uid")
641-
if err == nil || err.Error() != want {
637+
if err.Error() != want {
642638
t.Errorf("GetUser() = %v; want = %q", err, want)
643639
}
644640
}
@@ -664,7 +660,6 @@ type mockAuthServer struct {
664660
func echoServer(resp interface{}, t *testing.T) *mockAuthServer {
665661
var b []byte
666662
var err error
667-
testVersion := "test.version"
668663
switch v := resp.(type) {
669664
case nil:
670665
b = []byte("")
@@ -678,19 +673,30 @@ func echoServer(resp interface{}, t *testing.T) *mockAuthServer {
678673
}
679674
s := mockAuthServer{Resp: b}
680675

676+
const testToken = "test.token"
677+
const testVersion = "test.version"
678+
681679
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
682680
defer r.Body.Close()
683681
reqBody, err := ioutil.ReadAll(r.Body)
684682
if err != nil {
685683
t.Fatal(err)
686684
}
685+
s.Rbody = reqBody
687686
s.Req = append(s.Req, r)
688-
vh := r.Header.Get("X-Client-Version")
689-
wantvh := "Go/Admin/" + testVersion
690-
if vh != wantvh {
691-
t.Errorf("version header = %s; want: %s", vh, wantvh)
687+
688+
gh := r.Header.Get("Authorization")
689+
wh := "Bearer " + testToken
690+
if gh != wh {
691+
t.Errorf("Authorization header = %q; want = %q", gh, wh)
692692
}
693-
s.Rbody = reqBody
693+
694+
gh = r.Header.Get("X-Client-Version")
695+
wh = "Go/Admin/" + testVersion
696+
if gh != wh {
697+
t.Errorf("X-Client-Version header = %q; want: %q", gh, wh)
698+
}
699+
694700
for k, v := range s.Header {
695701
w.Header().Set(k, v)
696702
}
@@ -702,7 +708,14 @@ func echoServer(resp interface{}, t *testing.T) *mockAuthServer {
702708

703709
})
704710
s.Srv = httptest.NewServer(handler)
705-
authClient, err := NewClient(context.Background(), &internal.AuthConfig{Version: testVersion})
711+
712+
conf := &internal.AuthConfig{
713+
Opts: []option.ClientOption{
714+
option.WithTokenSource(&mockTokenSource{testToken}),
715+
},
716+
Version: testVersion,
717+
}
718+
authClient, err := NewClient(context.Background(), conf)
706719
if err != nil {
707720
t.Fatal(err)
708721
}
@@ -714,3 +727,11 @@ func echoServer(resp interface{}, t *testing.T) *mockAuthServer {
714727
func (s *mockAuthServer) Close() {
715728
s.Srv.Close()
716729
}
730+
731+
type mockTokenSource struct {
732+
AccessToken string
733+
}
734+
735+
func (m *mockTokenSource) Token() (*oauth2.Token, error) {
736+
return &oauth2.Token{AccessToken: m.AccessToken}, nil
737+
}

firebase.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"cloud.google.com/go/firestore"
2424

2525
"firebase.google.com/go/auth"
26+
"firebase.google.com/go/iid"
2627
"firebase.google.com/go/internal"
2728
"firebase.google.com/go/storage"
2829

@@ -44,7 +45,7 @@ var firebaseScopes = []string{
4445
}
4546

4647
// Version of the Firebase Go Admin SDK.
47-
const Version = "2.2.1"
48+
const Version = "2.3.0"
4849

4950
// An App holds configuration and state common to all Firebase services that are exposed from the SDK.
5051
type App struct {
@@ -89,6 +90,15 @@ func (a *App) Firestore(ctx context.Context) (*firestore.Client, error) {
8990
return firestore.NewClient(ctx, a.projectID, a.opts...)
9091
}
9192

93+
// InstanceID returns an instance of iid.Client.
94+
func (a *App) InstanceID(ctx context.Context) (*iid.Client, error) {
95+
conf := &internal.InstanceIDConfig{
96+
ProjectID: a.projectID,
97+
Opts: a.opts,
98+
}
99+
return iid.NewClient(ctx, conf)
100+
}
101+
92102
// NewApp creates a new App from the provided config and client options.
93103
//
94104
// If the client options contain a valid credential (a service account file, a refresh token file or an

firebase_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,18 @@ func TestFirestoreWithNoProjectID(t *testing.T) {
281281
}
282282
}
283283

284+
func TestInstanceID(t *testing.T) {
285+
ctx := context.Background()
286+
app, err := NewApp(ctx, nil, option.WithCredentialsFile("testdata/service_account.json"))
287+
if err != nil {
288+
t.Fatal(err)
289+
}
290+
291+
if c, err := app.InstanceID(ctx); c == nil || err != nil {
292+
t.Errorf("InstanceID() = (%v, %v); want (iid, nil)", c, err)
293+
}
294+
}
295+
284296
func TestCustomTokenSource(t *testing.T) {
285297
ctx := context.Background()
286298
ts := &testTokenSource{AccessToken: "mock-token-from-custom"}

0 commit comments

Comments
 (0)