
    i                         d Z ddlZddlmc mZ ddlZddlZ	ddl
Z	dZddZddZd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd ZdS )zD
Sprint 19 Tests: auth/login, security headers, request size limit.
    Nzhttp://127.0.0.1:8788c                    t           j                            t          | z             }|r0|                                D ]\  }}|                    ||           t           j                            |d          5 }t          j        |	                                          |j
        t          |j                  fcd d d            S # 1 swxY w Y   d S )N
   timeout)urllibrequestRequestBASEitems
add_headerurlopenjsonloadsreadstatusdictheaders)pathr   reqkvrs         0/home/ubuntu/hermes-webui/tests/test_sprint19.pygetr   	   s    
.
 
 
-
-C !MMOO 	! 	!DAqNN1a    			R		0	0 ?Az!&&((##QXtAI>? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s   ;A CCCc                    t          j        |pi                                           }t          j                            t          | z   |ddi          }|r0|                                D ]\  }}|                    ||           	 t          j        	                    |d          5 }t          j
        |                                          |j        t          |j                  fcd d d            S # 1 swxY w Y   d S # t          j        j        $ rJ}t          j
        |                                          |j        t          |j                  fcY d }~S d }~ww xY w)NzContent-Typezapplication/json)datar   r   r   )r   dumpsencoder   r   r	   r
   r   r   r   r   r   r   r   r   error	HTTPErrorcode)	r   bodyr   r   r   r   r   r   es	            r   postr$      s   :djb!!((**D
.
 
 4)79K(L ! N NC !MMOO 	! 	!DAqNN1a    =^##C#44 	C:affhh''4	??B	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C<! = = =z!&&((##QVT!)__<<<<<<<=sC   !D )A C6)D 6C::D =C:>D E!?EE!E!c                  z   t          d          \  } }}d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d	x}}| d
         }d}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j        |
                    d	x}x}}d	S )z5Auth should be disabled by default (no password set)./api/auth/status   ==z%(py0)s == %(py3)sr   py0py3assert %(py5)spy5Nauth_enabledFisz%(py1)s is %(py4)spy1py4assert %(py6)spy6	r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationdr   _@py_assert2@py_assert1@py_format4@py_format6@py_assert0@py_assert3@py_format5@py_format7s              r   test_auth_status_disabledrM   "   s   )**LAvq6S=6S66S^%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    c                     t          dddi          \  } }}d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }d	d
|iz  }t          t          j        |                    dx}}| d         }d}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j        |
                    dx}x}}dS )z8Login should succeed trivially when auth is not enabled.z/api/auth/loginpasswordanythingr'   r(   r*   r   r+   r.   r/   NokTr1   r3   r4   r7   r8   )	r$   r:   r;   r<   r=   r>   r?   r@   rA   rB   s              r   test_login_when_auth_disabledrS   )   s   )J
