U
    
ڲgD                     @   sV  d Z ddlZddlmZ ddlZddlmZ ddlZddlm	Z	 ddlm
Z
 ddlmZ ddlmZ dd	lmZ d
Zd
ZedZG dd dZedZG dd dZG dd dZG dd deZG dd deZG dd dZG dd dZG dd dZG dd dZG dd  d eZG d!d" d"Zd#d$ ZG d%d& d&Z G d'd( d(e	j!Z"dS ))z$Firebase user management sub module.    N)defaultdict)parse)_auth_utils)_rfc3339)_user_identifier)_user_import	ErrorInfo  s   REDACTEDc                   @   s   e Zd Zdd ZdS )Sentinelc                 C   s
   || _ d S N)description)selfr    r   </tmp/pip-unpacked-wheel-p0r7i5ii/firebase_admin/_user_mgt.py__init__&   s    zSentinel.__init__N)__name__
__module____qualname__r   r   r   r   r   r   $   s   r   z5Value used to delete an attribute from a user profilec                   @   s>   e Zd ZdZdddZedd Zedd Zed	d
 ZdS )UserMetadataz<Contains additional metadata associated with a user account.Nc                 C   s.   t |d| _t |d| _t |d| _d S )Ncreation_timestamplast_sign_in_timestamplast_refresh_timestamp)r   validate_timestamp_creation_timestamp_last_sign_in_timestamp_last_refresh_timestamp)r   r   r   r   r   r   r   r   0   s       zUserMetadata.__init__c                 C   s   | j S )z Creation timestamp in milliseconds since the epoch.

        Returns:
          integer: The user creation timestamp in milliseconds since the epoch.
        )r   r   r   r   r   r   9   s    zUserMetadata.creation_timestampc                 C   s   | j S )z Last sign in timestamp in milliseconds since the epoch.

        Returns:
          integer: The last sign in timestamp in milliseconds since the epoch.
        )r   r   r   r   r   r   B   s    z#UserMetadata.last_sign_in_timestampc                 C   s   | j S )zThe time at which the user was last active (ID token refreshed).

        Returns:
          integer: Milliseconds since epoch timestamp, or `None` if the user was
          never active.
        )r   r   r   r   r   r   K   s    z#UserMetadata.last_refresh_timestamp)NNN)	r   r   r   __doc__r   propertyr   r   r   r   r   r   r   r   -   s     
	

r   c                   @   sX   e Zd ZdZedd Zedd Zedd Zedd	 Zed
d Z	edd Z
dS )UserInfozA collection of standard profile information for a user.

    Used to expose profile information returned by an identity provider.
    c                 C   s   t dS )z!Returns the user ID of this user.NNotImplementedErrorr   r   r   r   uid\   s    zUserInfo.uidc                 C   s   t dS )z&Returns the display name of this user.Nr!   r   r   r   r   display_namea   s    zUserInfo.display_namec                 C   s   t dS )z4Returns the email address associated with this user.Nr!   r   r   r   r   emailf   s    zUserInfo.emailc                 C   s   t dS )z3Returns the phone number associated with this user.Nr!   r   r   r   r   phone_numberk   s    zUserInfo.phone_numberc                 C   s   t dS )z#Returns the photo URL of this user.Nr!   r   r   r   r   	photo_urlp   s    zUserInfo.photo_urlc                 C   s   t dS )zReturns the ID of the identity provider.

        This can be a short domain name (e.g. google.com), or the identity of an OpenID
        identity provider.
        Nr!   r   r   r   r   provider_idu   s    zUserInfo.provider_idN)r   r   r   r   r   r#   r$   r%   r&   r'   r(   r   r   r   r   r    V   s   




r    c                       s   e Zd ZdZ fddZedd Zedd Zedd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Z  ZS )
UserRecordz:Contains metadata associated with a Firebase user account.c                    sB   t t|   t|ts&td||ds8td|| _d S )N1Invalid data argument: {0}. Must be a dictionary.localId"User ID must not be None or empty.)	superr)   r   
isinstancedict
ValueErrorformatget_datar   data	__class__r   r   r      s    

