Skip to content

Commit 603f0f8

Browse files
authored
Release 1.0.1 (#16)
* Using the ClientOptions provided at App initialization to create the … (#12) * Using the ClientOptions provided at App initialization to create the HTTPClient in auth package. * Fixed context import * Updated test case * Fixing a test failure; Calling transport.NewHTTPClient() only when ctx and opts are available to avoid an unnecessary default credentials lookup. * Passing a non-nil context to AuthConfig during testing; Replacing Print+Exit calls with log.Fatal() (#13) * Bumped version to 1.0.1 (#15)
1 parent 7add6f4 commit 603f0f8

File tree

7 files changed

+116
-43
lines changed

7 files changed

+116
-43
lines changed

auth/auth.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ type Client struct {
7171
// This function can only be invoked from within the SDK. Client applications should access the
7272
// the Auth service through firebase.App.
7373
func NewClient(c *internal.AuthConfig) (*Client, error) {
74+
ks, err := newHTTPKeySource(c.Ctx, googleCertURL, c.Opts...)
75+
if err != nil {
76+
return nil, err
77+
}
78+
7479
client := &Client{
75-
ks: newHTTPKeySource(googleCertURL),
80+
ks: ks,
7681
projectID: c.ProjectID,
7782
}
7883
if c.Creds == nil || len(c.Creds.JSON) == 0 {
@@ -83,8 +88,7 @@ func NewClient(c *internal.AuthConfig) (*Client, error) {
8388
ClientEmail string `json:"client_email"`
8489
PrivateKey string `json:"private_key"`
8590
}
86-
err := json.Unmarshal(c.Creds.JSON, &svcAcct)
87-
if err != nil {
91+
if err := json.Unmarshal(c.Creds.JSON, &svcAcct); err != nil {
8892
return nil, err
8993
}
9094

auth/auth_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package auth
1616

1717
import (
1818
"errors"
19+
"log"
1920
"os"
2021
"strings"
2122
"testing"
@@ -98,15 +99,16 @@ func TestMain(m *testing.M) {
9899
opt := option.WithCredentialsFile("../testdata/service_account.json")
99100
creds, err = transport.Creds(context.Background(), opt)
100101
if err != nil {
101-
os.Exit(1)
102+
log.Fatalln(err)
102103
}
103104

104105
client, err = NewClient(&internal.AuthConfig{
106+
Ctx: context.Background(),
105107
Creds: creds,
106108
ProjectID: "mock-project-id",
107109
})
108110
if err != nil {
109-
os.Exit(1)
111+
log.Fatalln(err)
110112
}
111113
client.ks = &fileKeySource{FilePath: "../testdata/public_certs.json"}
112114

@@ -163,7 +165,7 @@ func TestCustomTokenError(t *testing.T) {
163165
}
164166

165167
func TestCustomTokenInvalidCredential(t *testing.T) {
166-
s, err := NewClient(&internal.AuthConfig{})
168+
s, err := NewClient(&internal.AuthConfig{Ctx: context.Background()})
167169
if err != nil {
168170
t.Fatal(err)
169171
}
@@ -226,7 +228,7 @@ func TestVerifyIDTokenError(t *testing.T) {
226228
}
227229

228230
func TestNoProjectID(t *testing.T) {
229-
c, err := NewClient(&internal.AuthConfig{Creds: creds})
231+
c, err := NewClient(&internal.AuthConfig{Ctx: context.Background(), Creds: creds})
230232
if err != nil {
231233
t.Fatal(err)
232234
}

auth/crypto.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ import (
2929
"strings"
3030
"sync"
3131
"time"
32+
33+
"golang.org/x/net/context"
34+
35+
"google.golang.org/api/option"
36+
"google.golang.org/api/transport"
3237
)
3338

3439
type publicKey struct {
@@ -70,12 +75,24 @@ type httpKeySource struct {
7075
Mutex *sync.Mutex
7176
}
7277

73-
func newHTTPKeySource(uri string) *httpKeySource {
74-
return &httpKeySource{
75-
KeyURI: uri,
76-
Clock: systemClock{},
77-
Mutex: &sync.Mutex{},
78+
func newHTTPKeySource(ctx context.Context, uri string, opts ...option.ClientOption) (*httpKeySource, error) {
79+
var hc *http.Client
80+
if ctx != nil && len(opts) > 0 {
81+
var err error
82+
hc, _, err = transport.NewHTTPClient(ctx, opts...)
83+
if err != nil {
84+
return nil, err
85+
}
86+
} else {
87+
hc = http.DefaultClient
7888
}
89+
90+
return &httpKeySource{
91+
KeyURI: uri,
92+
HTTPClient: hc,
93+
Clock: systemClock{},
94+
Mutex: &sync.Mutex{},
95+
}, nil
7996
}
8097

8198
// Keys returns the RSA Public Keys hosted at this key source's URI. Refreshes the data if
@@ -99,9 +116,6 @@ func (k *httpKeySource) hasExpired() bool {
99116

100117
func (k *httpKeySource) refreshKeys() error {
101118
k.CachedKeys = nil
102-
if k.HTTPClient == nil {
103-
k.HTTPClient = http.DefaultClient
104-
}
105119
resp, err := k.HTTPClient.Get(k.KeyURI)
106120
if err != nil {
107121
return err

auth/crypto_test.go

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@
1515
package auth
1616

1717
import (
18+
"fmt"
1819
"io"
1920
"io/ioutil"
2021
"net/http"
2122
"testing"
2223
"time"
24+
25+
"golang.org/x/net/context"
26+
27+
"google.golang.org/api/option"
2328
)
2429

2530
type mockHTTPResponse struct {
@@ -37,6 +42,27 @@ type mockReadCloser struct {
3742
closeCount int
3843
}
3944

45+
func newHTTPClient(data []byte) (*http.Client, *mockReadCloser) {
46+
rc := &mockReadCloser{
47+
data: string(data),
48+
closeCount: 0,
49+
}
50+
client := &http.Client{
51+
Transport: &mockHTTPResponse{
52+
Response: http.Response{
53+
Status: "200 OK",
54+
StatusCode: 200,
55+
Header: http.Header{
56+
"Cache-Control": {"public, max-age=100"},
57+
},
58+
Body: rc,
59+
},
60+
Err: nil,
61+
},
62+
}
63+
return client, rc
64+
}
65+
4066
func (r *mockReadCloser) Read(p []byte) (n int, err error) {
4167
if len(p) == 0 {
4268
return 0, nil
@@ -61,51 +87,70 @@ func TestHTTPKeySource(t *testing.T) {
6187
t.Fatal(err)
6288
}
6389

64-
mc := &mockClock{now: time.Unix(0, 0)}
65-
rc := &mockReadCloser{
66-
data: string(data),
67-
closeCount: 0,
90+
ks, err := newHTTPKeySource(context.Background(), "http://mock.url")
91+
if err != nil {
92+
t.Fatal(err)
6893
}
69-
ks := newHTTPKeySource("http://mock.url")
70-
ks.HTTPClient = &http.Client{
71-
Transport: &mockHTTPResponse{
72-
Response: http.Response{
73-
Status: "200 OK",
74-
StatusCode: 200,
75-
Header: http.Header{
76-
"Cache-Control": {"public, max-age=100"},
77-
},
78-
Body: rc,
79-
},
80-
Err: nil,
81-
},
94+
95+
if ks.HTTPClient == nil {
96+
t.Errorf("HTTPClient = nil; want non-nil")
8297
}
98+
hc, rc := newHTTPClient(data)
99+
ks.HTTPClient = hc
100+
if err := verifyHTTPKeySource(ks, rc); err != nil {
101+
t.Fatal(err)
102+
}
103+
}
104+
105+
func TestHTTPKeySourceWithClient(t *testing.T) {
106+
data, err := ioutil.ReadFile("../testdata/public_certs.json")
107+
if err != nil {
108+
t.Fatal(err)
109+
}
110+
111+
hc, rc := newHTTPClient(data)
112+
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
113+
if err != nil {
114+
t.Fatal(err)
115+
}
116+
117+
if ks.HTTPClient != hc {
118+
t.Errorf("HTTPClient = %v; want %v", ks.HTTPClient, hc)
119+
}
120+
if err := verifyHTTPKeySource(ks, rc); err != nil {
121+
t.Fatal(err)
122+
}
123+
}
124+
125+
func verifyHTTPKeySource(ks *httpKeySource, rc *mockReadCloser) error {
126+
mc := &mockClock{now: time.Unix(0, 0)}
83127
ks.Clock = mc
84128

85129
exp := time.Unix(100, 0)
86130
for i := 0; i <= 100; i++ {
87131
keys, err := ks.Keys()
88132
if err != nil {
89-
t.Fatal(err)
133+
return err
90134
}
91135
if len(keys) != 3 {
92-
t.Errorf("Keys: %d; want: 3", len(keys))
136+
return fmt.Errorf("Keys: %d; want: 3", len(keys))
93137
} else if rc.closeCount != 1 {
94-
t.Errorf("HTTP calls: %d; want: 1", rc.closeCount)
138+
return fmt.Errorf("HTTP calls: %d; want: 1", rc.closeCount)
95139
} else if ks.ExpiryTime != exp {
96-
t.Errorf("Expiry: %v; want: %v", ks.ExpiryTime, exp)
140+
return fmt.Errorf("Expiry: %v; want: %v", ks.ExpiryTime, exp)
97141
}
98142
mc.now = mc.now.Add(time.Second)
99143
}
100144

101145
mc.now = time.Unix(101, 0)
102146
keys, err := ks.Keys()
103147
if err != nil {
104-
t.Fatal(err)
148+
return err
105149
}
106150
if len(keys) != 3 {
107-
t.Errorf("Keys: %d; want: 3", len(keys))
151+
return fmt.Errorf("Keys: %d; want: 3", len(keys))
108152
} else if rc.closeCount != 2 {
109-
t.Errorf("HTTP calls: %d; want: 2", rc.closeCount)
153+
return fmt.Errorf("HTTP calls: %d; want: 2", rc.closeCount)
110154
}
155+
return nil
111156
}

firebase.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var firebaseScopes = []string{
3535
}
3636

3737
// Version of the Firebase Go Admin SDK.
38-
const Version = "1.0.0"
38+
const Version = "1.0.1"
3939

4040
// An App holds configuration and state common to all Firebase services that are exposed from the SDK.
4141
type App struct {
@@ -53,8 +53,10 @@ type Config struct {
5353
// Auth returns an instance of auth.Client.
5454
func (a *App) Auth() (*auth.Client, error) {
5555
conf := &internal.AuthConfig{
56+
Ctx: a.ctx,
5657
Creds: a.creds,
5758
ProjectID: a.projectID,
59+
Opts: a.opts,
5860
}
5961
return auth.NewClient(conf)
6062
}

integration/auth_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"flag"
2121
"fmt"
2222
"io/ioutil"
23+
"log"
2324
"net/http"
2425
"os"
2526
"testing"
@@ -37,18 +38,18 @@ var client *auth.Client
3738
func TestMain(m *testing.M) {
3839
flag.Parse()
3940
if testing.Short() {
40-
fmt.Println("skipping auth integration tests in short mode.")
41+
log.Println("skipping auth integration tests in short mode.")
4142
os.Exit(0)
4243
}
4344

4445
app, err := internal.NewTestApp(context.Background())
4546
if err != nil {
46-
os.Exit(1)
47+
log.Fatalln(err)
4748
}
4849

4950
client, err = app.Auth()
5051
if err != nil {
51-
os.Exit(1)
52+
log.Fatalln(err)
5253
}
5354

5455
os.Exit(m.Run())

internal/internal.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@
1616
package internal
1717

1818
import (
19+
"golang.org/x/net/context"
20+
"google.golang.org/api/option"
21+
1922
"golang.org/x/oauth2/google"
2023
)
2124

2225
// AuthConfig represents the configuration of Firebase Auth service.
2326
type AuthConfig struct {
27+
Ctx context.Context
28+
Opts []option.ClientOption
2429
Creds *google.DefaultCredentials
2530
ProjectID string
2631
}

0 commit comments

Comments
 (0)