a
    ŠxdA  ã                   @   s„   d Z ddlZddlZddlmZ ddlmZ ddlmZ d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dS )a.  
This module contains C{L{OpenIDStore}} implementations that use
various SQL databases to back them.

Example of how to initialize a store database::

python -c 'from openid.store import sqlstore; import pysqlite2.dbapi2;'
  'sqlstore.SQLiteStore(pysqlite2.dbapi2.connect("cstore.db")).createTables()'
é    N)ÚAssociation)ÚOpenIDStore)Únoncec                    sT   ‡ fdd„}t ˆ dƒr>zˆ jdd … |_W n ty<   Y n0 t ˆ dƒrPˆ j|_|S )Nc                    s   | j ˆ | g|¢R i |¤ŽS ©N)Ú_callInTransaction)ÚselfÚargsÚkwargs©Úfunc© úM/var/www/html/Ranjet/env/lib/python3.9/site-packages/openid/store/sqlstore.pyÚwrapped   s    z_inTxn.<locals>.wrappedÚ__name__é   Ú__doc__)Úhasattrr   Ú	TypeErrorr   )r   r   r   r
   r   Ú_inTxn   s    

r   c                   @   sÄ   e 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eeƒZdd„ ZeeƒZd"dd„ZeeƒZdd„ ZeeƒZdd„ ZeeƒZdd„ ZeeƒZdd „ ZeeƒZdS )#ÚSQLStoreaŒ  
    This is the parent class for the SQL stores, which contains the
    logic common to all of the SQL stores.

    The table names used are determined by the class variables
    C{L{associations_table}} and
    C{L{nonces_table}}.  To change the name of the tables used, pass
    new table names into the constructor.

    To create the tables with the proper schema, see the
    C{L{createTables}} method.

    This class shouldn't be used directly.  Use one of its subclasses
    instead, as those contain the code necessary to use a specific
    database.

    All methods other than C{L{__init__}} and C{L{createTables}}
    should be considered implementation details.


    @cvar associations_table: This is the default name of the table to
        keep associations in

    @cvar nonces_table: This is the default name of the table to keep
        nonces in.


    @sort: __init__, createTables
    Zoid_associationsZ
