Skip to content

Commit 027e651

Browse files
authored
Release 1.0.2 (#23)
* Enabling the use of App Engine's SignBytes, ServiceAccount and PublicCertificates (#18) * 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) * adding native app engine support via build tags * missing files * adding ability to use standard signer locally with GAE * allowing for std signer on GAE production env, fixing opts check * fixing env var name * removing test log * giving the key source the same treatment as the signer * missing files * removing unneeded build tag * code review feedback * missing file * adjusting constructor per review feedback * file rename per feedback * reverting more changes * review feedback, fixing test * Documentation update (#19) * 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) * Removed unused package variable; Updated godocs * Minor refactoring of test code (#20) * 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) * Moved integration/auth_test.go to its own package. Moved fileKeySource to auth_test.go * Testing for iss and sub headers of custom tokens * Bumped version to 1.0.2 (#21) * 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) * Bumped version to 1.0.2wq
1 parent a787b7a commit 027e651

File tree

9 files changed

+320
-142
lines changed

9 files changed

+320
-142
lines changed

auth/auth.go

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@
1616
package auth
1717

1818
import (
19+
"crypto/rsa"
20+
"crypto/x509"
1921
"encoding/json"
2022
"encoding/pem"
2123
"errors"
2224
"fmt"
2325
"strings"
2426

25-
"crypto/rsa"
26-
"crypto/x509"
27-
2827
"firebase.google.com/go/internal"
2928
)
3029

@@ -62,45 +61,60 @@ type Token struct {
6261
type Client struct {
6362
ks keySource
6463
projectID string
65-
email string
66-
pk *rsa.PrivateKey
64+
snr signer
65+
}
66+
67+
type signer interface {
68+
Email() (string, error)
69+
Sign(b []byte) ([]byte, error)
6770
}
6871

6972
// NewClient creates a new instance of the Firebase Auth Client.
7073
//
7174
// This function can only be invoked from within the SDK. Client applications should access the
7275
// the Auth service through firebase.App.
7376
func NewClient(c *internal.AuthConfig) (*Client, error) {
77+
var (
78+
err error
79+
email string
80+
pk *rsa.PrivateKey
81+
)
82+
if c.Creds != nil && len(c.Creds.JSON) > 0 {
83+
var svcAcct struct {
84+
ClientEmail string `json:"client_email"`
85+
PrivateKey string `json:"private_key"`
86+
}
87+
if err := json.Unmarshal(c.Creds.JSON, &svcAcct); err != nil {
88+
return nil, err
89+
}
90+
if svcAcct.PrivateKey != "" {
91+
pk, err = parseKey(svcAcct.PrivateKey)
92+
if err != nil {
93+
return nil, err
94+
}
95+
}
96+
email = svcAcct.ClientEmail
97+
}
98+
var snr signer
99+
if email != "" && pk != nil {
100+
snr = serviceAcctSigner{email: email, pk: pk}
101+
} else {
102+
snr, err = newSigner(c.Ctx)
103+
if err != nil {
104+
return nil, err
105+
}
106+
}
107+
74108
ks, err := newHTTPKeySource(c.Ctx, googleCertURL, c.Opts...)
75109
if err != nil {
76110
return nil, err
77111
}
78112

79-
client := &Client{
113+
return &Client{
80114
ks: ks,
81115
projectID: c.ProjectID,
82-
}
83-
if c.Creds == nil || len(c.Creds.JSON) == 0 {
84-
return client, nil
85-
}
86-
87-
var svcAcct struct {
88-
ClientEmail string `json:"client_email"`
89-
PrivateKey string `json:"private_key"`
90-
}
91-
if err := json.Unmarshal(c.Creds.JSON, &svcAcct); err != nil {
92-
return nil, err
93-
}
94-
95-
if svcAcct.PrivateKey != "" {
96-
pk, err := parseKey(svcAcct.PrivateKey)
97-
if err != nil {
98-
return nil, err
99-
}
100-
client.pk = pk
101-
}
102-
client.email = svcAcct.ClientEmail
103-
return client, nil
116+
snr: snr,
117+
}, nil
104118
}
105119

106120
// CustomToken creates a signed custom authentication token with the specified user ID. The resulting
@@ -114,11 +128,9 @@ func (c *Client) CustomToken(uid string) (string, error) {
114128
// CustomTokenWithClaims is similar to CustomToken, but in addition to the user ID, it also encodes
115129
// all the key-value pairs in the provided map as claims in the resulting JWT.
116130
func (c *Client) CustomTokenWithClaims(uid string, devClaims map[string]interface{}) (string, error) {
117-
if c.email == "" {
118-
return "", errors.New("service account email not available")
119-
}
120-
if c.pk == nil {
121-
return "", errors.New("private key not available")
131+
iss, err := c.snr.Email()
132+
if err != nil {
133+
return "", err
122134
}
123135

124136
if len(uid) == 0 || len(uid) > 128 {
@@ -139,15 +151,15 @@ func (c *Client) CustomTokenWithClaims(uid string, devClaims map[string]interfac
139151

140152
now := clk.Now().Unix()
141153
payload := &customToken{
142-
Iss: c.email,
143-
Sub: c.email,
154+
Iss: iss,
155+
Sub: iss,
144156
Aud: firebaseAudience,
145157
UID: uid,
146158
Iat: now,
147159
Exp: now + tokenExpSeconds,
148160
Claims: devClaims,
149161
}
150-
return encodeToken(defaultHeader(), payload, c.pk)
162+
return encodeToken(c.snr, defaultHeader(), payload)
151163
}
152164

153165
// VerifyIDToken verifies the signature and payload of the provided ID token.

auth/auth_appengine.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// +build appengine
2+
3+
// Copyright 2017 Google Inc. All Rights Reserved.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package auth
18+
19+
import (
20+
"golang.org/x/net/context"
21+
22+
"google.golang.org/appengine"
23+
)
24+
25+
type aeSigner struct {
26+
ctx context.Context
27+
}
28+
29+
func newSigner(ctx context.Context) (signer, error) {
30+
return aeSigner{ctx}, nil
31+
}
32+
33+
func (s aeSigner) Email() (string, error) {
34+
return appengine.ServiceAccount(s.ctx)
35+
}
36+
37+
func (s aeSigner) Sign(ss []byte) ([]byte, error) {
38+
_, sig, err := appengine.SignBytes(s.ctx, ss)
39+
return sig, err
40+
}

auth/auth_std.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// +build !appengine
2+
3+
// Copyright 2017 Google Inc. All Rights Reserved.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package auth
18+
19+
import "context"
20+
21+
func newSigner(ctx context.Context) (signer, error) {
22+
return serviceAcctSigner{}, nil
23+
}

0 commit comments

Comments
 (0)