B
    b
,c                  @   s   d Z ddlZddlmZ ddlmZmZ ddlmZm	Z	m
Z
mZmZmZ ddlZddlmZmZ ddlmZ dd	lmZ G d
d deZededZeedddZeG dd dZdgZdS )z>ZAP Authenticator in a Python Thread.

.. versionadded:: 14.1
    N)chain)EventThread)AnyDictListOptionalTypeVarcast)NOBLOCKPOLLIN)jsonapi   )Authenticatorc                   sf   e Zd ZdZddeeeee dd fddZddd	d
Z	ddddZ
ee edddZ  ZS )AuthenticationThreadziA Thread for running a zmq Authenticator

    This is run in the background by ThreadedAuthenticator
    utf-8Nzzmq.Context)contextendpointencodinglogauthenticatorreturnc                sv   t    |ptj | _|| _|p,td | _	}t
 | _|pLt|||d| _|tj| _d| j_| j| d S )Nzzmq.auth)r   r   r   )super__init__zmqContextinstancer   r   loggingZ	getLoggerr   r   startedr   r   socketPAIRpipelingerZconnect)selfr   r   r   r   r   )	__class__ .lib/python3.7/site-packages/zmq/auth/thread.pyr      s    
zAuthenticationThread.__init__)r   c             C   s  | j   | j  | j j}t }|| jtj	 ||tj	 xyt
| }W n tjk
rl   P Y nX | j|kr|| j t	krx@y| jjtd}W n tjk
r   P Y nX | |}|rP qW |rP ||krD|| t	krD|   qDW | j  | j   dS )z*Start the Authentication Agent thread task)flagsN)r   startr   set
zap_socketr   ZPollerregisterr!   r   dictZpollZZMQErrorrecv_multipartr   ZAgain_handle_pipe_handle_zapclosestop)r#   ZzapZpollerZsocksmsg	terminater%   r%   r&   run1   s4    



zAuthenticationThread.runc             C   s8   | j jdkrtd| j j }|s(dS | j | dS )z7
        Handle a message from the ZAP socket.
        NzZAP socket closed)r   r*   RuntimeErrorr-   Zhandle_zap_message)r#   r2   r%   r%   r&   r/   T   s    z AuthenticationThread._handle_zap)r2   r   c       	         s  d}|dkrd}|S |d } j d| |dkr fdd|d	d D }y jj|  W n" tk
r~    j d
| Y nX n|dkrڇ fdd|d	d D }y jj|  W n" tk
r    j d| Y nX n|dkr$|d	  j}|d }t	t
ttf t|} j|| nX|dkr^|d	  j}|d  j} j|| n|dkrnd}n j d| |S )z6
        Handle a message from front-end API.
        FNTr   zauth received API command %rs   ALLOWc                s   g | ]}|  jqS r%   )decoder   ).0m)r#   r%   r&   
<listcomp>m   s    z5AuthenticationThread._handle_pipe.<locals>.<listcomp>r   zFailed to allow %ss   DENYc                s   g | ]}|  jqS r%   )r6   r   )r7   r8   )r#   r%   r&   r9   t   s    zFailed to deny %ss   PLAIN   s   CURVEs	   TERMINATEz!Invalid auth command from API: %r)r   debugr   allow	ExceptionZ	exceptiondenyr6   r   r
   r   strr   loadsconfigure_plainconfigure_curveerror)	r#   r2   r3   Zcommand	addressesdomainZjson_passwords	passwordslocationr%   )r#   r&   r.   _   s@    