oid_noncesNc                 C   st   || _ d| _i | _|p| j|p"| jdœ| _d| _t| j dƒrPt| j dƒrP| j | _t| jdƒrht| jdƒspt	dƒ‚dS )a¸  
        This creates a new SQLStore instance.  It requires an
        established database connection be given to it, and it allows
        overriding the default table names.


        @param conn: This must be an established connection to a
            database of the correct type for the SQLStore subclass
            you're using.

        @type conn: A python database API compatible connection
            object.


        @param associations_table: This is an optional parameter to
            specify the name of the table used for storing
            associations.  The default value is specified in
            C{L{SQLStore.associations_table}}.

        @type associations_table: C{str}


        @param nonces_table: This is an optional parameter to specify
            the name of the table used for storing nonces.  The
            default value is specified in C{L{SQLStore.nonces_table}}.

        @type nonces_table: C{str}
        N)ÚassociationsZnoncesi`T  ÚIntegrityErrorÚOperationalErrorzDError using database connection module (Maybe it can't be imported?))
ÚconnÚcurÚ_statement_cacheÚassociations_tableÚnonces_tableÚ_table_namesZmax_nonce_ager   Ú
exceptionsÚRuntimeError)r   r   r   r   r   r   r   Ú__init__D   s    þ
ÿ
ÿzSQLStore.__init__c                 C   s   |S )zSConvert a blob as returned by the SQL engine into a str object.

        str -> strr   ©r   Úblobr   r   r   Ú
blobDecodev   s    zSQLStore.blobDecodec                 C   s   |S )z]Convert a str object into the necessary object for storing
        in the database as a blob.r   ©r   Úsr   r   r   Ú
blobEncode|   s    zSQLStore.blobEncodec                 C   sF   z| j | W S  ty@   t| |ƒ}|| j; }|| j |< | Y S 0 d S r   )r   ÚKeyErrorÚgetattrr   )r   Úsql_nameÚsqlr   r   r   Ú_getSQL   s    


zSQLStore._getSQLc                 G   s2   |   |¡}dd„ }tt||ƒƒ}| j ||¡ d S )Nc                 S   s   t | tƒrt| ƒS | S d S r   )Ú
isinstanceÚstr)Úargr   r   r   Úunicode_to_str‘   s    
z)SQLStore._execSQL.<locals>.unicode_to_str)r,   ÚlistÚmapr   Úexecute)r   r*   r   r+   r0   Zstr_argsr   r   r   Ú_execSQLŠ   s    
zSQLStore._execSQLc                    sP   |d d… dkr>|dd … d ‰‡ ‡fdd„}t ˆ ||ƒ |S td|f ƒ‚d S )Né   Zdb_Z_sqlc                     s   ˆ j ˆg| ¢R Ž S r   )r4   )r   ©r   r*   r   r   r   ¡   s    z"SQLStore.__getattr__.<locals>.funczAttribute %r not found)ÚsetattrÚAttributeError)r   Úattrr   r   r6   r   Ú__getattr__š   s    zSQLStore.__getattr__c                 O   sx   | j  ¡  zF| j  ¡ | _z"||i |¤Ž}W | j ¡  d| _n| j ¡  d| _0 W n   | j  ¡  ‚ Y n0 | j  ¡  |S )z­Execute the given function inside of a transaction, with an
        open cursor. If no exception is raised, the transaction is
        comitted, otherwise it is rolled back.N)r   ÚrollbackÚcursorr   ÚcloseÚcommit)r   r   r   r	   Úretr   r   r   r   ©   s    

ÿ


zSQLStore._callInTransactionc                 C   s   |   ¡  |  ¡  dS )z¡
        This method creates the database tables necessary for this
        store to work.  It should not be called if the tables already
        exist.
        N)Zdb_create_nonceZdb_create_assoc©r   r   r   r   Útxn_createTables¿   s    zSQLStore.txn_createTablesc                 C   s,   |}|   ||j|  |j¡|j|j|j¡ dS )zQSet the association for the server URL.

        Association -> NoneType
        N)Údb_set_assocÚhandler'   ÚsecretÚissuedÚlifetimeÚ
assoc_type)r   Ú
server_urlZassociationÚar   r   r   Útxn_storeAssociationÊ   s
    
þzSQLStore.txn_storeAssociationc                 C   s´   |dur|   ||¡ n
|  |¡ | j ¡ }t|ƒdkr:dS g }|D ]P}t|ƒ}|  |d ¡|d< t|Ž }|jdkr‚|  	||j
¡ qB| |j|f¡ qB|r¬| ¡  |d d S dS dS )zŠGet the most recent association that has been set for this
        server URL and handle.

        str -> NoneType or Association
        Nr   é   éÿÿÿÿ)Údb_get_assocZdb_get_assocsr   ÚfetchallÚlenr1   r$   r   Z	expiresInÚtxn_removeAssociationrC   ÚappendrE   Úsort)r   rH   rC   Úrowsr   ÚvaluesZassocr   r   r   Útxn_getAssociationÖ   s$    


zSQLStore.txn_getAssociationc                 C   s   |   ||¡ | jjdkS )zšRemove the association for the given server URL and handle,
        returning whether the association existed at all.

        (str, str) -> bool
        r   )Zdb_remove_assocr   Úrowcount)r   rH   rC   r   r   r   rP   ÷   s    zSQLStore.txn_removeAssociationc                 C   sN   t |t ¡  ƒtjkrdS z|  |||¡ W n | jjyD   Y dS 0 dS dS )zmReturn whether this nonce is present, and if it is, then
        remove it from the set.

        str -> boolFTN)ÚabsÚtimer   ÚSKEWZdb_add_noncer   r   )r   rH   Ú	timestampZsaltr   r   r   Útxn_useNonce  s    zSQLStore.txn_useNoncec                 C   s    |   tt ¡ ƒtj ¡ | jjS r   )Zdb_clean_nonceÚintrX   r   rY   r   rV   r@   r   r   r   Útxn_cleanupNonces  s    zSQLStore.txn_cleanupNoncesc                 C   s   |   tt ¡ ƒ¡ | jjS r   )Zdb_clean_assocr\   rX   r   rV   r@   r   r   r   Útxn_cleanupAssociations  s    z SQLStore.txn_cleanupAssociations)NN)N)r   Ú
__module__Ú__qualname__r   r   r   r!   r$   r'   r,   r4   r:   r   rA   r   ZcreateTablesrJ   ZstoreAssociationrU   ZgetAssociationrP   ZremoveAssociationr[   ÚuseNoncer]   ZcleanupNoncesr^   ZcleanupAssociationsr   r   r   r   r   "   s0   
2		

	r   c                       sP   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdd„ Z‡ fdd„Z‡  ZS )ÚSQLiteStorez÷
    This is an SQLite-based specialization of C{L{SQLStore}}.

    To create an instance, see C{L{SQLStore.__init__}}.  To create the
    tables it will use, see C{L{SQLStore.createTables}}.

    All other methods are implementation details.
    z¤
    CREATE TABLE %(nonces)s (
        server_url VARCHAR,
        timestamp INTEGER,
        salt CHAR(40),
        UNIQUE(server_url, timestamp, salt)
    );
    a  
    CREATE TABLE %(associations)s
    (
        server_url VARCHAR(2047),
        handle VARCHAR(255),
        secret BLOB(128),
        issued INTEGER,
        lifetime INTEGER,
        assoc_type VARCHAR(64),
        PRIMARY KEY (server_url, handle)
    );
    z}INSERT OR REPLACE INTO %(associations)s (server_url, handle, secret, issued, lifetime, assoc_type) VALUES (?, ?, ?, ?, ?, ?);z_SELECT handle, secret, issued, lifetime, assoc_type FROM %(associations)s WHERE server_url = ?;znSELECT handle, secret, issued, lifetime, assoc_type FROM %(associations)s WHERE server_url = ? AND handle = ?;zDSELECT server_url FROM %(associations)s WHERE issued + lifetime < ?;zADELETE FROM %(associations)s WHERE server_url = ? AND handle = ?;z9DELETE FROM %(associations)s WHERE issued + lifetime < ?;z(INSERT INTO %(nonces)s VALUES (?, ?, ?);z+DELETE FROM %(nonces)s WHERE timestamp < ?;c                 C   s   t |ƒS r   )Ú
memoryviewr%   r   r   r   r'   X  s    zSQLiteStore.blobEncodec              
      sf   zt t| ƒj|i |¤ŽW S  | jjy` } z,t dt|ƒ¡rJW Y d }~dS ‚ W Y d }~n