zUserRecord.__init__c                 C   s   | j dS )zReturns the user ID of this user.

        Returns:
          string: A user ID string. This value is never None or empty.
        r+   r3   r2   r   r   r   r   r#      s    zUserRecord.uidc                 C   s   | j dS )zrReturns the display name of this user.

        Returns:
          string: A display name string or None.
        displayNamer8   r   r   r   r   r$      s    zUserRecord.display_namec                 C   s   | j dS )zReturns the email address associated with this user.

        Returns:
          string: An email address string or None.
        r%   r8   r   r   r   r   r%      s    zUserRecord.emailc                 C   s   | j dS )zReturns the phone number associated with this user.

        Returns:
          string: A phone number string or None.
        phoneNumberr8   r   r   r   r   r&      s    zUserRecord.phone_numberc                 C   s   | j dS )zfReturns the photo URL of this user.

        Returns:
          string: A URL string or None.
        photoUrlr8   r   r   r   r   r'      s    zUserRecord.photo_urlc                 C   s   dS )zpReturns the provider ID of this user.

        Returns:
          string: A constant provider ID value.
        Zfirebaser   r   r   r   r   r(      s    zUserRecord.provider_idc                 C   s   t | jdS )zReturns whether the email address of this user has been verified.

        Returns:
          bool: True if the email has been verified, and False otherwise.
        emailVerifiedboolr3   r2   r   r   r   r   email_verified   s    zUserRecord.email_verifiedc                 C   s   t | jdS )zReturns whether this user account is disabled.

        Returns:
          bool: True if the user account is disabled, and False otherwise.
        disabledr=   r   r   r   r   r@      s    zUserRecord.disabledc                 C   s$   | j d}|dk	r dt| S dS )aA  Returns the time, in milliseconds since the epoch, before which tokens are invalid.

        Note: this is truncated to 1 second accuracy.

        Returns:
            int: Timestamp in milliseconds since the epoch, truncated to the second.
            All tokens issued before that time are considered revoked.
        
validSinceNr
   r   )r3   r2   int)r   valid_sincer   r   r   tokens_valid_after_timestamp   s    
z'UserRecord.tokens_valid_after_timestampc                    sH    fdd}d} j dd}|r4tt|d }t|d|d|S )zReturns additional metadata associated with this user.

        Returns:
          UserMetadata: A UserMetadata instance. Does not return None.
        c                    s   |  j krt j |  S d S r   )r3   rB   )keyr   r   r   _int_or_none   s    
z.UserRecord.user_metadata.<locals>._int_or_noneNZlastRefreshAtr
   Z	createdAtZlastLoginAt)r3   r2   rB   r   Zparse_to_epochr   )r   rF   Zlast_refresh_at_millisZlast_refresh_at_rfc3339r   r   r   user_metadata   s      zUserRecord.user_metadatac                 C   s   | j dg }dd |D S )zReturns a list of UserInfo instances.

        Each object represents an identity from an identity provider that is linked to this user.

        Returns:
          list: A list of UserInfo objects, which may be empty.
        ZproviderUserInfoc                 S   s   g | ]}t |qS r   )ProviderUserInfo).0entryr   r   r   
<listcomp>   s     z,UserRecord.provider_data.<locals>.<listcomp>r8   )r   Z	providersr   r   r   provider_data   s    	zUserRecord.provider_datac                 C   s*   | j d}|r&t|}|i kr&|S dS )z~Returns any custom claims set on this user account.

        Returns:
          dict: A dictionary of claims or None.
        customAttributesN)r3   r2   jsonloads)r   Zclaimsparsedr   r   r   custom_claims   s    
zUserRecord.custom_claimsc                 C   s   | j dS )zlReturns the tenant ID of this user.

        Returns:
          string: A tenant ID string or None.
        ZtenantIdr8   r   r   r   r   	tenant_id  s    zUserRecord.tenant_id)r   r   r   r   r   r   r#   r$   r%   r&   r'   r(   r?   r@   rD   rG   rL   rQ   rR   __classcell__r   r   r6   r   r)      s8   











