Skip to content

Commit aed47cf

Browse files
committed
Merge branch 'dev'
2 parents e9de174 + 82c46f4 commit aed47cf

File tree

14 files changed

+633
-80
lines changed

14 files changed

+633
-80
lines changed

auth/auth.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"strings"
2626

2727
"firebase.google.com/go/internal"
28+
"golang.org/x/net/context"
2829
)
2930

3031
const firebaseAudience = "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
@@ -73,7 +74,7 @@ type signer interface {
7374
//
7475
// This function can only be invoked from within the SDK. Client applications should access the
7576
// the Auth service through firebase.App.
76-
func NewClient(c *internal.AuthConfig) (*Client, error) {
77+
func NewClient(ctx context.Context, c *internal.AuthConfig) (*Client, error) {
7778
var (
7879
err error
7980
email string
@@ -99,13 +100,13 @@ func NewClient(c *internal.AuthConfig) (*Client, error) {
99100
if email != "" && pk != nil {
100101
snr = serviceAcctSigner{email: email, pk: pk}
101102
} else {
102-
snr, err = newSigner(c.Ctx)
103+
snr, err = newSigner(ctx)
103104
if err != nil {
104105
return nil, err
105106
}
106107
}
107108

108-
ks, err := newHTTPKeySource(c.Ctx, googleCertURL, c.Opts...)
109+
ks, err := newHTTPKeySource(ctx, googleCertURL, c.Opts...)
109110
if err != nil {
110111
return nil, err
111112
}

auth/auth_test.go

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
package auth
1616

1717
import (
18+
"encoding/json"
1819
"errors"
20+
"fmt"
1921
"io/ioutil"
2022
"log"
2123
"os"
@@ -58,17 +60,16 @@ func TestMain(m *testing.M) {
5860
log.Fatalln(err)
5961
}
6062
} else {
61-
opt := option.WithCredentialsFile("../testdata/service_account.json")
62-
creds, err = transport.Creds(context.Background(), opt)
63+
ctx = context.Background()
64+
creds, err = transport.Creds(ctx, option.WithCredentialsFile("../testdata/service_account.json"))
6365
if err != nil {
6466
log.Fatalln(err)
6567
}
6668

6769
ks = &fileKeySource{FilePath: "../testdata/public_certs.json"}
6870
}
6971

70-
client, err = NewClient(&internal.AuthConfig{
71-
Ctx: ctx,
72+
client, err = NewClient(ctx, &internal.AuthConfig{
7273
Creds: creds,
7374
ProjectID: "mock-project-id",
7475
})
@@ -81,6 +82,32 @@ func TestMain(m *testing.M) {
8182
os.Exit(m.Run())
8283
}
8384

85+
func TestNewClientInvalidCredentials(t *testing.T) {
86+
creds := &google.DefaultCredentials{
87+
JSON: []byte("foo"),
88+
}
89+
conf := &internal.AuthConfig{Creds: creds}
90+
if c, err := NewClient(context.Background(), conf); c != nil || err == nil {
91+
t.Errorf("NewCient() = (%v,%v); want = (nil, error)", c, err)
92+
}
93+
}
94+
95+
func TestNewClientInvalidPrivateKey(t *testing.T) {
96+
sa := map[string]interface{}{
97+
"private_key": "foo",
98+
"client_email": "bar@test.com",
99+
}
100+
b, err := json.Marshal(sa)
101+
if err != nil {
102+
t.Fatal(err)
103+
}
104+
creds := &google.DefaultCredentials{JSON: b}
105+
conf := &internal.AuthConfig{Creds: creds}
106+
if c, err := NewClient(context.Background(), conf); c != nil || err == nil {
107+
t.Errorf("NewCient() = (%v,%v); want = (nil, error)", c, err)
108+
}
109+
}
110+
84111
func TestCustomToken(t *testing.T) {
85112
token, err := client.CustomToken("user1")
86113
if err != nil {
@@ -118,31 +145,32 @@ func TestCustomTokenError(t *testing.T) {
118145
}{
119146
{"EmptyName", "", nil},
120147
{"LongUid", strings.Repeat("a", 129), nil},
121-
{"ReservedClaims", "uid", map[string]interface{}{"sub": "1234"}},
148+
{"ReservedClaim", "uid", map[string]interface{}{"sub": "1234"}},
149+
{"ReservedClaims", "uid", map[string]interface{}{"sub": "1234", "aud": "foo"}},
122150
}
123151

124152
for _, tc := range cases {
125153
token, err := client.CustomTokenWithClaims(tc.uid, tc.claims)
126154
if token != "" || err == nil {
127-
t.Errorf("CustomTokenWithClaims(%q) = (%q, %v); want: (\"\", error)", tc.name, token, err)
155+
t.Errorf("CustomTokenWithClaims(%q) = (%q, %v); want = (\"\", error)", tc.name, token, err)
128156
}
129157
}
130158
}
131159

132160
func TestCustomTokenInvalidCredential(t *testing.T) {
133-
s, err := NewClient(&internal.AuthConfig{Ctx: context.Background()})
161+
s, err := NewClient(context.Background(), &internal.AuthConfig{})
134162
if err != nil {
135163
t.Fatal(err)
136164
}
137165

138166
token, err := s.CustomToken("user1")
139167
if token != "" || err == nil {
140-
t.Errorf("CustomTokenWithClaims() = (%q, %v); want: (\"\", error)", token, err)
168+
t.Errorf("CustomTokenWithClaims() = (%q, %v); want = (\"\", error)", token, err)
141169
}
142170

143171
token, err = s.CustomTokenWithClaims("user1", map[string]interface{}{"foo": "bar"})
144172
if token != "" || err == nil {
145-
t.Errorf("CustomTokenWithClaims() = (%q, %v); want: (\"\", error)", token, err)
173+
t.Errorf("CustomTokenWithClaims() = (%q, %v); want = (\"\", error)", token, err)
146174
}
147175
}
148176

@@ -152,15 +180,23 @@ func TestVerifyIDToken(t *testing.T) {
152180
t.Fatal(err)
153181
}
154182
if ft.Claims["admin"] != true {
155-
t.Errorf("Claims['admin'] = %v; want: true", ft.Claims["admin"])
183+
t.Errorf("Claims['admin'] = %v; want = true", ft.Claims["admin"])
156184
}
157185
if ft.UID != ft.Subject {
158186
t.Errorf("UID = %q; Sub = %q; want UID = Sub", ft.UID, ft.Subject)
159187
}
160188
}
161189

190+
func TestVerifyIDTokenInvalidSignature(t *testing.T) {
191+
parts := strings.Split(testIDToken, ".")
192+
token := fmt.Sprintf("%s:%s:invalidsignature", parts[0], parts[1])
193+
if ft, err := client.VerifyIDToken(token); ft != nil || err == nil {
194+
t.Errorf("VerifyiDToken('invalid-signature') = (%v, %v); want = (nil, error)", ft, err)
195+
}
196+
}
197+
162198
func TestVerifyIDTokenError(t *testing.T) {
163-
var now int64 = 1000
199+
now := time.Now().Unix()
164200
cases := []struct {
165201
name string
166202
token string
@@ -172,28 +208,24 @@ func TestVerifyIDTokenError(t *testing.T) {
172208
{"EmptySubject", getIDToken(mockIDTokenPayload{"sub": ""})},
173209
{"IntSubject", getIDToken(mockIDTokenPayload{"sub": 10})},
174210
{"LongSubject", getIDToken(mockIDTokenPayload{"sub": strings.Repeat("a", 129)})},
175-
{"FutureToken", getIDToken(mockIDTokenPayload{"iat": time.Unix(now+1, 0)})},
211+
{"FutureToken", getIDToken(mockIDTokenPayload{"iat": now + 1000})},
176212
{"ExpiredToken", getIDToken(mockIDTokenPayload{
177-
"iat": time.Unix(now-10, 0),
178-
"exp": time.Unix(now-1, 0),
213+
"iat": now - 1000,
214+
"exp": now - 100,
179215
})},
180216
{"EmptyToken", ""},
181217
{"BadFormatToken", "foobar"},
182218
}
183219

184-
clk = &mockClock{now: time.Unix(now, 0)}
185-
defer func() {
186-
clk = &systemClock{}
187-
}()
188220
for _, tc := range cases {
189221
if _, err := client.VerifyIDToken(tc.token); err == nil {
190-
t.Errorf("VerifyyIDToken(%q) = nil; want error", tc.name)
222+
t.Errorf("VerifyIDToken(%q) = nil; want error", tc.name)
191223
}
192224
}
193225
}
194226

195227
func TestNoProjectID(t *testing.T) {
196-
c, err := NewClient(&internal.AuthConfig{Ctx: context.Background()})
228+
c, err := NewClient(context.Background(), &internal.AuthConfig{})
197229
if err != nil {
198230
t.Fatal(err)
199231
}

auth/crypto.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,10 @@ func (k *httpKeySource) refreshKeys() error {
148148

149149
func findMaxAge(resp *http.Response) (*time.Duration, error) {
150150
cc := resp.Header.Get("cache-control")
151-
for _, value := range strings.Split(cc, ", ") {
151+
for _, value := range strings.Split(cc, ",") {
152152
value = strings.TrimSpace(value)
153-
if strings.HasPrefix(value, "max-age") {
153+
if strings.HasPrefix(value, "max-age=") {
154154
sep := strings.Index(value, "=")
155-
if sep == -1 {
156-
return nil, errors.New("Malformed cache-control header")
157-
}
158155
seconds, err := strconv.ParseInt(value[sep+1:], 10, 64)
159156
if err != nil {
160157
return nil, err

auth/crypto_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package auth
1616

1717
import (
18+
"errors"
1819
"fmt"
1920
"io"
2021
"io/ioutil"
@@ -122,6 +123,122 @@ func TestHTTPKeySourceWithClient(t *testing.T) {
122123
}
123124
}
124125

126+
func TestHTTPKeySourceEmptyResponse(t *testing.T) {
127+
hc, _ := newHTTPClient([]byte(""))
128+
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
129+
if err != nil {
130+
t.Fatal(err)
131+
}
132+
133+
if keys, err := ks.Keys(); keys != nil || err == nil {
134+
t.Errorf("Keys() = (%v, %v); want = (nil, error)", keys, err)
135+
}
136+
}
137+
138+
func TestHTTPKeySourceIncorrectResponse(t *testing.T) {
139+
hc, _ := newHTTPClient([]byte("{\"foo\": 1}"))
140+
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
141+
if err != nil {
142+
t.Fatal(err)
143+
}
144+
145+
if keys, err := ks.Keys(); keys != nil || err == nil {
146+
t.Errorf("Keys() = (%v, %v); want = (nil, error)", keys, err)
147+
}
148+
}
149+
150+
func TestHTTPKeySourceTransportError(t *testing.T) {
151+
hc := &http.Client{
152+
Transport: &mockHTTPResponse{
153+
Err: errors.New("transport error"),
154+
},
155+
}
156+
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
157+
if err != nil {
158+
t.Fatal(err)
159+
}
160+
161+
if keys, err := ks.Keys(); keys != nil || err == nil {
162+
t.Errorf("Keys() = (%v, %v); want = (nil, error)", keys, err)
163+
}
164+
}
165+
166+
func TestFindMaxAge(t *testing.T) {
167+
cases := []struct {
168+
cc string
169+
want int64
170+
}{
171+
{"max-age=100", 100},
172+
{"public, max-age=100", 100},
173+
{"public,max-age=100", 100},
174+
}
175+
for _, tc := range cases {
176+
resp := &http.Response{
177+
Header: http.Header{"Cache-Control": {tc.cc}},
178+
}
179+
age, err := findMaxAge(resp)
180+
if err != nil {
181+
t.Errorf("findMaxAge(%q) = %v", tc.cc, err)
182+
} else if *age != (time.Duration(tc.want) * time.Second) {
183+
t.Errorf("findMaxAge(%q) = %v; want %v", tc.cc, *age, tc.want)
184+
}
185+
}
186+
}
187+
188+
func TestFindMaxAgeError(t *testing.T) {
189+
cases := []string{
190+
"",
191+
"max-age 100",
192+
"max-age: 100",
193+
"max-age2=100",
194+
"max-age=foo",
195+
}
196+
for _, tc := range cases {
197+
resp := &http.Response{
198+
Header: http.Header{"Cache-Control": []string{tc}},
199+
}
200+
if age, err := findMaxAge(resp); age != nil || err == nil {
201+
t.Errorf("findMaxAge(%q) = (%v, %v); want = (nil, err)", tc, age, err)
202+
}
203+
}
204+
}
205+
206+
func TestParsePublicKeys(t *testing.T) {
207+
b, err := ioutil.ReadFile("../testdata/public_certs.json")
208+
if err != nil {
209+
t.Fatal(err)
210+
}
211+
keys, err := parsePublicKeys(b)
212+
if err != nil {
213+
t.Fatal(err)
214+
}
215+
if len(keys) != 3 {
216+
t.Errorf("parsePublicKeys() = %d; want: %d", len(keys), 3)
217+
}
218+
}
219+
220+
func TestParsePublicKeysError(t *testing.T) {
221+
cases := []string{
222+
"",
223+
"not-json",
224+
}
225+
for _, tc := range cases {
226+
if keys, err := parsePublicKeys([]byte(tc)); keys != nil || err == nil {
227+
t.Errorf("parsePublicKeys(%q) = (%v, %v); want: (nil, err)", tc, keys, err)
228+
}
229+
}
230+
}
231+
232+
func TestDefaultServiceAcctSigner(t *testing.T) {
233+
signer := &serviceAcctSigner{}
234+
if email, err := signer.Email(); email != "" || err == nil {
235+
t.Errorf("Email() = (%v, %v); want = ('', error)", email, err)
236+
}
237+
if sig, err := signer.Sign([]byte("")); sig != nil || err == nil {
238+
t.Errorf("Sign() = (%v, %v); want = ('', error)", sig, err)
239+
}
240+
}
241+
125242
func verifyHTTPKeySource(ks *httpKeySource, rc *mockReadCloser) error {
126243
mc := &mockClock{now: time.Unix(0, 0)}
127244
ks.Clock = mc

auth/jwt.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ func decode(s string, i interface{}) error {
8080
if err != nil {
8181
return err
8282
}
83-
if err := json.NewDecoder(bytes.NewBuffer(decoded)).Decode(i); err != nil {
84-
return err
85-
}
86-
return nil
83+
return json.NewDecoder(bytes.NewBuffer(decoded)).Decode(i)
8784
}
8885

8986
func encodeToken(s signer, h jwtHeader, p jwtPayload) (string, error) {

0 commit comments

Comments
 (0)