a
    !fH                     @   sX   d Z G dd deZG dd deZG dd deZG dd deZG d	d
 d
eZdS )a  Manipulate access control lists that Cloud Storage provides.

:class:`gcloud.storage.bucket.Bucket` has a getting method that creates
an ACL object under the hood, and you can interact with that using
:func:`gcloud.storage.bucket.Bucket.acl`::

  >>> from gcloud import storage
  >>> client = storage.Client()
  >>> bucket = client.get_bucket(bucket_name)
  >>> acl = bucket.acl

Adding and removing permissions can be done with the following methods
(in increasing order of granularity):

- :func:`ACL.all`
  corresponds to access for all users.
- :func:`ACL.all_authenticated` corresponds
  to access for all users that are signed into a Google account.
- :func:`ACL.domain` corresponds to access on a
  per Google Apps domain (ie, ``example.com``).
- :func:`ACL.group` corresponds to access on a
  per group basis (either by ID or e-mail address).
- :func:`ACL.user` corresponds to access on a
  per user basis (either by ID or e-mail address).

And you are able to ``grant`` and ``revoke`` the following roles:

- **Reading**:
  :func:`_ACLEntity.grant_read` and :func:`_ACLEntity.revoke_read`
- **Writing**:
  :func:`_ACLEntity.grant_write` and :func:`_ACLEntity.revoke_write`
- **Owning**:
  :func:`_ACLEntity.grant_owner` and :func:`_ACLEntity.revoke_owner`

You can use any of these like any other factory method (these happen to
be :class:`_ACLEntity` factories)::

  >>> acl.user('me@example.org').grant_read()
  >>> acl.all_authenticated().grant_write()

You can also chain these ``grant_*`` and ``revoke_*`` methods together
for brevity::

  >>> acl.all().grant_read().revoke_write()

After that, you can save any changes you make with the
:func:`gcloud.storage.acl.ACL.save` method::

  >>> acl.save()

You can alternatively save any existing :class:`gcloud.storage.acl.ACL`
object (whether it was created by a factory method or not) from a
:class:`gcloud.storage.bucket.Bucket`::

  >>> bucket.acl.save(acl=acl)

To get the list of ``entity`` and ``role`` for each unique pair, the
:class:`ACL` class is iterable::

  >>> print list(ACL)
  [{'role': 'OWNER', 'entity': 'allUsers'}, ...]

This list of tuples can be used as the ``entity`` and ``role`` fields
when sending metadata for ACLs to the API.
c                   @   s~   e Zd ZdZdZdZdZdddZdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )
_ACLEntitya  Class representing a set of roles for an entity.

    This is a helper class that you likely won't ever construct
    outside of using the factor methods on the :class:`ACL` object.

    :type entity_type: string
    :param entity_type: The type of entity (ie, 'group' or 'user').

    :type identifier: string
    :param identifier: The ID or e-mail of the entity. For the special
                       entity types (like 'allUsers') this is optional.
    ZREADERZWRITERZOWNERNc                 C   s   || _ tg | _|| _d S N)
identifiersetrolestype)selfentity_typer    r	   S/var/www/html/python-backend/venv/lib/python3.9/site-packages/gcloud/storage/acl.py__init__d   s    
z_ACLEntity.__init__c                 C   s    | j st| jS dj| dS d S )Nz{acl.type}-{acl.identifier})acl)r   strr   formatr   r	   r	   r
   __str__i   s    
z_ACLEntity.__str__c                 C   s   dj | d| jdS )Nz<ACL Entity: {acl} ({roles})>z, )r   r   )r   joinr   r   r	   r	   r
   __repr__o   s    z_ACLEntity.__repr__c                 C   s   | j S )zGet the list of roles permitted by this entity.

        :rtype: list of strings
        :returns: The list of roles associated with this entity.
        )r   r   r	   r	   r
   	get_roless   s    z_ACLEntity.get_rolesc                 C   s   | j | dS )zrAdd a role to the entity.

        :type role: string
        :param role: The role to add to the entity.
        N)r   addr   roler	   r	   r
   grant{   s    z_ACLEntity.grantc                 C   s   || j v r| j | dS )z|Remove a role from the entity.

        :type role: string
        :param role: The role to remove from the entity.
        N)r   remover   r	   r	   r
   revoke   s    
z_ACLEntity.revokec                 C   s   |  tj dS )z(Grant read access to the current entity.N)r   r   READER_ROLEr   r	   r	   r
   