z!AuthenticationThread._handle_pipe)r   NN)__name__
__module____qualname____doc__r?   r   r   r   r   r4   r/   r   bytesboolr.   __classcell__r%   r%   )r$   r&   r      s     #r   T)Zbound)clsr   c             C   sJ   xD| j  D ]6\}}|dst|s(qtt|d}|js|j|_qW | S )zAinherit docstrings from Authenticator, so we don't duplicate them_N)__dict__items
startswithcallablegetattrr   rK   )rP   namemethodZupstream_methodr%   r%   r&   _inherit_docstrings   s    rY   c               @   s  e Zd ZU dZded< eed< eed< ded< dZeed	< eed
< d.e	d eedddZ
eedddZedddZedddZedddZd/ee	eeef  dddZd0eedd d!Zd1eed"d#d$Zdd%d&d'Zdd%d(d)Zed%d*d+Zdd%d,d-ZdS )2ThreadAuthenticatorz-Run ZAP authentication in a background threadzzmq.Contextr   r   r   z
zmq.Socketr!    pipe_endpointthreadNutf-8)r   r   r   c             C   s>   || _ || _d | _dt|  d| _d | _|p6tj | _	d S )Nz	inproc://z.inproc)
r   r   r!   idr\   r]   r   r   r   r   )r#   r   r   r   r%   r%   r&   r      s    zThreadAuthenticator.__init__)keyvaluec             C   s\   xFt | g| j D ]0}||jks2|t|di krt| || d S qW t| jj	|| d S )N__annotations__)
r   r$   mrorR   rV   object__setattr__setattrr]   r   )r#   r`   ra   objr%   r%   r&   re      s
    zThreadAuthenticator.__setattr__)r`   c             C   s   t | jj|S )N)rV   r]   r   )r#   r`   r%   r%   r&   __getattr__   s    zThreadAuthenticator.__getattr__)rD   c                s$    j dg fdd|D   d S )Ns   ALLOWc                s   g | ]}|  jqS r%   )encoder   )r7   a)r#   r%   r&   r9      s    z-ThreadAuthenticator.allow.<locals>.<listcomp>)r!   send_multipart)r#   rD   r%   )r#   r&   r<      s    zThreadAuthenticator.allowc                s$    j dg fdd|D   d S )Ns   DENYc                s   g | ]}|  jqS r%   )ri   r   )r7   rj   )r#   r%   r&   r9      s    z,ThreadAuthenticator.deny.<locals>.<listcomp>)r!   rk   )r#   rD   r%   )r#   r&   r>      s    zThreadAuthenticator.deny*)rE   rF   c             C   s(   | j d|| jt|pi g d S )Ns   PLAIN)r!   rk   ri   r   r   dumps)r#   rE   rF   r%   r%   r&   rA      s    z#ThreadAuthenticator.configure_plain)rE   rG   c             C   s.   | | j}| | j}| jd||g d S )Ns   CURVE)ri   r   r!   rk   )r#   rE   rG   r%   r%   r&   rB      s    z#ThreadAuthenticator.configure_curve)rE   credentials_providerc             C   s   | j jj||d d S )N)rn   )r]   r   configure_curve_callback)r#   rE   rn   r%   r%   r&   ro      s    z,ThreadAuthenticator.configure_curve_callback)r   c             C   sf   | j tj| _d| j_| j| j t| j | j| j	| j
d| _| j  | jjjddsbtddS )zStart the authentication threadr   )r   r   
   )Ztimeoutz$Authenticator thread failed to startN)r   r   r   r    r!   r"   Zbindr\   r   r   r   r]   r(   r   waitr5   )r#   r%   r%   r&   r(      s    
zThreadAuthenticator.startc             C   s>   | j r:| j d |  r$| j  d| _| j   d| _ dS )zStop the authentication threads	   TERMINATEN)r!   sendis_aliver]   joinr0   )r#   r%   r%   r&   r1      s    

zThreadAuthenticator.stopc             C   s   t | jo| j S )z$Is the ZAP thread currently running?)rM   r]   rs   )r#   r%   r%   r&   rs      s    zThreadAuthenticator.is_alivec             C   s   |    d S )N)r1   )r#   r%   r%   r&   __del__   s    zThreadAuthenticator.__del__)Nr^   N)rl   N)rl   r[   )rl   N)rH   rI   rJ   rK   rb   r   r?   r\   r   r   r   re   rh   r<   r>   r   rA   rB   ro   r(   r1   rM   rs   ru   r%   r%   r%   r&   rZ      s*   
  
rZ   )rK   r   	itertoolsr   Z	threadingr   r   typingr   r   r   r   r	   r
   r   r   r   Z	zmq.utilsr   baser   r   typerO   rY   rZ   __all__r%   r%   r%   r&   <module>   s    `