Skip to content

Commit 27160ef

Browse files
authored
Import Users API for auth.Client (#146)
* Added hmac sha512 hash type * Updated changelog * Added basic integration test * Added integration test for import with password * Minor clean up * Using non-pointer type for hash implementations; other code clean up changes
1 parent f1c488b commit 27160ef

File tree

8 files changed

+1279
-6
lines changed

8 files changed

+1279
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Unreleased
22

3+
- [added] Implemented the `auth.ImportUsers()` function for importing
4+
users into Firebase Auth in bulk.
5+
36
# v3.0.0
47

58
- All functions that make network calls now take context as an argument.

auth/hash/hash.go

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// Copyright 2018 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package hash contains a collection of password hash algorithms that can be used with the
16+
// auth.ImportUsers() API. Refer to https://firebase.google.com/docs/auth/admin/import-users for
17+
// more details about supported hash algorithms.
18+
package hash // import "firebase.google.com/go/auth/hash"
19+
20+
import (
21+
"encoding/base64"
22+
"errors"
23+
24+
"firebase.google.com/go/internal"
25+
)
26+
27+
// Bcrypt represents the BCRYPT hash algorithm.
28+
//
29+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_bcrypt_hashed_passwords
30+
// for more details.
31+
type Bcrypt struct{}
32+
33+
// Config returns the validated hash configuration.
34+
func (b Bcrypt) Config() (*internal.HashConfig, error) {
35+
return &internal.HashConfig{HashAlgorithm: "BCRYPT"}, nil
36+
}
37+
38+
// StandardScrypt represents the standard scrypt hash algorithm.
39+
//
40+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_standard_scrypt_hashed_passwords
41+
// for more details.
42+
type StandardScrypt struct {
43+
BlockSize int
44+
DerivedKeyLength int
45+
MemoryCost int
46+
Parallelization int
47+
}
48+
49+
// Config returns the validated hash configuration.
50+
func (s StandardScrypt) Config() (*internal.HashConfig, error) {
51+
return &internal.HashConfig{
52+
HashAlgorithm: "STANDARD_SCRYPT",
53+
DerivedKeyLength: int64(s.DerivedKeyLength),
54+
BlockSize: int64(s.BlockSize),
55+
Parallelization: int64(s.Parallelization),
56+
MemoryCost: int64(s.MemoryCost),
57+
ForceSendFields: []string{"BlockSize", "Parallelization", "MemoryCost", "DkLen"},
58+
}, nil
59+
}
60+
61+
// Scrypt represents the scrypt hash algorithm.
62+
//
63+
// This is the modified scrypt used by Firebase Auth (https://github.com/firebase/scrypt).
64+
// Rounds must be between 1 and 8, and the MemoryCost must be between 1 and 14. Key is required.
65+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_firebase_scrypt_hashed_passwords
66+
// for more details.
67+
type Scrypt struct {
68+
Key []byte
69+
SaltSeparator []byte
70+
Rounds int
71+
MemoryCost int
72+
}
73+
74+
// Config returns the validated hash configuration.
75+
func (s Scrypt) Config() (*internal.HashConfig, error) {
76+
if len(s.Key) == 0 {
77+
return nil, errors.New("signer key not specified")
78+
}
79+
if s.Rounds < 1 || s.Rounds > 8 {
80+
return nil, errors.New("rounds must be between 1 and 8")
81+
}
82+
if s.MemoryCost < 1 || s.MemoryCost > 14 {
83+
return nil, errors.New("memory cost must be between 1 and 14")
84+
}
85+
return &internal.HashConfig{
86+
HashAlgorithm: "SCRYPT",
87+
SignerKey: base64.RawURLEncoding.EncodeToString(s.Key),
88+
SaltSeparator: base64.RawURLEncoding.EncodeToString(s.SaltSeparator),
89+
Rounds: int64(s.Rounds),
90+
MemoryCost: int64(s.MemoryCost),
91+
}, nil
92+
}
93+
94+
// HMACMD5 represents the HMAC SHA512 hash algorithm.
95+
//
96+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_hmac_hashed_passwords
97+
// for more details. Key is required.
98+
type HMACMD5 struct {
99+
Key []byte
100+
}
101+
102+
// Config returns the validated hash configuration.
103+
func (h HMACMD5) Config() (*internal.HashConfig, error) {
104+
return hmacConfig("HMAC_MD5", h.Key)
105+
}
106+
107+
// HMACSHA1 represents the HMAC SHA512 hash algorithm.
108+
//
109+
// Key is required.
110+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_hmac_hashed_passwords
111+
// for more details.
112+
type HMACSHA1 struct {
113+
Key []byte
114+
}
115+
116+
// Config returns the validated hash configuration.
117+
func (h HMACSHA1) Config() (*internal.HashConfig, error) {
118+
return hmacConfig("HMAC_SHA1", h.Key)
119+
}
120+
121+
// HMACSHA256 represents the HMAC SHA512 hash algorithm.
122+
//
123+
// Key is required.
124+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_hmac_hashed_passwords
125+
// for more details.
126+
type HMACSHA256 struct {
127+
Key []byte
128+
}
129+
130+
// Config returns the validated hash configuration.
131+
func (h HMACSHA256) Config() (*internal.HashConfig, error) {
132+
return hmacConfig("HMAC_SHA256", h.Key)
133+
}
134+
135+
// HMACSHA512 represents the HMAC SHA512 hash algorithm.
136+
//
137+
// Key is required.
138+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_hmac_hashed_passwords
139+
// for more details.
140+
type HMACSHA512 struct {
141+
Key []byte
142+
}
143+
144+
// Config returns the validated hash configuration.
145+
func (h HMACSHA512) Config() (*internal.HashConfig, error) {
146+
return hmacConfig("HMAC_SHA512", h.Key)
147+
}
148+
149+
// MD5 represents the MD5 hash algorithm.
150+
//
151+
// Rounds must be between 0 and 120000.
152+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_md5_sha_and_pbkdf_hashed_passwords
153+
// for more details.
154+
type MD5 struct {
155+
Rounds int
156+
}
157+
158+
// Config returns the validated hash configuration.
159+
func (h MD5) Config() (*internal.HashConfig, error) {
160+
return basicConfig("MD5", h.Rounds)
161+
}
162+
163+
// PBKDF2SHA256 represents the PBKDF2SHA256 hash algorithm.
164+
//
165+
// Rounds must be between 0 and 120000.
166+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_md5_sha_and_pbkdf_hashed_passwords
167+
// for more details.
168+
type PBKDF2SHA256 struct {
169+
Rounds int
170+
}
171+
172+
// Config returns the validated hash configuration.
173+
func (h PBKDF2SHA256) Config() (*internal.HashConfig, error) {
174+
return basicConfig("PBKDF2_SHA256", h.Rounds)
175+
}
176+
177+
// PBKDFSHA1 represents the PBKDFSHA1 hash algorithm.
178+
//
179+
// Rounds must be between 0 and 120000.
180+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_md5_sha_and_pbkdf_hashed_passwords
181+
// for more details.
182+
type PBKDFSHA1 struct {
183+
Rounds int
184+
}
185+
186+
// Config returns the validated hash configuration.
187+
func (h PBKDFSHA1) Config() (*internal.HashConfig, error) {
188+
return basicConfig("PBKDF_SHA1", h.Rounds)
189+
}
190+
191+
// SHA1 represents the SHA1 hash algorithm.
192+
//
193+
// Rounds must be between 0 and 120000.
194+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_md5_sha_and_pbkdf_hashed_passwords
195+
// for more details.
196+
type SHA1 struct {
197+
Rounds int
198+
}
199+
200+
// Config returns the validated hash configuration.
201+
func (h SHA1) Config() (*internal.HashConfig, error) {
202+
return basicConfig("SHA1", h.Rounds)
203+
}
204+
205+
// SHA256 represents the SHA256 hash algorithm.
206+
//
207+
// Rounds must be between 0 and 120000.
208+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_md5_sha_and_pbkdf_hashed_passwords
209+
// for more details.
210+
type SHA256 struct {
211+
Rounds int
212+
}
213+
214+
// Config returns the validated hash configuration.
215+
func (h SHA256) Config() (*internal.HashConfig, error) {
216+
return basicConfig("SHA256", h.Rounds)
217+
}
218+
219+
// SHA512 represents the SHA512 hash algorithm.
220+
//
221+
// Rounds must be between 0 and 120000.
222+
// Refer to https://firebase.google.com/docs/auth/admin/import-users#import_users_with_md5_sha_and_pbkdf_hashed_passwords
223+
// for more details.
224+
type SHA512 struct {
225+
Rounds int
226+
}
227+
228+
// Config returns the validated hash configuration.
229+
func (h SHA512) Config() (*internal.HashConfig, error) {
230+
return basicConfig("SHA512", h.Rounds)
231+
}
232+
233+
func hmacConfig(name string, key []byte) (*internal.HashConfig, error) {
234+
if len(key) == 0 {
235+
return nil, errors.New("signer key not specified")
236+
}
237+
return &internal.HashConfig{
238+
HashAlgorithm: name,
239+
SignerKey: base64.RawURLEncoding.EncodeToString(key),
240+
}, nil
241+
}
242+
243+
func basicConfig(name string, rounds int) (*internal.HashConfig, error) {
244+
if rounds < 0 || rounds > 120000 {
245+
return nil, errors.New("rounds must be between 0 and 120000")
246+
}
247+
return &internal.HashConfig{
248+
HashAlgorithm: name,
249+
Rounds: int64(rounds),
250+
ForceSendFields: []string{"Rounds"},
251+
}, nil
252+
}

0 commit comments

Comments
 (0)