d }~0 0 d S )Nz^columns .* are not unique$F)Úsuperrb   ra   r   r   ÚreÚmatchr.   )r   r   r	   Úwhy©Ú	__class__r   r   ra   [  s    zSQLiteStore.useNonce)r   r_   r`   r   Úcreate_nonce_sqlÚcreate_assoc_sqlÚset_assoc_sqlÚget_assocs_sqlÚget_assoc_sqlÚget_expired_sqlÚremove_assoc_sqlÚclean_assoc_sqlÚadd_nonce_sqlÚclean_nonce_sqlr'   ra   Ú__classcell__r   r   rh   r   rb   "  s   		ÿrb   c                   @   s\   e Zd ZdZzddlZW n ey.   dZY n0 dZdZdZ	dZ
dZd	Zd
ZdZdZdZdS )Ú
MySQLStorea&  
    This is a MySQL-based specialization of C{L{SQLStore}}.

    Uses InnoDB tables for transaction support.

    To create an instance, see C{L{SQLStore.__init__}}.  To create the
    tables it will use, see C{L{SQLStore.createTables}}.

    All other methods are implementation details.
    r   NzÙ
    CREATE TABLE %(nonces)s (
        server_url BLOB NOT NULL,
        timestamp INTEGER NOT NULL,
        salt CHAR(40) NOT NULL,
        PRIMARY KEY (server_url(255), timestamp, salt)
    )
    ENGINE=InnoDB;
    aG  
    CREATE TABLE %(associations)s
    (
        server_url BLOB NOT NULL,
        handle VARCHAR(255) NOT NULL,
        secret BLOB NOT NULL,
        issued INTEGER NOT NULL,
        lifetime INTEGER NOT NULL,
        assoc_type VARCHAR(64) NOT NULL,
        PRIMARY KEY (server_url(255), handle)
    )
    ENGINE=InnoDB;
    zDREPLACE INTO %(associations)s VALUES (%%s, %%s, %%s, %%s, %%s, %%s);úaSELECT handle, secret, issued, lifetime, assoc_type FROM %(associations)s WHERE server_url = %%s;úFSELECT server_url FROM %(associations)s WHERE issued + lifetime < %%s;úrSELECT handle, secret, issued, lifetime, assoc_type FROM %(associations)s WHERE server_url = %%s AND handle = %%s;úEDELETE FROM %(associations)s WHERE server_url = %%s AND handle = %%s;ú;DELETE FROM %(associations)s WHERE issued + lifetime < %%s;ú.INSERT INTO %(nonces)s VALUES (%%s, %%s, %%s);ú-DELETE FROM %(nonces)s WHERE timestamp < %%s;)r   r_   r`   r   ZMySQLdbr   ÚImportErrorrj   rk   rl   rm   ro   rn   rp   rq   rr   rs   r   r   r   r   ru   h  s    