grant_read   s    z_ACLEntity.grant_readc                 C   s   |  tj dS )z)Grant write access to the current entity.N)r   r   WRITER_ROLEr   r	   r	   r
   grant_write   s    z_ACLEntity.grant_writec                 C   s   |  tj dS )z)Grant owner access to the current entity.N)r   r   
OWNER_ROLEr   r	   r	   r
   grant_owner   s    z_ACLEntity.grant_ownerc                 C   s   |  tj dS )z+Revoke read access from the current entity.N)r   r   r   r   r	   r	   r
   revoke_read   s    z_ACLEntity.revoke_readc                 C   s   |  tj dS )z,Revoke write access from the current entity.N)r   r   r   r   r	   r	   r
   revoke_write   s    z_ACLEntity.revoke_writec                 C   s   |  tj dS )z,Revoke owner access from the current entity.N)r   r   r   r   r	   r	   r
   revoke_owner   s    z_ACLEntity.revoke_owner)N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r	   r	   r	   r
   r   R   s    
	r   c                   @   s  e Zd ZdZdZdZdddddd	d
Zeg dZdZ	dZ
dZdd Zdd Zdd Zdd Zdd Zdd Zd:ddZdd Zd;ddZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zed,d- Zd.d/ Zd<d0d1Zd2d3 Zd=d4d5Z d>d6d7Z!d?d8d9Z"dS )@ACLz7Container class representing a list of access controls.r   ZpredefinedAclprojectPrivate
publicReadpublicReadWriteauthenticatedReadbucketOwnerReadbucketOwnerFullControl)zproject-privatezpublic-readzpublic-read-writezauthenticated-readzbucket-owner-readzbucket-owner-full-control)privater(   r)   r*   r+   r,   r-   FNc                 C   s
   i | _ d S r   )entitiesr   r	   r	   r
   r      s    zACL.__init__c                 C   s   | j s|   dS )zLoad if not already loaded.N)loadedreloadr   r	   r	   r
   _ensure_loaded   s    zACL._ensure_loadedc                 C   s   | j   d| _dS )z@Remove all entities from the ACL, and clear the ``loaded`` flag.FN)r/   clearr0   r   r	   r	   r
   reset   s    
z	ACL.resetc                 c   s>   |    | j D ]&}| D ]}|rt||dV  qqd S )N)entityr   )r2   r/   valuesr   r   )r   r5   r   r	   r	   r
   __iter__   s
    zACL.__iter__c                 C   s~   |d }|d }|dkr"|   }n8|dkr4|  }n&d|v rZ|dd\}}| j||d}t|tsptd| || |S )	a  Build an _ACLEntity object from a dictionary of data.

        An entity is a mutable object that represents a list of roles
        belonging to either a user or group or the special types for all
        users and all authenticated users.

        :type entity_dict: dict
        :param entity_dict: Dictionary full of data from an ACL lookup.

        :rtype: :class:`_ACLEntity`
        :returns: An Entity constructed from the dictionary.
        r5   r   allUsersallAuthenticatedUsers-   r   r   zInvalid dictionary: %s)allall_authenticatedsplitr5   
isinstancer   
ValueErrorr   )r   Zentity_dictr5   r   r   r   r	   r	   r
   entity_from_dict   s    



zACL.entity_from_dictc                 C   s   |    t|| jv S )a	  Returns whether or not this ACL has any entries for an entity.

        :type entity: :class:`_ACLEntity`
        :param entity: The entity to check for existence in this ACL.

        :rtype: boolean
        :returns: True of the entity exists in the ACL.
        )r2   r   r/   r   r5   r	   r	   r
   
has_entity   s    	zACL.has_entityc                 C   s   |    | jt||S )a  Gets an entity object from the ACL.

        :type entity: :class:`_ACLEntity` or string
        :param entity: The entity to get lookup in the ACL.

        :type default: anything
        :param default: This value will be returned if the entity
                        doesn't exist.

        :rtype: :class:`_ACLEntity`
        :returns: The corresponding entity or the value provided
                  to ``default``.
        )r2   r/   getr   )r   r5   defaultr	   r	   r
   
get_entity  s    zACL.get_entityc                 C   s   |    || jt|< dS )zAdd an entity to the ACL.

        :type entity: :class:`_ACLEntity`
        :param entity: The entity to add to this ACL.
        N)r2   r/   r   rC   r	   r	   r
   
