Skip to content

Commit

Permalink
Release 2.2.0 (#48)
Browse files Browse the repository at this point in the history
* 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)
  • Loading branch information
avishalom authored and hiranya911 committed Dec 8, 2017
1 parent edbe442 commit ad5322b
Show file tree
Hide file tree
Showing 15 changed files with 1,831 additions and 56 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
testdata/integration_*
.vscode/*
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ We get lots of those and we love helping you, but GitHub is not the best place f
which just ask about usage will be closed. Here are some resources to get help:

- Go through the [guides](https://firebase.google.com/docs/admin/setup/)
- Read the full [API reference](https://firebase.google.com/docs/reference/admin/go/)
- Read the full [API reference](https://godoc.org/firebase.google.com/go)

If the official documentation doesn't help, try asking a question on the
[Firebase Google Group](https://groups.google.com/forum/#!forum/firebase-talk/) or one of our
Expand Down Expand Up @@ -122,8 +122,8 @@ do not already have one suitable for running the tests against. Then obtain the
following credentials from the project:

1. *Service account certificate*: This can be downloaded as a JSON file from
the "Settings > Service Accounts" tab of the Firebase console. Copy the
file into your Go workspace as
the "Settings > Service Accounts" tab of the Firebase console. Click
"GENERATE NEW PRIVATE KEY" and copy the file into your Go workspace as
`src/firebase.google.com/go/testdata/integration_cert.json`.
2. *Web API key*: This is displayed in the "Settings > General" tab of the
console. Copy it and save to a new text file. Copy this text file into
Expand Down
31 changes: 29 additions & 2 deletions auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ import (
"encoding/pem"
"errors"
"fmt"
"net/http"
"strings"

"firebase.google.com/go/internal"
"golang.org/x/net/context"
"google.golang.org/api/transport"
)

const firebaseAudience = "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
const googleCertURL = "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com"
const idToolKitURL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/"
const issuerPrefix = "https://securetoken.google.com/"
const tokenExpSeconds = 3600

Expand Down Expand Up @@ -60,9 +63,11 @@ type Token struct {
// Client facilitates generating custom JWT tokens for Firebase clients, and verifying ID tokens issued
// by Firebase backend services.
type Client struct {
hc *internal.HTTPClient
ks keySource
projectID string
snr signer
url string
}

type signer interface {
Expand Down Expand Up @@ -105,19 +110,41 @@ func NewClient(ctx context.Context, c *internal.AuthConfig) (*Client, error) {
return nil, err
}
}

ks, err := newHTTPKeySource(ctx, googleCertURL, c.Opts...)
hc := http.DefaultClient
if len(c.Opts) > 0 { // TODO: fix the default when len = 0
hc, _, err = transport.NewHTTPClient(ctx, c.Opts...)
if err != nil {
return nil, err
}
}
ks, err := newHTTPKeySource(googleCertURL, hc)
if err != nil {
return nil, err
}

return &Client{
hc: &internal.HTTPClient{Client: hc},
ks: ks,
projectID: c.ProjectID,
snr: snr,
url: idToolKitURL,
}, nil
}

// Passes the request struct, returns a byte array of the json
func (c *Client) makeHTTPCall(ctx context.Context, serviceName string, payload interface{}, result interface{}) error {
request := &internal.Request{
Method: "POST",
URL: c.url + serviceName,
Body: internal.NewJSONEntity(payload),
}
resp, err := c.hc.Do(ctx, request)
if err != nil {
return err
}
return resp.Unmarshal(200, result)
}

// CustomToken creates a signed custom authentication token with the specified user ID. The resulting
// JWT can be used in a Firebase client SDK to trigger an authentication flow. See
// https://firebase.google.com/docs/auth/admin/create-custom-tokens#sign_in_using_custom_tokens_on_clients
Expand Down
26 changes: 19 additions & 7 deletions auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import (

var client *Client
var testIDToken string
var testGetUserResponse []byte
var testListUsersResponse []byte

func TestMain(m *testing.M) {
var (
Expand All @@ -46,7 +48,6 @@ func TestMain(m *testing.M) {
ctx context.Context
creds *google.DefaultCredentials
)

if appengine.IsDevAppServer() {
aectx, aedone, err := aetest.NewContext()
if err != nil {
Expand All @@ -61,23 +62,34 @@ func TestMain(m *testing.M) {
}
} else {
ctx = context.Background()
creds, err = transport.Creds(ctx, option.WithCredentialsFile("../testdata/service_account.json"))
opt := option.WithCredentialsFile("../testdata/service_account.json")
creds, err = transport.Creds(ctx, opt)
if err != nil {
log.Fatalln(err)
}

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

client, err = NewClient(ctx, &internal.AuthConfig{
Creds: creds,
Opts: []option.ClientOption{option.WithCredentialsFile("../testdata/service_account.json")},
ProjectID: "mock-project-id",
})
if err != nil {
log.Fatalln(err)
}
client.ks = ks

testGetUserResponse, err = ioutil.ReadFile("../testdata/get_user.json")
if err != nil {
log.Fatalln(err)
}

testListUsersResponse, err = ioutil.ReadFile("../testdata/list_users.json")
if err != nil {
log.Fatalln(err)
}

testIDToken = getIDToken(nil)
os.Exit(m.Run())
}
Expand All @@ -88,7 +100,7 @@ func TestNewClientInvalidCredentials(t *testing.T) {
}
conf := &internal.AuthConfig{Creds: creds}
if c, err := NewClient(context.Background(), conf); c != nil || err == nil {
t.Errorf("NewCient() = (%v,%v); want = (nil, error)", c, err)
t.Errorf("NewClient() = (%v,%v); want = (nil, error)", c, err)
}
}

Expand All @@ -104,7 +116,7 @@ func TestNewClientInvalidPrivateKey(t *testing.T) {
creds := &google.DefaultCredentials{JSON: b}
conf := &internal.AuthConfig{Creds: creds}
if c, err := NewClient(context.Background(), conf); c != nil || err == nil {
t.Errorf("NewCient() = (%v,%v); want = (nil, error)", c, err)
t.Errorf("NewClient() = (%v,%v); want = (nil, error)", c, err)
}
}

Expand Down Expand Up @@ -325,8 +337,8 @@ type mockKeySource struct {
err error
}

func (t *mockKeySource) Keys() ([]*publicKey, error) {
return t.keys, t.err
func (k *mockKeySource) Keys() ([]*publicKey, error) {
return k.keys, k.err
}

// fileKeySource loads a set of public keys from the local file system.
Expand Down
18 changes: 1 addition & 17 deletions auth/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ import (
"strings"
"sync"
"time"

"golang.org/x/net/context"

"google.golang.org/api/option"
"google.golang.org/api/transport"
)

// publicKey represents a parsed RSA public key along with its unique key ID.
Expand Down Expand Up @@ -80,18 +75,7 @@ type httpKeySource struct {
Mutex *sync.Mutex
}

func newHTTPKeySource(ctx context.Context, uri string, opts ...option.ClientOption) (*httpKeySource, error) {
var hc *http.Client
if ctx != nil && len(opts) > 0 {
var err error
hc, _, err = transport.NewHTTPClient(ctx, opts...)
if err != nil {
return nil, err
}
} else {
hc = http.DefaultClient
}

func newHTTPKeySource(uri string, hc *http.Client) (*httpKeySource, error) {
return &httpKeySource{
KeyURI: uri,
HTTPClient: hc,
Expand Down
25 changes: 10 additions & 15 deletions auth/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ import (
"net/http"
"testing"
"time"

"golang.org/x/net/context"

"google.golang.org/api/option"
)

type mockHTTPResponse struct {
Expand All @@ -43,7 +39,7 @@ type mockReadCloser struct {
closeCount int
}

func newHTTPClient(data []byte) (*http.Client, *mockReadCloser) {
func newTestHTTPClient(data []byte) (*http.Client, *mockReadCloser) {
rc := &mockReadCloser{
data: string(data),
closeCount: 0,
Expand Down Expand Up @@ -87,16 +83,15 @@ func TestHTTPKeySource(t *testing.T) {
if err != nil {
t.Fatal(err)
}

ks, err := newHTTPKeySource(context.Background(), "http://mock.url")
ks, err := newHTTPKeySource("http://mock.url", http.DefaultClient)
if err != nil {
t.Fatal(err)
}

if ks.HTTPClient == nil {
t.Errorf("HTTPClient = nil; want non-nil")
}
hc, rc := newHTTPClient(data)
hc, rc := newTestHTTPClient(data)
ks.HTTPClient = hc
if err := verifyHTTPKeySource(ks, rc); err != nil {
t.Fatal(err)
Expand All @@ -109,8 +104,8 @@ func TestHTTPKeySourceWithClient(t *testing.T) {
t.Fatal(err)
}

hc, rc := newHTTPClient(data)
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
hc, rc := newTestHTTPClient(data)
ks, err := newHTTPKeySource("http://mock.url", hc)
if err != nil {
t.Fatal(err)
}
Expand All @@ -124,8 +119,8 @@ func TestHTTPKeySourceWithClient(t *testing.T) {
}

func TestHTTPKeySourceEmptyResponse(t *testing.T) {
hc, _ := newHTTPClient([]byte(""))
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
hc, _ := newTestHTTPClient([]byte(""))
ks, err := newHTTPKeySource("http://mock.url", hc)
if err != nil {
t.Fatal(err)
}
Expand All @@ -136,8 +131,8 @@ func TestHTTPKeySourceEmptyResponse(t *testing.T) {
}

func TestHTTPKeySourceIncorrectResponse(t *testing.T) {
hc, _ := newHTTPClient([]byte("{\"foo\": 1}"))
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
hc, _ := newTestHTTPClient([]byte("{\"foo\": 1}"))
ks, err := newHTTPKeySource("http://mock.url", hc)
if err != nil {
t.Fatal(err)
}
Expand All @@ -153,7 +148,7 @@ func TestHTTPKeySourceTransportError(t *testing.T) {
Err: errors.New("transport error"),
},
}
ks, err := newHTTPKeySource(context.Background(), "http://mock.url", option.WithHTTPClient(hc))
ks, err := newHTTPKeySource("http://mock.url", hc)
if err != nil {
t.Fatal(err)
}
Expand Down
Loading

0 comments on commit ad5322b

Please sign in to comment.