r)   c                   @   s(   e Zd ZdZedd Zedd ZdS )ExportedUserRecordzJContains metadata associated with a user including password hash and salt.c                 C   s   | j d}|tkrdS |S )a  The user's password hash as a base64-encoded string.

        If the Firebase Auth hashing algorithm (SCRYPT) was used to create the user account, this
        is the base64-encoded password hash of the user. If a different hashing algorithm was
        used to create this user, as is typical when migrating from another Auth system, this
        is an empty string. If no password is set, or if the service account doesn't have permission
        to read the password, then this is ``None``.
        passwordHashN)r3   r2   B64_REDACTED)r   password_hashr   r   r   rW     s    
z ExportedUserRecord.password_hashc                 C   s   | j dS )a  The user's password salt as a base64-encoded string.

        If the Firebase Auth hashing algorithm (SCRYPT) was used to create the user account, this
        is the base64-encoded password salt of the user. If a different hashing algorithm was
        used to create this user, as is typical when migrating from another Auth system, this is
        an empty string. If no password is set, or if the service account doesn't have permission to
        read the password, then this is ``None``.
        Zsaltr8   r   r   r   r   password_salt-  s    
z ExportedUserRecord.password_saltN)r   r   r   r   r   rW   rX   r   r   r   r   rT     s
   
rT   c                   @   s0   e Zd ZdZdd Zedd Zedd ZdS )	GetUsersResultz6Represents the result of the ``auth.get_users()`` API.c                 C   s   || _ || _dS )zConstructs a `GetUsersResult` object.

        Args:
            users: List of `UserRecord` instances.
            not_found: List of `UserIdentifier` instances.
        N)_users
_not_found)r   users	not_foundr   r   r   r   =  s    zGetUsersResult.__init__c                 C   s   | j S )zSet of `UserRecord` instances, corresponding to the set of users
        that were requested. Only users that were found are listed here. The
        result set is unordered.
        )rZ   r   r   r   r   r\   G  s    zGetUsersResult.usersc                 C   s   | j S )zVSet of `UserIdentifier` instances that were requested, but not
        found.
        )r[   r   r   r   r   r]   O  s    zGetUsersResult.not_foundN)r   r   r   r   r   r   r\   r]   r   r   r   r   rY   :  s   

rY   c                   @   sL   e Zd ZdZdd Zedd Zedd Zedd	 Zd
d Z	dd Z
dS )ListUsersPageaT  Represents a page of user records exported from a Firebase project.

    Provides methods for traversing the user accounts included in this page, as well as retrieving
    subsequent pages of users. The iterator returned by ``iterate_all()`` can be used to iterate
    through all users in the Firebase project starting from this page.
    c                 C   s   || _ || _|||| _d S r   )	_download_max_results_current)r   download