add_entity  s    zACL.add_entityc                 C   s0   t ||d}| |r"| |}n
| | |S )a  Factory method for creating an Entity.

        If an entity with the same type and identifier already exists,
        this will return a reference to that entity.  If not, it will
        create a new one and add it to the list of known entities for
        this ACL.

        :type entity_type: string
        :param entity_type: The type of entity to create
                            (ie, ``user``, ``group``, etc)

        :type identifier: string
        :param identifier: The ID of the entity (if applicable).
                           This can be either an ID or an e-mail address.

        :rtype: :class:`_ACLEntity`
        :returns: A new Entity or a reference to an existing identical entity.
        r<   )r   rD   rG   rH   )r   r   r   r5   r	   r	   r
   r5   %  s
    

z
ACL.entityc                 C   s   | j d|dS )zFactory method for a user Entity.

        :type identifier: string
        :param identifier: An id or e-mail for this particular user.

        :rtype: :class:`_ACLEntity`
        :returns: An Entity corresponding to this user.
        userr   r5   r   r   r	   r	   r
   rI   ?  s    	zACL.userc                 C   s   | j d|dS )zFactory method for a group Entity.

        :type identifier: string
        :param identifier: An id or e-mail for this particular group.

        :rtype: :class:`_ACLEntity`
        :returns: An Entity corresponding to this group.
        grouprJ   rK   rL   r	   r	   r
   rM   J  s    	z	ACL.groupc                 C   s   | j d|dS )zFactory method for a domain Entity.

        :type domain: string
        :param domain: The domain for this entity.

        :rtype: :class:`_ACLEntity`
        :returns: An entity corresponding to this domain.
        domainrJ   rK   )r   rN   r	   r	   r
   rN   U  s    	z