ÿru   c                   @   sŒ   e Zd ZdZzddlZW n& ey>   ddlmZ e ¡  Y n0 dZ	dZ
dZdd„ Zd	Zd
ZdZdZdZdZdZdZdZdd„ Zdd„ ZdS )ÚPostgreSQLStorezú
    This is a PostgreSQL-based specialization of C{L{SQLStore}}.

    To create an instance, see C{L{SQLStore.__init__}}.  To create the
    tables it will use, see C{L{SQLStore.createTables}}.

    All other methods are implementation details.
    r   N)ÚcompatzË
    CREATE TABLE %(nonces)s (
        server_url VARCHAR(2047) NOT NULL,
        timestamp INTEGER NOT NULL,
        salt CHAR(40) NOT NULL,
        PRIMARY KEY (server_url, timestamp, salt)
    );
    a…  
    CREATE TABLE %(associations)s
    (
        server_url VARCHAR(2047) NOT NULL,
        handle VARCHAR(255) NOT NULL,
        secret BYTEA NOT NULL,
        issued INTEGER NOT NULL,
        lifetime INTEGER NOT NULL,
        assoc_type VARCHAR(64) NOT NULL,
        PRIMARY KEY (server_url, handle),
        CONSTRAINT secret_length_constraint CHECK (LENGTH(secret) <= 128)
    );
    c           	      C   sJ   |   ||¡}| j ¡ }t|ƒr2|  ||||||¡S |  ||||||¡S dS )z¥
        Set an association.  This is implemented as a method because
        REPLACE INTO is not supported by PostgreSQL (and is not
        standard SQL).
        N)rM   r   rN   rO   Zdb_update_assocZdb_new_assoc)	r   rH   rC   rD   rE   rF   rG   ÚresultrS   r   r   r   rB   Î  s    
ÿÿzPostgreSQLStore.db_set_assoczCINSERT INTO %(associations)s VALUES (%%s, %%s, %%s, %%s, %%s, %%s);zUPDATE %(associations)s SET secret = %%s, issued = %%s, lifetime = %%s, assoc_type = %%s WHERE server_url = %%s AND handle = %%s;rv   rw   rx   ry   rz   r{   r|   c                 C   s   ddl m} ||ƒS )Nr   )ÚBinary)Úpsycopg2r   )r   r#   r   r   r   r   r'   ø  s    zPostgreSQLStore.blobEncodec                 C   s   |  ¡ S r   )Útobytesr"   r   r   r   r$   ý  s    zPostgreSQLStore.blobDecode)r   r_   r`   r   r‚   r}   Zpsycopg2cffir   Úregisterr   rj   rk   rB   Znew_assoc_sqlZupdate_assoc_sqlrm   ro   rn   rp   rq   rr   rs   r'   r$   r   r   r   r   r~   ¥  s,   		ÿr~   )r   re   rX   Zopenid.associationr   Zopenid.store.interfacer   Zopenid.storer   r   r   rb   ru   r~   r   r   r   r   Ú<module>   s   	  F=