page_tokenmax_resultsr   r   r   r   _  s    zListUsersPage.__init__c                 C   s   dd | j dg D S )zBA list of ``ExportedUserRecord`` instances available in this page.c                 S   s   g | ]}t |qS r   )rT   )rI   userr   r   r   rK   g  s     z'ListUsersPage.users.<locals>.<listcomp>r\   ra   r2   r   r   r   r   r\   d  s    zListUsersPage.usersc                 C   s   | j ddS )zKPage token string for the next page (empty string indicates no more pages).nextPageToken rf   r   r   r   r   next_page_tokeni  s    zListUsersPage.next_page_tokenc                 C   s
   t | jS )z6A boolean indicating whether more pages are available.)r>   ri   r   r   r   r   has_next_pagen  s    zListUsersPage.has_next_pagec                 C   s   | j rt| j| j| jS dS )zRetrieves the next page of user accounts, if available.

        Returns:
            ListUsersPage: Next page of users, or None if this is the last page.
        N)rj   r^   r_   ri   r`   r   r   r   r   get_next_pages  s    zListUsersPage.get_next_pagec                 C   s   t | S )a]  Retrieves an iterator for user accounts.

        Returned iterator will iterate through all the user accounts in the Firebase project
        starting from this page. The iterator will never buffer more than one page of users
        in memory at a time.

        Returns:
            iterator: An iterator of ExportedUserRecord instances.
        )_UserIteratorr   r   r   r   iterate_all}  s    
zListUsersPage.iterate_allN)r   r   r   r   r   r   r\   ri   rj   rk   rm   r   r   r   r   r^   W  s   



r^   c                   @   s<   e Zd ZdZdd Zedd Zedd Zedd	 Zd
S )DeleteUsersResultz9Represents the result of the ``auth.delete_users()`` API.c                 C   s(   |j }|t| | _t|| _|| _dS )zConstructs a `DeleteUsersResult` object.

        Args:
          result: The proto response, wrapped in a
            `BatchDeleteAccountsResponse` instance.
          total: Total integer number of deletion attempts.
        N)errorslen_success_count_failure_count_errors)r   resulttotalro   r   r   r   r     s    
zDeleteUsersResult.__init__c                 C   s   | j S )zReturns the number of users that were deleted successfully (possibly
        zero).

        Users that did not exist prior to calling `delete_users()` are
        considered to be successfully deleted.
        )rq   r   r   r   r   success_count  s    zDeleteUsersResult.success_countc                 C   s   | j S )zWReturns the number of users that failed to be deleted (possibly
        zero).
        )rr   r   r   r   r   failure_count  s    zDeleteUsersResult.failure_countc                 C   s   | j S )zA list of `auth.ErrorInfo` instances describing the errors that
        were encountered during the deletion. Length of this list is equal to
        `failure_count`.
        )rs   r   r   r   r   ro     s    zDeleteUsersResult.errorsN)	r   r   r   r   r   r   rv   rw   ro   r   r   r   r   rn     s   
	
rn   c                   @   s   e Zd ZdZdddZdS )BatchDeleteAccountsResponsez2Represents the results of a `delete_users()` call.Nc                 C   s   |rdd |D ng | _ dS )aa  Constructs a `BatchDeleteAccountsResponse` instance, corresponding to
        the JSON representing the `BatchDeleteAccountsResponse` proto.

        Args:
            errors: List of dictionaries, with each dictionary representing an
                `ErrorInfo` instance as returned by the server. `None` implies
                an empty list.
        c                 S   s   g | ]}t |qS r   r   )rI   errr   r   r   rK     s     z8BatchDeleteAccountsResponse.__init__.<locals>.<listcomp>N)ro   )r   ro   r   r   r   r     s    	z$BatchDeleteAccountsResponse.__init__)Nr   r   r   r   r   r   r   r   r   rx     s   rx   c                       sh   e Zd ZdZ fddZedd Zedd Zedd	 Zed
d Z	edd Z
edd Z  ZS )rH   zRContains metadata regarding how a user is known by a particular identity provider.c                    sB   t t|   t|ts&td||ds8td|| _d S )Nr*   rawIdr,   )	r-   rH   r   r.   r/   r0   r1   r2   r3   r4   r6   r   r   r     s    

zProviderUserInfo.__init__c                 C   s   | j dS )Nr{   r8   r   r   r   r   r#     s    zProviderUserInfo.uidc                 C   s   | j dS )Nr9   r8   r   r   r   r   r$     s    zProviderUserInfo.display_namec                 C   s   | j dS )Nr%   r8   r   r   r   r   r%     s    zProviderUserInfo.emailc                 C   s   | j dS )Nr:   r8   r   r   r   r   r&     s    zProviderUserInfo.phone_numberc                 C   s   | j dS )Nr;   r8   r   r   r   r   r'     s    zProviderUserInfo.photo_urlc                 C   s   | j dS )N
providerIdr8   r   r   r   r   r(     s    zProviderUserInfo.provider_id)r   r   r   r   r   r   r#   r$   r%   r&   r'   r(   rS   r   r   r6   r   rH     s   




rH   c                   @   s   e Zd ZdZdddZdS )ActionCodeSettingszContains required continue/state URL with optional Android and iOS settings.
    Used when invoking the email action link generation APIs.
    Nc                 C   s.   || _ || _|| _|| _|| _|| _|| _d S r   )urlhandle_code_in_appdynamic_link_domainios_bundle_idandroid_package_nameandroid_install_appandroid_minimum_version)r   r~   r   r   r   r   r   r   r   r   r   r     s    zActionCodeSettings.__init__)NNNNNNrz   r   r   r   r   r}     s         r}   c                 C   s  i }| j stdz0t| j }|js6td| j | j |d< W n$ tk
rf   td| j Y nX | jdk	rt| jt	std| j| j|d< | j
dk	rt| j
tstd| j
| j
|d< | jdk	rt| jtstd	| j| j|d
< | js| jr| jstd| jdk	rLt| jtsBtd| j| j|d< | jdk	rt| jtsvtd| j| j|d< | jdk	rt| jt	std| j| j|d< |S )z Validates the provided action code settings for email link generation and
    populates the REST api parameters.

    settings - ``ActionCodeSettings`` object provided to be encoded
    returns  - dict of parameters to be passed for link gereration.
    z%Dynamic action links url is mandatoryz*Malformed dynamic action links url: "{0}".ZcontinueUrlNz2Invalid value provided for handle_code_in_app: {0}ZcanHandleCodeInAppz3Invalid value provided for dynamic_link_domain: {0}ZdynamicLinkDomainz-Invalid value provided for ios_bundle_id: {0}ZiOSBundleIdzGAndroid package name is required when specifying other Android settingsz4Invalid value provided for android_package_name: {0}ZandroidPackageNamez7Invalid value provided for android_minimum_version: {0}ZandroidMinimumVersionz3Invalid value provided for android_install_app: {0}ZandroidInstallApp)r~   r0   r   urlparsenetlocr1   	Exceptionr   r.   r>   r   strr   r   r   r   )settings
parametersrP   r   r   r   encode_action_code_settings  sf    








r   c                
   @   s~   e Zd ZdZdZdddZdd Zdd	 Zdefd
dZ	dddZ
dddZdd ZdddZdddZd ddZdd ZdS )!UserManagerzBProvides methods for interacting with the Google Identity Toolkit.z)https://identitytoolkit.googleapis.com/v1Nc                 C   s:   || _ |p| j}d||| _|r6|  jd|7  _d S )Nz{0}/projects/{1}z/tenants/{0})http_clientID_TOOLKIT_URLr1   base_url)r   r   Z
project_idrR   Zurl_overrideZ
url_prefixr   r   r   r   @  s
    
zUserManager.__init__c                 K   s   d|kr.| dd }}dtj|ddgi}njd|kr\| dd }}dtj|ddgi}n<d|kr| dd }}d	tj|ddgi}ntd
|| jdd|d\}}|r|dstj	d|||d|d d S )z5Gets the user data corresponding to the provided key.r#   zuser IDr+   Trequiredr%   r&   zphone numberr:   z#Unsupported keyword arguments: {0}.post/accounts:lookuprN   r\   z/No user record found for the provided {0}: {1}.http_responser   )
popr   validate_uidvalidate_emailvalidate_phone	TypeErrorr1   _make_requestr2   ZUserNotFoundError)r   kwargsrE   Zkey_typepayloadbody	http_respr   r   r   get_userG  s"    
zUserManager.get_userc                 C   s   |sg S t |dkrtdtt}|D ]}t|tjrJ|d |j q(t|tj	rh|d |j
 q(t|tjr|d |j q(t|tjr|d |j|jd q(tdt|q(| jd	d
|d\}}|jstjd|d|dg S )ao  Looks up multiple users by their identifiers (uid, email, etc.)

        Args:
            identifiers: UserIdentifier[]: The identifiers indicating the user
                to be looked up. Must have <= 100 entries.

        Returns:
            list[dict[string, string]]: List of dicts representing the JSON
            `UserInfo` responses from the server.

        Raises:
            ValueError: If any of the identifiers are invalid or if more than
                100 identifiers are specified.
            UnexpectedResponseError: If the backend server responds with an
                unexpected message.
        d   z1`identifiers` parameter must have <= 100 entries.r+   r%   r:   ZfederatedUserId)r|   r{   z9Invalid entry in "identifiers" list. Unsupported type: {}r   r   r   zFailed to get users.r   r\   )rp   r0   r   listr.   r   ZUidIdentifierappendr#   ZEmailIdentifierr%   ZPhoneIdentifierr&   ZProviderIdentifierr(   Zprovider_uidr1   typer   okr   UnexpectedResponseErrorr2   )r   Zidentifiersr   
identifierr   r   r   r   r   	get_users\  sB    
  
 zUserManager.get_usersc                 C   sz   |dk	rt |tr|stdt |ts0td|dk s@|tkrNtdtd|i}|rb||d< | jdd	|d
\}}|S )zRetrieves a batch of users.Nz&Page token must be a non-empty string.zMax results must be an integer.   z5Max results must be a positive integer less than {0}.Z
maxResultsrg   r2   z/accounts:batchGet)params)r.   r   r0   rB   MAX_LIST_USERS_RESULTSr1   r   )r   rc   rd   r   r   _r   r   r   
list_users  s     
zUserManager.list_usersc	              	   C   s   t |t |t |t |t |t ||dk	r@t|nd|dk	rRt|ndd}	dd |	 D }	| j	dd|	d\}
}|
r|

dst jd	|d
|

dS )z9Creates a new user account with the specified properties.N)r+   r9   r%   r:   r;   passwordr<   r@   c                 S   s   i | ]\}}|d k	r||qS r   r   rI   kvr   r   r   
<dictcomp>  s       z+UserManager.create_user.<locals>.<dictcomp>r   z	/accountsr   r+   zFailed to create new user.r   )r   r   validate_display_namer   r   validate_photo_urlvalidate_passwordr>   itemsr   r2   r   )r   r#   r$   r%   r&   r'   r   r@   r?   r   r   r   r   r   r   create_user  s"    
 zUserManager.create_userc                 C   s  t j|ddt |t |t |	d|dk	r6t|nd|dk	rHt|ndd}g }t |}|dk	r|tkrz|d nt 	||d< |dk	r|tkr|d nt 
||d	< |r||d
< |dk	r|tkr|d nt ||d< |
dk	r&|
tkri }
t|
trt|
n|
}t ||d< |r<tt||d< dd | D }| jdd|d\}}|rt|dst jd||d|dS )z>Updates an existing user account with the specified propertiesTr   rC   N)r+   r%   r   rA   r<   ZdisableUserZDISPLAY_NAMEr9   Z	PHOTO_URLr;   ZdeleteAttributeZphoner:   rM   ZdeleteProviderc                 S   s   i | ]\}}|d k	r||qS r   r   r   r   r   r   r     s       z+UserManager.update_user.<locals>.<dictcomp>r   z/accounts:updater   r+   zFailed to update user: {0}.r   )r   r   r   r   r   r>   Zvalidate_provider_idsDELETE_ATTRIBUTEr   r   r   r   r.   r/   rN   dumpsZvalidate_custom_claimsr   setr   r   r2   r   r1   )r   r#   r$   r%   r&   r'   r   r@   r?   rC   rQ   Zproviders_to_deleter   removeZremove_providerZjson_claimsr   r   r   r   r   update_user  sV    
	

  zUserManager.update_userc                 C   sL   t j|dd | jddd|id\}}|r4|dsHt jd||d	d
S )z5Deletes the user identified by the specified user ID.Tr   r   z/accounts:deleter+   r   kindzFailed to delete user: {0}.r   N)r   r   r   r2   r   r1   )r   r#   r   r   r   r   r   delete_user  s     zUserManager.delete_userFc                 C   sx   |s
t  S t|dkrtd|D ]}tj|dd q"| jdd||dd\}}t|tshtjd	|d
t |	dg S )a  Deletes the users identified by the specified user ids.

        Args:
            uids: A list of strings indicating the uids of the users to be deleted.
                Must have <= 1000 entries.
            force_delete: Optional parameter that indicates if users should be
                deleted, even if they're not disabled. Defaults to False.


        Returns:
            BatchDeleteAccountsResponse: Server's proto response, wrapped in a
            python object.

        Raises:
            ValueError: If any of the identifiers are invalid or if more than 1000
                identifiers are specified.
            UnexpectedResponseError: If the backend server responds with an
                unexpected message.
        r
   z*`uids` paramter must have <= 1000 entries.Tr   r   z/accounts:batchDelete)ZlocalIdsforcer   zAUnexpected response from server while attempting to delete users.r   ro   )
rx   rp   r0   r   r   r   r.   r/   r   r2   )r   ZuidsZforce_deleter#   r   r   r   r   r   delete_users  s    

zUserManager.delete_usersc                 C   s   z<|rt |tkr tdttdd |D r:tdW n tk
rX   tdY nX ddd |D i}tdd |d D rt|tjstd	|	|
  | jd
d|d\}}t|tstjd|d|S )z1Imports the given list of users to Firebase Auth.z>Users must be a non-empty list with no more than {0} elements.c                 S   s   g | ]}t |tj qS r   )r.   r   ZImportUserRecordrI   ur   r   r   rK     s     z,UserManager.import_users.<locals>.<listcomp>z%One or more user objects are invalid.zusers must be iterabler\   c                 S   s   g | ]}|  qS r   )to_dictr   r   r   r   rK     s     c                 S   s   g | ]}d |kqS )rU   r   r   r   r   r   rK     s     z<A UserImportHash is required to import users with passwords.r   z/accounts:batchCreater   zFailed to import users.r   )rp   MAX_IMPORT_USERS_SIZEr0   r1   anyr   r.   r   ZUserImportHashupdater   r   r/   r   r   )r   r\   Zhash_algr   r   r   r   r   r   import_users  s.    
 zUserManager.import_usersc                 C   sd   t |t |dd}|r*|t| | jdd|d\}}|rL|dsZt jd|d|dS )	a!  Fetches the email action links for types

        Args:
            action_type: String. Valid values ['VERIFY_EMAIL', 'EMAIL_SIGNIN', 'PASSWORD_RESET']
            email: Email of the user for which the action is performed
            action_code_settings: ``ActionCodeSettings`` object or dict (optional). Defines whether
                the link is to be handled by a mobile app and the additional state information to be
                passed in the deep link, etc.
        Returns:
            link_url: action url to be emailed to the user

        Raises:
            UnexpectedResponseError: If the backend server responds with an unexpected message
            FirebaseError: If an error occurs while generating the link
            ValueError: If the provided arguments are invalid
        T)ZrequestTyper%   ZreturnOobLinkr   z/accounts:sendOobCoder   ZoobLinkz%Failed to generate email action link.r   )r   Zvalidate_action_typer   r   r   r   r2   r   )r   Zaction_typer%   Zaction_code_settingsr   r   r   r   r   r   generate_email_action_link'  s     z&UserManager.generate_email_action_linkc              
   K   sX   d | j|}z| jj||f|W S  tjjk
rR } zt|W 5 d }~X Y nX d S )Nz{0}{1})	r1   r   r   Zbody_and_responserequests
exceptionsRequestExceptionr   Zhandle_auth_backend_error)r   methodpathr   r~   errorr   r   r   r   G  s
    zUserManager._make_request)NN)NNNNNNNN)
NNNNNNNNNN)F)N)N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ;  s4   
/        
             
3
$

 r   c                   @   s   e Zd Zedd ZdS )rl   c                 C   s   | j jS r   )Z_current_pager\   r   r   r   r   r   Q  s    z_UserIterator.itemsN)r   r   r   r   r   r   r   r   r   rl   O  s   rl   )#r   base64collectionsr   rN   urllibr   r   Zfirebase_adminr   r   r   r   Zfirebase_admin._user_importr	   r   r   	b64encoderV   r   r   r   r    r)   rT   rY   r^   rn   rx   rH   r}   r   r   ZPageIteratorrl   r   r   r   r   <module>   s>   
)) #3*$D  