ACL.domainc                 C   s
   |  dS )zFactory method for an Entity representing all users.

        :rtype: :class:`_ACLEntity`
        :returns: An entity representing all users.
        r8   rK   r   r	   r	   r
   r=   `  s    zACL.allc                 C   s
   |  dS )zFactory method for an Entity representing all authenticated users.

        :rtype: :class:`_ACLEntity`
        :returns: An entity representing all authenticated users.
        r9   rK   r   r	   r	   r
   r>   h  s    zACL.all_authenticatedc                 C   s   |    t| j S )zGet a list of all Entity objects.

        :rtype: list of :class:`_ACLEntity` objects
        :returns: A list of all Entity objects.
        )r2   listr/   r6   r   r	   r	   r
   get_entitiesp  s    zACL.get_entitiesc                 C   s   t dS )z&Abstract getter for the object client.N)NotImplementedErrorr   r	   r	   r
   clienty  s    z
ACL.clientc                 C   s   |du r| j }|S )a}  Check client or verify over-ride.

        :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
        :param client: the client to use.  If not passed, falls back to the
                       ``client`` stored on the current ACL.

        :rtype: :class:`gcloud.storage.client.Client`
        :returns: The client passed in or the currently bound client.
        NrR   r   rR   r	   r	   r
   _require_client~  s    
zACL._require_clientc                 C   sV   | j }| |}| j  |jjd|d}d| _|ddD ]}| | 	| q<dS )a  Reload the ACL data from Cloud Storage.

        :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the ACL's parent.
        GET)methodpathTitemsr	   N)
reload_pathrU   r/   r3   
connectionapi_requestr0   rE   rH   rB   )r   rR   rX   foundentryr	   r	   r
   r1     s    

z
ACL.reloadc                 C   s   ddi}|durg }||| j < | j}| |}|jjd|| jt|i|d}| j  |	| jdD ]}| 
| | qdd| _dS )a  Helper for :meth:`save` and :meth:`save_predefined`.

        :type acl: :class:`gcloud.storage.acl.ACL`, or a compatible list.
        :param acl: The ACL object to save.  If left blank, this will save
                    current entries.

        :type predefined: string or None
        :param predefined: An identifier for a predefined ACL.  Must be one
                           of the keys in :attr:`PREDEFINED_JSON_ACLS`
                           If passed, `acl` must be None.

        :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the ACL's parent.
        Z
projectionfullNPATCH)rW   rX   dataquery_paramsr	   T)_PREDEFINED_QUERY_PARAM	save_pathrU   r[   r\   _URL_PATH_ELEMrO   r/   r3   rE   rH   rB   r0   )r   r   
predefinedrR   rb   rX   resultr^   r	   r	   r
   _save  s     


z	ACL._savec                 C   s.   |du r| }|j }nd}|r*| |d| dS )a  Save this ACL for the current bucket.

        :type acl: :class:`gcloud.storage.acl.ACL`, or a compatible list.
        :param acl: The ACL object to save.  If left blank, this will save
                    current entries.

        :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the ACL's parent.
        NT)r0   rh   )r   r   rR   Zsave_to_backendr	   r	   r
   save  s    zACL.savec                 C   s8   | j ||}|| jvr&td|f | d|| dS )a  Save this ACL for the current bucket using a predefined ACL.

        :type predefined: string
        :param predefined: An identifier for a predefined ACL.  Must be one
                           of the keys in :attr:`PREDEFINED_JSON_ACLS`
                           or :attr:`PREDEFINED_XML_ACLS` (which will be
                           aliased to the corresponding JSON name).
                           If passed, `acl` must be None.

        :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the ACL's parent.
        zInvalid predefined ACL: %sN)PREDEFINED_XML_ACLSrE   PREDEFINED_JSON_ACLSrA   rh   )r   rf   rR   r	   r	   r
   save_predefined  s    
zACL.save_predefinedc                 C   s   | j g |d dS )a  Remove all ACL entries.

        Note that this won't actually remove *ALL* the rules, but it
        will remove all the non-default rules.  In short, you'll still
        have access to a bucket that you created even after you clear
        ACL rules with this method.

        :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the ACL's parent.
        rS   N)ri   rT   r	   r	   r
   r3     s    z	ACL.clear)N)N)N)NN)N)N)#r#   r$   r%   r&   re   rc   rj   	frozensetrk   r0   rZ   rd   r   r2   r4   r7   rB   rD   rG   rH   r5   rI   rM   rN   r=   r>   rP   propertyrR   rU   r1   rh   ri   rl   r3   r	   r	   r	   r
   r'      sJ   
!
	
	

!

r'   c                       sD   e Zd ZdZ fddZedd Zedd Zedd	 Z  Z	S )
	BucketACLzAn ACL specifically for a bucket.

    :type bucket: :class:`gcloud.storage.bucket.Bucket`
    :param bucket: The bucket to which this ACL relates.
    c                    s   t t|   || _d S r   )superro   r   bucket)r   rq   	__class__r	   r
   r     s    zBucketACL.__init__c                 C   s   | j jS )z&The client bound to this ACL's bucket.)rq   rR   r   r	   r	   r
   rR     s    zBucketACL.clientc                 C   s   d| j j| jf S )3Compute the path for GET API requests for this ACL.z%s/%s)rq   rX   re   r   r	   r	   r
   rZ     s    zBucketACL.reload_pathc                 C   s   | j jS z5Compute the path for PATCH API requests for this ACL.)rq   rX   r   r	   r	   r
   rd     s    zBucketACL.save_path
r#   r$   r%   r&   r   rn   rR   rZ   rd   __classcell__r	   r	   rr   r
   ro     s   

ro   c                   @   s   e Zd ZdZdZdZdS )DefaultObjectACLz9A class representing the default object ACL for a bucket.ZdefaultObjectAclZpredefinedDefaultObjectAclN)r#   r$   r%   r&   re   rc   r	   r	   r	   r
   rx     s   rx   c                       sD   e Zd ZdZ fddZedd Zedd Zedd	 Z  Z	S )
	ObjectACLzAn ACL specifically for a Cloud Storage object / blob.

    :type blob: :class:`gcloud.storage.blob.Blob`
    :param blob: The blob that this ACL corresponds to.
    c                    s   t t|   || _d S r   )rp   ry   r   blob)r   rz   rr   r	   r
   r     s    zObjectACL.__init__c                 C   s   | j jS )z$The client bound to this ACL's blob.)rz   rR   r   r	   r	   r
   rR   #  s    zObjectACL.clientc                 C   s   d| j j S )rt   z%s/aclrz   rX   r   r	   r	   r
   rZ   (  s    zObjectACL.reload_pathc                 C   s   | j jS ru   r{   r   r	   r	   r
   rd   -  s    zObjectACL.save_pathrv   r	   r	   rr   r
   ry     s   

ry   N)r&   objectr   r'   ro   rx   ry   r	   r	   r	   r
   <module>   s   CS  S