-
Notifications
You must be signed in to change notification settings - Fork 339
Add API to look up users by provider user ID. #388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -468,6 +468,24 @@ def get_user(self, **kwargs): | |
elif 'phone_number' in kwargs: | ||
key, key_type = kwargs.pop('phone_number'), 'phone number' | ||
payload = {'phoneNumber' : [_auth_utils.validate_phone(key, required=True)]} | ||
elif 'provider_id' in kwargs and 'provider_uid' in kwargs: | ||
provider_id = kwargs.pop('provider_id') | ||
provider_uid = kwargs.pop('provider_uid') | ||
if provider_id == 'phone': | ||
key, key_type = provider_uid, 'phone number' | ||
payload = {'phoneNumber' : [_auth_utils.validate_phone(key, required=True)]} | ||
elif provider_id == 'password': | ||
key, key_type = provider_uid, 'email' | ||
payload = {'email' : [_auth_utils.validate_email(key, required=True)]} | ||
else: | ||
key, key_type = { | ||
'provider_id': provider_id, 'provider_uid': provider_uid | ||
}, 'provider_user_id' | ||
payload = { | ||
'federated_user_id' : [{ | ||
'provider_id': _auth_utils.validate_provider_id(key['provider_id']), | ||
'raw_id': _auth_utils.validate_provider_id(key['provider_uid'])}] | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional: elif 'provider_id' in kwargs:
raise ValueError('provider_uid keyword argument must be supplied when setting provider_id argument')
elif 'provider_uid' in kwargs:
raise ValueError('provider_id keyword argument must be supplied when setting provider_uid argument') Alternatively, change the elif condition on 471 to be 'or' instead of 'and'. Then, let kwargs.pop throw a KeyError if one of them is missing. You won't get as nice of an error message though, so you may want to catch-and-rethrow at which point, you might be better off with the elif's. |
||
else: | ||
raise TypeError('Unsupported keyword arguments: {0}.'.format(kwargs)) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,7 @@ | |
'get_user', | ||
'get_user_by_email', | ||
'get_user_by_phone_number', | ||
'get_user_by_provider_user_id', | ||
'import_users', | ||
'list_users', | ||
'revoke_refresh_tokens', | ||
|
@@ -308,6 +309,28 @@ def get_user_by_phone_number(phone_number, app=None): | |
response = user_manager.get_user(phone_number=phone_number) | ||
return UserRecord(response) | ||
|
||
def get_user_by_provider_user_id(provider_id, provider_uid, app=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. naming: get_user_by_provider_uid. (A recent change; sorry. :( ) |
||
"""Gets the user data corresponding to the specified provider identifier. | ||
|
||
Args: | ||
provider_id: Identifier for the given provider, for example, | ||
"google.com" for the Google provider. | ||
provider_uid: The user identifier with the given provider. | ||
app: An App instance (optional). | ||
|
||
Returns: | ||
UserRecord: A UserRecord instance. | ||
|
||
Raises: | ||
ValueError: If the given provider identifier is None or empty, or if | ||
the given provider user identifier is None or empty. | ||
UserNotFoundError: If no user exists by the specified identifiers. | ||
FirebaseError: If an error occurs while retrieving the user. | ||
""" | ||
user_manager = _get_auth_service(app).user_manager | ||
response = user_manager.get_user( | ||
provider_id=provider_id, provider_uid=provider_uid) | ||
return UserRecord(response) | ||
|
||
def list_users(page_token=None, max_results=_user_mgt.MAX_LIST_USERS_RESULTS, app=None): | ||
"""Retrieves a page of user accounts from a Firebase project. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -177,6 +177,27 @@ def new_user_with_params(): | |
yield user | ||
auth.delete_user(user.uid) | ||
|
||
@pytest.fixture | ||
def imported_user_with_params(): | ||
random_id, email = _random_id() | ||
phone = _random_phone() | ||
user = auth.ImportUserRecord( | ||
uid=random_id, | ||
email=email, | ||
phone_number=phone, | ||
display_name='Random User', | ||
photo_url='https://example.com/photo.png', | ||
user_metadata=auth.UserMetadata(100, 150), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't figure out what 100,150 were without looking up UserMetadata. Named parameters would make this more obvious, i.e.
Optional. |
||
password_hash=b'password', password_salt=b'NaCl', custom_claims={'admin': True}, | ||
email_verified=True, | ||
disabled=False, | ||
provider_data=[auth.UserProvider(uid='test', provider_id='google.com')]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as before: uid=test might cause this to fail if the test doesn't get properly cleaned up. |
||
hash_alg = auth.UserImportHash.scrypt( | ||
b'key', rounds=8, memory_cost=14, salt_separator=b'sep') | ||
auth.import_users([user], hash_alg=hash_alg) | ||
yield user | ||
auth.delete_user(user.uid) | ||
|
||
@pytest.fixture | ||
def new_user_list(): | ||
users = [ | ||
|
@@ -200,24 +221,33 @@ def new_user_email_unverified(): | |
yield user | ||
auth.delete_user(user.uid) | ||
|
||
def test_get_user(new_user_with_params): | ||
user = auth.get_user(new_user_with_params.uid) | ||
assert user.uid == new_user_with_params.uid | ||
def test_get_user(imported_user_with_params): | ||
user = auth.get_user(imported_user_with_params.uid) | ||
assert user.uid == imported_user_with_params.uid | ||
assert user.display_name == 'Random User' | ||
assert user.email == new_user_with_params.email | ||
assert user.phone_number == new_user_with_params.phone_number | ||
assert user.email == imported_user_with_params.email | ||
assert user.phone_number == imported_user_with_params.phone_number | ||
assert user.photo_url == 'https://example.com/photo.png' | ||
assert user.email_verified is True | ||
assert user.disabled is False | ||
assert len(user.provider_data) == 3 | ||
provider_ids = sorted([provider.provider_id for provider in user.provider_data]) | ||
assert provider_ids == ['google.com', 'password', 'phone'] | ||
|
||
user = auth.get_user_by_email(new_user_with_params.email) | ||
assert user.uid == new_user_with_params.uid | ||
user = auth.get_user_by_phone_number(new_user_with_params.phone_number) | ||
assert user.uid == new_user_with_params.uid | ||
user = auth.get_user_by_email(imported_user_with_params.email) | ||
assert user.uid == imported_user_with_params.uid | ||
|
||
assert len(user.provider_data) == 2 | ||
provider_ids = sorted([provider.provider_id for provider in user.provider_data]) | ||
assert provider_ids == ['password', 'phone'] | ||
user = auth.get_user_by_phone_number(imported_user_with_params.phone_number) | ||
assert user.uid == imported_user_with_params.uid | ||
|
||
user = auth.get_user_by_provider_user_id('phone', imported_user_with_params.phone_number) | ||
assert user.uid == imported_user_with_params.uid | ||
|
||
user = auth.get_user_by_provider_user_id('password', imported_user_with_params.email) | ||
assert user.uid == imported_user_with_params.uid | ||
|
||
user = auth.get_user_by_provider_user_id('google.com', 'test') | ||
assert user.uid == imported_user_with_params.uid | ||
|
||
def test_list_users(new_user_list): | ||
err_msg_template = ( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double check the spelling in the json payload. Normally, the json part needs to be camelCase. (i.e. like 470). But maybe the backend accepts both?