Skip to content

Commit e4604da

Browse files
authored
Updated API docs (#171)
* Updated API refs; Renamed UserImportRecord to ImportUserRecord * Updated documentation for hash types * Added snippets for import_users() API (#172)
1 parent 4b2e858 commit e4604da

File tree

6 files changed

+328
-29
lines changed

6 files changed

+328
-29
lines changed

firebase_admin/_user_import.py

+111-6
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def b64_encode(bytes_value):
2727
class UserProvider(object):
2828
"""Represents a user identity provider that can be associated with a Firebase user.
2929
30-
One or more providers can be specified in a ``UserImportRecord`` when importing users via
30+
One or more providers can be specified in an ``ImportUserRecord`` when importing users via
3131
``auth.import_users()``.
3232
3333
Args:
@@ -97,10 +97,10 @@ def to_dict(self):
9797
return {k: v for k, v in payload.items() if v is not None}
9898

9999

100-
class UserImportRecord(object):
100+
class ImportUserRecord(object):
101101
"""Represents a user account to be imported to Firebase Auth.
102102
103-
Must specify the ``uid`` field at a minimum. A sequence of ``UserImportRecord`` objects can be
103+
Must specify the ``uid`` field at a minimum. A sequence of ``ImportUserRecord`` objects can be
104104
passed to the ``auth.import_users()`` function, in order to import those users into Firebase
105105
Auth in bulk. If the ``password_hash`` is set on a user, a hash configuration must be
106106
specified when calling ``import_users()``.
@@ -259,7 +259,10 @@ class UserImportHash(object):
259259
"""Represents a hash algorithm used to hash user passwords.
260260
261261
An instance of this class must be specified when importing users with passwords via the
262-
``auth.import_users()`` API.
262+
``auth.import_users()`` API. Use one of the provided class methods to obtain new
263+
instances when required. Refer to `documentation`_ for more details.
264+
265+
.. _documentation: https://firebase.google.com/docs/auth/admin/import-users
263266
"""
264267

265268
def __init__(self, name, data=None):
@@ -298,42 +301,128 @@ def hmac_sha512(cls, key):
298301

299302
@classmethod
300303
def hmac_sha256(cls, key):
304+
"""Creates a new HMAC SHA256 algorithm instance.
305+
306+
Args:
307+
key: Signer key as a byte sequence.
308+
309+
Returns:
310+
UserImportHash: A new ``UserImportHash``.
311+
"""
301312
return cls._hmac('HMAC_SHA256', key)
302313

303314
@classmethod
304315
def hmac_sha1(cls, key):
316+
"""Creates a new HMAC SHA1 algorithm instance.
317+
318+
Args:
319+
key: Signer key as a byte sequence.
320+
321+
Returns:
322+
UserImportHash: A new ``UserImportHash``.
323+
"""
305324
return cls._hmac('HMAC_SHA1', key)
306325

307326
@classmethod
308327
def hmac_md5(cls, key):
328+
"""Creates a new HMAC MD5 algorithm instance.
329+
330+
Args:
331+
key: Signer key as a byte sequence.
332+
333+
Returns:
334+
UserImportHash: A new ``UserImportHash``.
335+
"""
309336
return cls._hmac('HMAC_MD5', key)
310337

311338
@classmethod
312339
def md5(cls, rounds):
340+
"""Creates a new MD5 algorithm instance.
341+
342+
Args:
343+
rounds: Number of rounds. Must be an integer between 0 and 120000.
344+
345+
Returns:
346+
UserImportHash: A new ``UserImportHash``.
347+
"""
313348
return cls._basic_hash('MD5', rounds)
314349

315350
@classmethod
316351
def sha1(cls, rounds):
352+
"""Creates a new SHA1 algorithm instance.
353+
354+
Args:
355+
rounds: Number of rounds. Must be an integer between 0 and 120000.
356+
357+
Returns:
358+
UserImportHash: A new ``UserImportHash``.
359+
"""
317360
return cls._basic_hash('SHA1', rounds)
318361

319362
@classmethod
320363
def sha256(cls, rounds):
364+
"""Creates a new SHA256 algorithm instance.
365+
366+
Args:
367+
rounds: Number of rounds. Must be an integer between 0 and 120000.
368+
369+
Returns:
370+
UserImportHash: A new ``UserImportHash``.
371+
"""
321372
return cls._basic_hash('SHA256', rounds)
322373

323374
@classmethod
324375
def sha512(cls, rounds):
376+
"""Creates a new SHA512 algorithm instance.
377+
378+
Args:
379+
rounds: Number of rounds. Must be an integer between 0 and 120000.
380+
381+
Returns:
382+
UserImportHash: A new ``UserImportHash``.
383+
"""
325384
return cls._basic_hash('SHA512', rounds)
326385

327386
@classmethod
328387
def pbkdf_sha1(cls, rounds):
388+
"""Creates a new PBKDF SHA1 algorithm instance.
389+
390+
Args:
391+
rounds: Number of rounds. Must be an integer between 0 and 120000.
392+
393+
Returns:
394+
UserImportHash: A new ``UserImportHash``.
395+
"""
329396
return cls._basic_hash('PBKDF_SHA1', rounds)
330397

331398
@classmethod
332-
def pbkdf_sha256(cls, rounds):
399+
def pbkdf2_sha256(cls, rounds):
400+
"""Creates a new PBKDF2 SHA256 algorithm instance.
401+
402+
Args:
403+
rounds: Number of rounds. Must be an integer between 0 and 120000.
404+
405+
Returns:
406+
UserImportHash: A new ``UserImportHash``.
407+
"""
333408
return cls._basic_hash('PBKDF2_SHA256', rounds)
334409

335410
@classmethod
336411
def scrypt(cls, key, rounds, memory_cost, salt_separator=None):
412+
"""Creates a new Scrypt algorithm instance.
413+
414+
This is the modified Scrypt algorithm used by Firebase Auth. See ``standard_scrypt()``
415+
function for the standard Scrypt algorith,
416+
417+
Args:
418+
key: Signer key as a byte sequence.
419+
rounds: Number of rounds. Must be an integer between 1 and 8.
420+
memory_cost: Memory cost as an integer between 1 and 14.
421+
salt_separator: Salt separator as a byte sequence (optional).
422+
423+
Returns:
424+
UserImportHash: A new ``UserImportHash``.
425+
"""
337426
data = {
338427
'signerKey': b64_encode(_auth_utils.validate_bytes(key, 'key', required=True)),
339428
'rounds': _auth_utils.validate_int(rounds, 'rounds', 1, 8),
@@ -346,10 +435,26 @@ def scrypt(cls, key, rounds, memory_cost, salt_separator=None):
346435

347436
@classmethod
348437
def bcrypt(cls):
438+
"""Creates a new Bcrypt algorithm instance.
439+
440+
Returns:
441+
UserImportHash: A new ``UserImportHash``.
442+
"""
349443
return UserImportHash('BCRYPT')
350444

351445
@classmethod
352446
def standard_scrypt(cls, memory_cost, parallelization, block_size, derived_key_length):
447+
"""Creates a new standard Scrypt algorithm instance.
448+
449+
Args:
450+
memory_cost: Memory cost as a non-negaive integer.
451+
parallelization: Parallelization as a non-negative integer.
452+
block_size: Block size as a non-negative integer.
453+
derived_key_length: Derived key length as a non-negative integer.
454+
455+
Returns:
456+
UserImportHash: A new ``UserImportHash``.
457+
"""
353458
data = {
354459
'memoryCost': _auth_utils.validate_int(memory_cost, 'memory_cost', low=0),
355460
'parallelization': _auth_utils.validate_int(parallelization, 'parallelization', low=0),
@@ -360,7 +465,7 @@ def standard_scrypt(cls, memory_cost, parallelization, block_size, derived_key_l
360465

361466

362467
class ErrorInfo(object):
363-
"""Represents an error encountered while importing a ``UserImportRecord``."""
468+
"""Represents an error encountered while importing an ``ImportUserRecord``."""
364469

365470
def __init__(self, error):
366471
self._index = error['index']

firebase_admin/_user_mgt.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ def import_users(self, users, hash_alg=None):
518518
raise ValueError(
519519
'Users must be a non-empty list with no more than {0} elements.'.format(
520520
MAX_IMPORT_USERS_SIZE))
521-
if any([not isinstance(u, _user_import.UserImportRecord) for u in users]):
521+
if any([not isinstance(u, _user_import.ImportUserRecord) for u in users]):
522522
raise ValueError('One or more user objects are invalid.')
523523
except TypeError:
524524
raise ValueError('users must be iterable')

firebase_admin/auth.py

+23-2
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939
'AuthError',
4040
'ErrorInfo',
4141
'ExportedUserRecord',
42+
'ImportUserRecord',
4243
'ListUsersPage',
4344
'UserImportHash',
44-
'UserImportRecord',
4545
'UserImportResult',
4646
'UserInfo',
4747
'UserMetadata',
@@ -68,7 +68,7 @@
6868
ExportedUserRecord = _user_mgt.ExportedUserRecord
6969
ListUsersPage = _user_mgt.ListUsersPage
7070
UserImportHash = _user_import.UserImportHash
71-
UserImportRecord = _user_import.UserImportRecord
71+
ImportUserRecord = _user_import.ImportUserRecord
7272
UserImportResult = _user_import.UserImportResult
7373
UserInfo = _user_mgt.UserInfo
7474
UserMetadata = _user_mgt.UserMetadata
@@ -418,6 +418,27 @@ def delete_user(uid, app=None):
418418
raise AuthError(error.code, str(error), error.detail)
419419

420420
def import_users(users, hash_alg=None, app=None):
421+
"""Imports the specified list of users into Firebase Auth.
422+
423+
At most 1000 users can be imported at a time. This operation is optimized for bulk imports and
424+
will ignore checks on identifier uniqueness which could result in duplications. The
425+
``hash_alg`` parameter must be specified when importing users with passwords. Refer to the
426+
``UserImportHash`` class for supported hash algorithms.
427+
428+
Args:
429+
users: A list of ``ImportUserRecord`` instances to import. Length of the list must not
430+
exceed 1000.
431+
hash_alg: A ``UserImportHash`` object (optional). Required when importing users with
432+
passwords.
433+
app: An App instance (optional).
434+
435+
Returns:
436+
UserImportResult: An object summarizing the result of the import operation.
437+
438+
Raises:
439+
ValueError: If the provided arguments are invalid.
440+
AuthError: If an error occurs while importing users.
441+
"""
421442
user_manager = _get_auth_service(app).user_manager
422443
try:
423444
result = user_manager.import_users(users, hash_alg)

integration/test_auth.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def test_verify_session_cookie_revoked(new_user, api_key):
321321

322322
def test_import_users():
323323
uid, email = _random_id()
324-
user = auth.UserImportRecord(uid=uid, email=email)
324+
user = auth.ImportUserRecord(uid=uid, email=email)
325325
result = auth.import_users([user])
326326
try:
327327
assert result.success_count == 1
@@ -335,7 +335,7 @@ def test_import_users_with_password(api_key):
335335
uid, email = _random_id()
336336
password_hash = base64.b64decode(
337337
'V358E8LdWJXAO7muq0CufVpEOXaj8aFiC7T/rcaGieN04q/ZPJ08WhJEHGjj9lz/2TT+/86N5VjVoc5DdBhBiw==')
338-
user = auth.UserImportRecord(
338+
user = auth.ImportUserRecord(
339339
uid=uid, email=email, password_hash=password_hash, password_salt=b'NaCl')
340340

341341
scrypt_key = base64.b64decode(

0 commit comments

Comments
 (0)