+CDDLAvq6S=6S66ST7d7d?7d7drN   c                     t          d          \  } }}d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d	x}}d
}|| v }|st          j        d|fd|| f          t          j        |          dt          j                    v st          j        |           rt          j        |           nddz  }dd|iz  }t          t          j        |                    d	x}}d	S )z>When auth is disabled, all routes should work without cookies./api/sessionsr'   r(   r*   r   r+   r.   r/   Nsessionsinz%(py1)s in %(py3)srC   r5   r-   r9   rC   r   rD   rE   rF   rG   rH   rI   s           r   'test_all_routes_accessible_without_authr\   0   s   ''LAvq6S=6S66S:?::rN   c                  "   t           j                            t          dz             } t           j                            | d          5 }|                                                                }|j        }d}||k    }|st          j	        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }d	d
|iz  }t          t          j        |                    dx}x}}d}||v }	|	st          j	        d|	fd||f          t          j        |          dt          j                    v st          j        |          rt          j        |          nddz  }
dd|
iz  }t          t          j        |                    dx}}	d}||v }	|	st          j	        d|	fd||f          t          j        |          dt          j                    v st          j        |          rt          j        |          nddz  }
dd|
iz  }t          t          j        |                    dx}}	ddd           dS # 1 swxY w Y   dS )z-GET /login should return the login page HTML.z/loginr   r   r'   r(   )z.%(py2)s
{%(py2)s = %(py0)s.status
} == %(py5)sr   )r,   py2r/   zassert %(py7)spy7NzSign inrW   rY   htmlrZ   r.   r/   Hermes)r   r   r	   r
   r   r   decoder   r:   r;   r<   r=   r>   r?   r@   rA   )r   r   r`   rF   @py_assert4rJ   rH   @py_format8rI   rE   rG   s              r   test_login_page_servedre   7   s   
.
 
 
1
1C			R		0	0  Avvxx  x3x3x3qqx3 yD          yD     y           D     D                           x4x4x44	                                   s   	H.JJJc                  F   t          d          \  } }}d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d	x}}|j         }d
} ||          }d}	||	k    }
|
st          j        d|
fd||	f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          t          j        |          t          j        |	          dz  }dd|iz  }t          t          j        |                    d	x}x}x}x}
}	|j         }d} ||          }d}	||	k    }
|
st          j        d|
fd||	f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          t          j        |          t          j        |	          dz  }dd|iz  }t          t          j        |                    d	x}x}x}x}
}	|j         }d} ||          }d}	||	k    }
|
st          j        d|
fd||	f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          t          j        |          t          j        |	          dz  }dd|iz  }t          t          j        |                    d	x}x}x}x}
}	d	S )z/JSON responses should include security headers.r&   r'   r(   r*   r   r+   r.   r/   NX-Content-Type-OptionsnosniffzI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)sr   r,   r^   r6   r8   py9assert %(py11)spy11zX-Frame-OptionsDENYzReferrer-Policyzsame-originr9   rC   r   r   rE   rF   rG   rH   rJ   @py_assert5@py_assert8@py_assert7@py_format10@py_format12s                r   test_security_headers_on_jsonru   C   s;   /00Avw6S=6S66S;=/=;;/00=I=0I==========0I============7=====7======;====/====0====I===============================;3(3;;())3V3)V3333333333)V3333333333337333337333333;3333(3333)3333V3333333333333333333333333333333;:(:;;()):]:)]::::::::::)]::::::::::::7:::::7::::::;::::(::::)::::]:::::::::::::::::::::::::::::::::rN   c                  f   t          d          \  } }}d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d	x}}|j         }d
} ||          }d}	||	k    }
|
st          j        d|
fd||	f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          t          j        |          t          j        |	          dz  }dd|iz  }t          t          j        |                    d	x}x}x}x}
}	d	S )z0Health endpoint should include security headers.z/healthr'   r(   r*   r   r+   r.   r/   Nrg   rh   ri   r   rj   rl   rm   r9   ro   s                r   test_security_headers_on_healthrw   L   s   YAvw6S=6S66S;=/=;;/00=I=0I==========0I============7=====7======;====/====0====I=================================rN   c                     t          d          \  } }}|j         }d} ||          }d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          t          j        |          t          j        |          dz  }dd	|iz  }	t          t          j        |	                    d
x}x}x}x}}d
S )z2API responses should have Cache-Control: no-store.rU   zCache-Controlzno-storer(   ri   r   rj   rl   rm   Nr9   )
rC   r   r   rF   rJ   rp   rq   rr   rs   rt   s
             r   test_cache_control_no_storery   S   s8   _--Avw;55;;''5:5':5555555555':5555555555557555557555555;55555555'5555:555555555555555555555555555555555rN   c                     t          d          \  } }}d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d	x}}d
}|| v}|st          j        d|fd|| f          t          j        |          dt          j                    v st          j        |           rt          j        |           nddz  }dd|iz  }t          t          j        |                    d	x}}d	S )z=GET /api/settings must never expose the stored password hash./api/settingsr'   r(   r*   r   r+   r.   r/   Npassword_hashnot inz%(py1)s not in %(py3)srC   rZ   r9   r[   s           r   'test_settings_password_hash_not_exposedr   [   s   ''LAvq6S=6S66S#?!##########?!#####?###########!#####!#############################rN   c                  T   t          d          \  } }}t          dddi          \  }}}d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }d	d
|iz  }t          t          j	        |                    dx}}t          d          \  }}}d}	|	|v }|st          j        d|fd|	|f          t          j        |	          dt	          j                    v st          j        |          rt          j        |          nddz  }d	d
|iz  }t          t          j	        |                    dx}	}d}	|	|v }|st          j        d|fd|	|f          t          j        |	          dt	          j                    v st          j        |          rt          j        |          nddz  }d	d
|iz  }t          t          j	        |                    dx}	}dS )z1Saving settings should not break existing fields.r{   send_keyenterr'   r(   r*   r   r+   r.   r/   Ndefault_modelrW   rY   updatedrZ   default_workspace)
r   r$   r:   r;   r<   r=   r>   r?   r@   rA   )
currentrD   rC   r   rE   rF   rG   rH   r   rI   s
             r   )test_settings_save_preserves_other_fieldsr   b   s    ((MGQ*g)>??LAvq6S=6S66S((MGQ%?g%%%%%%%%%%?g%%%%%?%%%%%%%%%%%g%%%%%g%%%%%%%%%%%%%%%%%%%%%%%%%%%)'))))))))))'))))))))))))))))')))))')))))))))))))))))))))))))))))rN   c                     t          dddi           t          d          \  } }}d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }d	d
|iz  }t          t          j	        |                    dx}}d}|| v}|st          j        d|fd|| f          t          j        |          dt	          j                    v st          j        |           rt          j        |           nddz  }d	d
|iz  }t          t          j	        |                    dx}}dS )zIPOST /api/settings with password_hash must not overwrite the stored hash.r{   r|   @deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefr'   r(   r*   r   r+   r.   r/   Nr}   r   r   rZ   )
r$   r   r:   r;   r<   r=   r>   r?   r@   rA   )r   r   rD   rE   rF   rG   rH   rI   s           r   1test_settings_password_hash_not_directly_settabler   o   s    	?N;<<<_--GVQ6S=6S66S)?'))))))))))?')))))?)))))))))))')))))')))))))))))))))))))))))))))))rN   )N)NN)__doc__builtinsr<   _pytest.assertion.rewrite	assertionrewriter:   r   urllib.errorr   urllib.requestr
   r   r$   rM   rS   r\   re   ru   rw   ry   r   r   r    rN   r   <module>r      s                 ) ) ) ) ) ) ) ) ) ) ) )? ? ? ?= = = = & & &         ; ; ;> > >6 6 6$ $ $
* 
* 
** * * * *rN   