
    &ۤh:c                     f   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dl
Z
ddlmZmZmZmZmZmZmZmZmZ ej*                  j,                  d        Zej*                  j,                  d        Zej*                  j,                  d        Zej*                  j,                  d        Zej*                  j,                  d        Zej*                  j,                  d	        Zej*                  j,                  d
        Zej*                  j,                  d        Zej*                  j,                  d        Zy)a  
test_security_enhancements.py

Purpose:
  Unit tests for the security enhancement functions that implement protection against
  sophisticated attack vectors. These tests validate that security functions work
  correctly under normal conditions and properly block malicious inputs while
  maintaining usability for legitimate users.

Test Coverage:
  - Timing attack protection validation
  - Geographic coordinate validation with bounds checking
  - Error message sanitization to prevent information disclosure
  - Filename security validation including path traversal prevention
  - Cryptographic token generation and verification
  - API input validation with security pattern detection
  - Security headers middleware functionality

Security Testing Philosophy:
  Each test validates both positive cases (legitimate inputs work correctly) and
  negative cases (malicious inputs are properly blocked). Tests ensure security
  measures are transparent to legitimate users while effectively blocking attacks.
    N)	secure_password_checkvalidate_geographic_coordinatessanitize_error_messagevalidate_filename_securitygenerate_secure_tokenverify_hmac_token#rate_limit_with_exponential_backoffvalidate_api_inputsecurity_headers_middlewarec                     ddl } d}| j                  |j                  d      | j                               j	                  d      }d|d}t        d||      }d}||u }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}t        dd|      }d}||u }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}t        d|d      }d}||u }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}g }	g }
t        d      D ]K  }t!        j"                         }t        dd|       t!        j"                         }|	j%                  ||z
         M t        d      D ]K  }t!        j"                         }t        ddd       t!        j"                         }|
j%                  ||z
         M t'        |	      t)        |	      z  }t'        |
      t)        |
      z  }t+        ||z
        }d}||k  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|dd      dz   d|iz  }t        t        j                  |            dx}}y)z
    Test that password checking maintains consistent timing regardless of username validity.
    
    This prevents timing-based username enumeration attacks by ensuring bcrypt
    operations run in both valid and invalid username scenarios.
    r   Ntestpassword123utf-8testuser)usernamepassword_hashTisz%(py0)s is %(py3)sresultpy0py3z/Valid password should authenticate successfully
>assert %(py5)spy5wrongpasswordFz+Invalid password should fail authenticationnonexistentz,Non-existent user should fail authentication
   g?)<)z%(py0)s < %(py3)stiming_diffzTiming difference too large: z.4fz0s - potential username enumeration vulnerability)bcrypthashpwencodegensaltdecoder   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationrangetimeperf_counterappendsumlenabs)r    passwordr   valid_user_rowr   @py_assert2@py_assert1@py_format4@py_format6valid_timesinvalid_times_startend	valid_avginvalid_avgr   s                    \C:\Users\algun\Documents\ceba web\Ceba - Github\tests\security\test_security_enhancements.py-test_secure_password_check_timing_consistencyrC   *   s4     !HMM(//'":FNN<LMTTU\]M &N #:xHFL6T>LLL6TLLLLLL6LLL6LLLTLLLLLLLLLL #:OFI6U?III6UIIIIII6III6IIIUIIIIIIIIII #=(DAFJ6U?JJJ6UJJJJJJ6JJJ6JJJUJJJJJJJJJJ KM 2Y!!#j/>J!3;'	  2Y!!#m_dC!S5[)	  K 3{#33Im$s='99Ki+-.K   A;  A  A  A;  A  A  A  A  A  A;  A  A  A;  A  A  A  A  A  A!>{3>OO   A  A  A  A  A  A  A    c                  <   t        dd      \  } }}d}| |u }|st        j                  d|fd| |f      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d      d	z   d
|iz  }t        t        j                  |            dx}}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d	z   d
|iz  }t        t        j                  |            dx}}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d	z   d
|iz  }t        t        j                  |            dx}}g d}|D ]  \  }}	t        ||	      \  } }}d}| |u }|st        j                  d|fd| |f      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d| d|	 d      d	z   d
|iz  }t        t        j                  |            dx}}||	f}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d	z   d
|iz  }t        t        j                  |            dx}} g d}
|
D ]  \  }}	t        ||	      \  } }}d}| |u }|st        j                  d|fd| |f      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d| d      d	z   d
|iz  }t        t        j                  |            dx}}d}|j                  } |       }||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d |       d!z   d"|iz  }t        t        j                  |            dx}x}x}}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d#      d	z   d
|iz  }t        t        j                  |            dx}} g d$}|D ]  \  }}	t        ||	      \  } }}d}| |u }|st        j                  d|fd| |f      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d%|	 d      d	z   d
|iz  }t        t        j                  |            dx}}d&}|j                  } |       }||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d'|	       d!z   d"|iz  }t        t        j                  |            dx}x}x}}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d#      d	z   d
|iz  }t        t        j                  |            dx}} g d(}|D ]  \  }}	t        ||	      \  } }}d}| |u }|st        j                  d|fd| |f      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d)| d|	 d*      d	z   d
|iz  }t        t        j                  |            dx}}|d+   }t        |t              }|st        j                  d,      d-z   d.t        j                         v st        j
                  t              rt        j                  t              nd.t        j                  |      d/t        j                         v st        j
                  t              rt        j                  t              nd/t        j                  |      d0z  }t        t        j                  |            dx}}|d1   }t        |t              }|st        j                  d2      d-z   d.t        j                         v st        j
                  t              rt        j                  t              nd.t        j                  |      d/t        j                         v st        j
                  t              rt        j                  t              nd/t        j                  |      d0z  }t        t        j                  |            dx}} d3d4d5d6d7d8t        d9      d:fd;t        d9      ft        d<      d:fd;t        d<      fg
}|D ]N  \  }}	t        ||	      \  } }}d}| |u }|st        j                  d|fd| |f      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d=| d|	 d>      d	z   d
|iz  }t        t        j                  |            dx}}d}||u}|st        j                  d?|fd@||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  dA      d	z   d
|iz  }t        t        j                  |            dx}}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  dB      d	z   d
|iz  }t        t        j                  |            dx}}Q y)CzBTest geographic coordinate validation with proper bounds checking.v^F@]P/@Tr   r   successr   z(Valid coordinates should pass validationr   r   Nerrorz/Valid coordinates should not have error message)rF   rG   ==)z%(py0)s == %(py3)scoordsz.Valid coordinates should be returned unchanged))g     V@     f@)g     V     f)        rO   )     F@g      /@zBoundary coordinates (, z) should be validz1Boundary coordinates should be returned unchanged))g     V@      .@)g     VrR   )rM   rR   )rN   rR   FzInvalid latitude z should be rejectedu   geografska širinainzD%(py1)s in %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.lower
}()
}py1r   r   py7z'Should have latitude error message for 
>assert %(py9)spy9z&Invalid coordinates should return None))rP   g     f@)rP   g     f)rP   g     v@)rP   g     vzInvalid longitude u   geografska dužinaz(Should have longitude error message for ))z	45.815399z	15.981919)4515)45.015.0zString coordinates (z) should convert and validater   z"Converted latitude should be float7
>assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}
isinstancefloatr   py2r   r      z#Converted longitude should be float)invalidr^   )r]   re   )Nr^   )r]   N)z'; DROP TABLE coords; --r^   )z<script>alert('xss')</script>r^   infrR   rP   nanzInvalid input (z) should be rejectedis notz%(py0)s is not %(py3)sz'Invalid input should have error messagez,Invalid input should return None coordinates)r   r%   r&   r'   r(   r)   r*   r+   r,   r-   lowerr`   ra   )rH   rI   rL   r7   r8   r9   r:   boundary_testslatlnginvalid_lat_tests@py_assert0@py_assert4@py_assert6@py_format8@py_format10invalid_lng_testsstring_coordinate_testsinvalid_inputss                      rB   $test_validate_geographic_coordinatesrx   d   s   
 =Y	RGUFF7d?FFF7dFFFFFF7FFF7FFFdFFFFFFFFFFK5D=KKK5DKKKKKK5KKK5KKKDKKKKKKKKKK+]6++]]]6+]]]]]]6]]]6]]]+]]]-]]]]]]]N #S!@c!JVw$VVVw$VVVVVVwVVVwVVV$VVV"8RuDU VVVVVVVsYv#YYYvYYYYYYvYYYvYYYYYY'XYYYYYYY # &S!@c!JMw%MMMw%MMMMMMwMMMwMMM%MMM#4SE9L!MMMMMMM#eu{{e{}e#}4eee#}eee#eeeeeeueeeueee{eee}eee8_`c_d6eeeeeeeeGv~GGGvGGGGGGvGGGvGGGGGGGGGGGGGG	 & &S!@c!JNw%NNNw%NNNNNNwNNNwNNN%NNN#5cU:M!NNNNNNN#fu{{f{}f#}4fff#}fff#ffffffufffufff{fff}fff8`ad`e6ffffffffGv~GGGvGGGGGGvGGGvGGGGGGGGGGGGGG	 & ,S!@c!J`w$```w$``````w```w```$```"6se2cUB_ ``````` )Qz)U+Q+QQ-QQQQQQQzQQQzQQQ)QQQQQQUQQQUQQQ+QQQQQQ )Rz)U+R+RR-RRRRRRRzRRRzRRR)RRRRRRURRRURRR+RRRRRR	 , 	,1	ut	uU|	ut	uU|N #S!@c!JSw%SSSw%SSSSSSwSSSwSSS%SSS?3%r#>R!SSSSSSS KuD KKKuDKKKKKKuKKKuKKKDKKK"KKKKKKKMv~MMMvMMMMMMvMMMvMMMMMMMMMMMMMM	 #rD   c                  :   t        d      t        d      t        d      t        d      g} | D ]  }t        |d      }d}|j                  } |       }||v}|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}}d}|j                  } |       }||v}|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}}d}|j                  } |       }||v}|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}}d}|j                  } |       }||v}|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}}d}|j                  } |       }||v }|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}x}}  t        d      t        d      t        d      t        d      g}	|	D ]  }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  }
t        j                  d|       dz   d |
iz  }t        t        j                  |            dx}}d!}|j                  } |       }||v}|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}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  }
t        j                  d|       dz   d |
iz  }t        t        j                  |            dx}}d#}|j                  } |       }||v }|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d$      dz   d|iz  }t        t        j                  |            dx}x}x}} t        d%      t        d&      t        d'      g}|D ]  }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  }
t        j                  d*|       dz   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  }
t        j                  d,|       dz   d |
iz  }t        t        j                  |            dx}}d-}|j                  } |       }||v }|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d.      dz   d|iz  }t        t        j                  |            dx}x}x}} t        d/      }t        |d0      }d1}|j                  } |       }||v }|st        j                  d|fd||f      t        j
                  |      d	t        j                         v st        j                  |      rt        j
                  |      nd	t        j
                  |      t        j
                  |      d
z  }t        j                  d2      dz   d|iz  }t        t        j                  |            dx}x}x}}y)3zBTest error message sanitization to prevent information disclosure.z(UNIQUE constraint failed: users.usernamezBsqlite3.OperationalError: table users has no column named passwordz Database disk image is malformedzFOREIGN KEY constraint faileddatabasesqlitenot in)zH%(py1)s not in %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.lower
}()
}	sanitizedrV   zDatabase error leaked info: rY   rZ   Ntablecolumn
constraintu   greška pri obradi podatakarS   rU   z*Should have generic database error messagezPermission denied: /etc/passwdz.No such file or directory: /var/www/secret.txtz.Access is denied to C:\Windows\System32\configz&File not found: /home/user/.ssh/id_rsa
filesystemz/etc/)z%(py1)s not in %(py3)s)rW   r   zFile path leaked: r   r   zc:\z.sshu   greška pri pristupu datoteciz&Should have generic file error messagez*Connection timeout to internal-server:3306z"Network unreachable: 192.168.1.100zSocket connection failednetworkz192.168zIP address leaked: z:3306zPort number leaked: u   greška mrežez)Should have generic network error messagezSome random error messagegenericu   došlo je do greškez!Should have generic error message)	Exceptionr   rk   r%   r&   r*   r'   r(   r)   r+   r,   r-   )database_errorsrI   r~   rp   rq   rr   r7   rs   rt   filesystem_errorsr9   r:   network_errorsgeneric_errors                 rB   test_sanitize_error_messager      s    	<=VW4512	O !*5*=	\y\0\x00\\\x0\\\x\\\\\\y\\\y\\\\\\0\\\4PQZP[2\\\\\\\\[ioo[o/[w//[[[w/[[[w[[[[[[i[[[i[[[o[[[/[[[3OPY{1[[[[[[[[\y\0\x00\\\x0\\\x\\\\\\y\\\y\\\\\\0\\\4PQZP[2\\\\\\\\`9??`?#4`|#44```|#4```|``````9```9```?```#4```8TU^T_6````````,o	o0Ao,0AAooo,0Aooo,oooooo	ooo	oooooo0AoooCoooooooo ! 	23BCEF:;	 #*5,?	Iwi'IIIwiIIIwIIIIIIiIIIiIIII+=i[)IIIIIIIPY__P_.Pv..PPPv.PPPvPPPPPPYPPPYPPP_PPP.PPP2DYK0PPPPPPPPHvY&HHHvYHHHvHHHHHHYHHHYHHHH*<YK(HHHHHHH.m)//m/2Cm.2CCmmm.2Cmmm.mmmmmm)mmm)mmm/mmm2CmmmEmmmmmmmm # 	>?67,-N  *5)<	Ly	)LLLy	LLLyLLLLLL	LLL	LLLL-@+LLLLLLLKwi'KKKwiKKKwKKKKKKiKKKiKKKK+?	{)KKKKKKKa9??a?#4a#44aaa#4aaaaaaaaa9aaa9aaa?aaa#4aaa6aaaaaaaa	   9:M&}i@I![Y__[_%6[!%66[[[!%6[[[![[[[[[Y[[[Y[[[_[[[%6[[[8[[[[[[[[rD   c                  j   g d} | D ]  }t        |      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}d
}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}} g d}|D ]  }t        |      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}d
}||u}|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}d}	|j                  }
 |
       }|	|v }|st        j                  d|fd|	|f      t        j                  |	      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |
      t        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            d
x}	x}x}
} g d}|D ]  }t        |      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}d
}||u}|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}d}	|j                  }
 |
       }|	|v }|st        j                  d|fd|	|f      t        j                  |	      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |
      t        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            d
x}	x}x}
} g d}|D ]  }t        |      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d |       dz   d	|iz  }t        t        j                  |            d
x}}d
}||u}|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d!|       dz   d	|iz  }t        t        j                  |            d
x}} d"}t        |      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d#      dz   d	|iz  }t        t        j                  |            d
x}}d$}	|j                  }
 |
       }|	|v }|st        j                  d|fd|	|f      t        j                  |	      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |
      t        j                  |      dz  }t        j                  d%      dz   d|iz  }t        t        j                  |            d
x}	x}x}
}d&}t        |      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d'      dz   d	|iz  }t        t        j                  |            d
x}}d
}||u}|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d(      dz   d	|iz  }t        t        j                  |            d
x}}t        d)      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d*      dz   d	|iz  }t        t        j                  |            d
x}}t        d
      \  }}d}||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d+      dz   d	|iz  }t        t        j                  |            d
x}}y
),zFTest filename validation for security issues including path traversal.)z	image.jpgzcamera_photo_123.pngz%PICT_20231201_120000_123456789012.jpgztest_file.jpegzdocument.pdfTr   r   is_validr   zValid filename should pass: r   r   NrI   z&Valid filename should not have error: )z../../../etc/passwdz$..\..\..\windows\system32\config\samz....//....//....//etc/passwdzfile/../../../sensitive.txtz..%2f..%2f..%2fetc%2fpasswdFz"Path traversal should be blocked: rh   rj   z*Path traversal should have error message: zneispravno ime datotekerS   rU   rV   z'Should have generic error message for: rY   rZ   )	zmalicious.phpzscript.php3zbackdoor.aspz	shell.jspz
trojan.exez	virus.batzconfig.htaccesszsecrets.iniz
exploit.pyz'Dangerous extension should be blocked: z'Dangerous extension should have error: znedozvoljena vrsta datotekez!Should have file type error for: )zfile<script>.jpgzfile>redirect.jpgzfile|pipe.jpgzfile:stream.jpgzfile*wildcard.jpgzfile?query.jpgzfile"quote.jpgz&Special characters should be blocked: z&Special characters should have error: a0  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.jpgz'Overly long filename should be rejectedu   predugačkoz Should have length error messagez	file .jpgz%Null byte injection should be blockedz-Null byte injection should have error message z!Empty filename should be rejectedz None filename should be rejected)r   r%   r&   r'   r(   r)   r*   r+   r,   r-   rk   )valid_filenamesfilenamer   rI   r7   r8   r9   r:   path_traversal_filenamesrp   rq   rr   rs   rt   dangerous_filenamesspecial_char_filenameslong_filenamenull_byte_filenames                     rB   test_validate_filename_securityr      s   
O $4X>%Jx4JJJx4JJJJJJxJJJxJJJ4JJJ#?z!JJJJJJJQu}QQQuQQQQQQuQQQuQQQQQQ FxjQQQQQQQQ $  -4X>% Qx5 QQQx5QQQQQQxQQQxQQQ5QQQ$Fxj"QQQQQQQ YuD YYYuDYYYYYYuYYYuYYYDYYY$Nxj"YYYYYYY(oEKKoKMo(M9ooo(Mooo(ooooooEoooEoooKoooMooo=demdn;oooooooo	 -
 (4X>% Vx5 VVVx5VVVVVVxVVVxVVV5VVV$KH:"VVVVVVV VuD VVVuDVVVVVVuVVVuVVVDVVV$KH:"VVVVVVV,mmm,=mmm,mmm,mmmmmmmmmmmmmmmmmmAbckbl?mmmmmmmm	 ( +4X>% Ux5 UUUx5UUUUUUxUUUxUUU5UUU$J8*"UUUUUUU UuD UUUuDUUUUUUuUUUuUUUDUUU$J8*"UUUUUUUU + 'M0?OHeG8uGGG8uGGGGGG8GGG8GGGuGGGGGGGGGGMEKKMKMM=M)MMM=MMMM=MMMMMMEMMMEMMMKMMMMMMM+MMMMMMMM (01CDOHeE8uEEE8uEEEEEE8EEE8EEEuEEEEEEEEEEM5MMM5MMMMMM5MMM5MMMMMMMMMMMMM 14OHeA8uAAA8uAAAAAA8AAA8AAAuAAAAAAAAAA06OHe@8u@@@8u@@@@@@8@@@8@@@u@@@@@@@@@@rD   c            	         t        d      D  cg c]  } t                }} t        |      }t        |      }d}||k(  }|sit	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      t	        j                  |      dz  }t	        j                  d      d	z   d
|iz  }t        t	        j                  |            dx}x}x}}|dd D ]k  }t        |      }	d}|	|k\  }
|
st	        j
                  d|
fd|	|f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |	      t	        j                  |      dz  }t	        j                  dt        |       d      dz   d|iz  }t        t	        j                  |            dx}	x}
}t        |      }	d}|	|k  }
|
st	        j
                  d|
fd|	|f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |	      t	        j                  |      dz  }t	        j                  dt        |       d      dz   d|iz  }t        t	        j                  |            dx}	x}
}n t        d      }t        d      }t        |      }	d}|	|k\  }
|
st	        j
                  d|
fd|	|f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |	      t	        j                  |      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}	x}
}t        |      }	d}|	|k\  }
|
st	        j
                  d|
fd|	|f      dt        j                         v st	        j                  t              rt	        j                  t              ndd t        j                         v st	        j                  |      rt	        j                  |      nd t	        j                  |	      t	        j                  |      dz  }t	        j                  d!      dz   d|iz  }t        t	        j                  |            dx}	x}
}d"dl}t        |j                  |j                  z   d#z         }|dd D ]L  }t        |j!                  d$            }||z
  }t        |      }	d"}|	|k(  }
|
st	        j
                  d|
fd%|	|f      dt        j                         v st	        j                  t              rt	        j                  t              ndd&t        j                         v st	        j                  |      rt	        j                  |      nd&t	        j                  |	      t	        j                  |      dz  }t	        j                  d'|       dz   d|iz  }t        t	        j                  |            dx}	x}
}O yc c} w )(z8Test secure token generation for cryptographic strength.d   rJ   )zN%(py6)s
{%(py6)s = %(py0)s(%(py4)s
{%(py4)s = %(py1)s(%(py2)s)
})
} == %(py9)sr3   settokens)r   rW   rc   py4py6rZ   z%All generated tokens should be uniquez
>assert %(py11)spy11Nr   (   >=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)stoken)r   rW   r   r   zToken too short: z chars
>assert %(py8)spy82   <=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} <= %(py6)szToken too long:    @      short_tokenz&Short token should be encoded properlyP   
long_tokenz%Long token should be encoded properlyr   z-_=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sinvalid_charsz#Token contains invalid characters: )r.   r   r   r3   r%   r&   r'   r(   r)   r*   r+   r,   r-   stringascii_lettersdigitsrstrip)r=   r   @py_assert3@py_assert5@py_assert8@py_assert7rt   @py_format12r   r7   rq   @py_format7@py_format9r   r   r   valid_charstoken_charsr   s                      rB   test_generate_secure_tokenr   G  s   
 05Sz:z!#%zF: 6{K3{KsKs"KKKsKKKKKK3KKK3KKKKKKsKKKsKKKKKK6KKK6KKK{KKKKKKsKKK$KKKKKKKK 5zGRGzRGGGzRGGGGGGsGGGsGGGGGG5GGG5GGGzGGGRGGG#4SZL!GGGGGGGG5zFRFzRFFFzRFFFFFFsFFFsFFFFFF5FFF5FFFzFFFRFFF#3CJ<v!FFFFFFFF 
 (+K&r*J{KrKr!KKKrKKKKKK3KKK3KKKKKK{KKK{KKKKKKrKKK#KKKKKKKKz?IbI?b III?bIIIIII3III3IIIIIIzIIIzIII?IIIbIII"IIIIIIII f**V]]:TABK%,,s+,#k1=!]Q]!Q&]]]!Q]]]]]]s]]]s]]]]]]=]]]=]]]!]]]Q]]]*Mm_(]]]]]]]] + ;s   `	c            	         d} d}t        j                  | j                  d      |j                  d      t        j                        j                         }t        |||       }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	      d
z   d|iz  }t        t        j                  |            dx}}d}t        |||       }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d
z   d|iz  }t        t        j                  |            dx}}d}	t        |	||       }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d
z   d|iz  }t        t        j                  |            dx}}d}
t        |||
      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d
z   d|iz  }t        t        j                  |            dx}}d|| f|d| f||dfd|| f|d| fg}|D ]  \  }}}	 t        |||      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d| d| d|       d
z   d|iz  }t        t        j                  |            dx}} y# t         $ r Y w xY w)z<Test HMAC token verification for integrity and authenticity.test_secret_key_12345user_data_to_signr   Tr   r   r   r   z+Valid HMAC token should verify successfullyr   r   Ninvalid_token_12345Fz+Invalid HMAC token should fail verificationmodified_user_dataz+Modified data should fail HMAC verificationwrong_secret_keyz)Wrong secret key should fail verificationr   zMalformed input should fail: rQ   )hmacnewr"   hashlibsha256	hexdigestr   r%   r&   r'   r(   r)   r*   r+   r,   r-   r   )
secret_keydatavalid_tokenr   r7   r8   r9   r:   invalid_tokenmodified_datawrong_secretmalformed_tests	test_data
test_tokentest_secrets                  rB   test_verify_hmac_tokenr   g  s   
 )JD (('"G ik	  !{J?HJ8tJJJ8tJJJJJJ8JJJ8JJJtJJJJJJJJJJ *M }jAHK8uKKK8uKKKKKK8KKK8KKKuKKKKKKKKKK )M ZHHK8uKKK8uKKKKKK8KKK8KKKuKKKKKKKKKK &L {LAHI8uIII8uIIIIII8III8IIIuIIIIIIIIII 
[*%	r:	{B	{J'	tZ O />*	:{	(JLH$n8u$nnn8unnnnnn8nnn8nnnunnn(Ei[PRS]R^^`al`m&nnnnnnn />  		s   CQ00	Q<;Q<c                     t        dd      D  cg c]  } t        |        }} t        dt        |            D ]  } ||    }|| dz
     }||k\  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }t        j                  d|| dz
      d||           dz   d	|iz  }t        t        j                  |            d
x}x}} |d   }d}||k(  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }t        j                  d|d          dz   d	|iz  }t        t        j                  |            d
x}x}}d}t        |      }d}||k(  }	|	st        j                  d|	fd||f      dt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |      t        j
                  |      t        j
                  |      dz  }
t        j                  d      dz   d|
iz  }t        t        j                  |            d
x}x}x}	}d}| }t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |      t        j
                  |      t        j
                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            d
x}x}x}x}}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  }t        j                  d!|       d"z   d#|iz  }t        t        j                  |            d
x}}t        d      }t        d$      }t        d%      }d$}||z  }	||	k(  }|st        j                  d|fd&||	f      d't        j                         v st        j                  |      rt        j
                  |      nd'd(t        j                         v st        j                  |      rt        j
                  |      nd(t        j
                  |      d)z  }t        j                  d*| d|       d+z   d,|iz  }
t        t        j                  |
            d
x}x}}	d-}||z  }	||	k(  }|st        j                  d|fd&||	f      d.t        j                         v st        j                  |      rt        j
                  |      nd.d(t        j                         v st        j                  |      rt        j
                  |      nd(t        j
                  |      d)z  }t        j                  d/| d|       d+z   d,|iz  }
t        t        j                  |
            d
x}x}}	y
c c} w )0z7Test exponential backoff calculation for rate limiting.rd      r   )z%(py1)s >= %(py4)srW   r   zDelay should increase: z -> 
>assert %(py6)sr   Nr      rJ   z%(py1)s == %(py4)sz.First attempt should have 5 second delay, got )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr	   )r   rc   r   rX   z$Zero attempts should have zero delayrY   rZ   )z1%(py5)s
{%(py5)s = %(py0)s(-%(py2)s)
} == %(py8)s)r   rc   r   r   z(Negative attempts should have zero delayz
>assert %(py10)spy10r   i  r   )z%(py0)s <= %(py3)s
high_delayr   z&Delay should be capped at 1 hour, got r   r         )z%(py0)s == (%(py2)s * %(py4)s)delay2delay1r   rc   r   zDelay should double: 
>assert %(py7)srX      delay3zDelay should quadruple: )r.   r	   r3   r%   r&   r*   r+   r,   r-   r'   r(   r)   )idelaysrp   r   r7   @py_format5r   r8   rr   r   rs   rt   rq   r   r   @py_format11r   r9   r:   r   r   r   s                         rB   (test_rate_limit_with_exponential_backoffr     s   
 ?DArlKl1!4lFK 1c&k"ay_F1Q3K_yK'___yK___y___K___+B6!A#;-tTZ[\T]S^)________ # !9WW9>WWW9WWW9WWWWWWKFSTI;WWWWWWWW 01^.q1^Q^1Q6^^^1Q^^^^^^.^^^.^^^q^^^1^^^Q^^^8^^^^^^^^01crc.r2cac2a7ccc2acccccc.ccc.cccccc2cccaccc9cccccccc 5R8JT:TTT:TTTTTT:TTT:TTTTTT!G
|TTTTTTT 13F03F03FMVaZM6ZMMM6ZMMMMMM6MMM6MMMMMMVMMMVMMMaMMM#8VH!MMMMMMMMPVaZP6ZPPP6ZPPPPPP6PPP6PPPPPPVPPPVPPPaPPP#;F84x!PPPPPPPP/ Ls   Zc                     t         ddddt         ddddt         ddddd} d	d
dd}t        ||       \  }}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      nddz  }	t        j                  d      dz   d|	iz  }
t        t        j                  |
            d}dd	i}t        ||       \  }}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d       dz   d|iz  }t        t        j                  |            dx}}d}||u}|st        j                  d!|fd"||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d#      dz   d|iz  }t        t        j                  |            dx}}d$}|j                  } |       }||v }|st        j                  d%|fd&||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d'z  }t        j                  d(      d)z   d*|iz  }t        t        j                  |            dx}x}x}}d+d
d,dd-fd.d
d,dd/fd0d1d,dd-fd0d2d,dd/fg}|D ]  \  }}t        ||       \  }}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d3|       dz   d|iz  }t        t        j                  |            dx}}|j                  } |       }||v }|st        j                  d%|fd4||f      d5t	        j
                         v st        j                  |      rt        j                  |      nd5dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d6z  }t        j                  d7|       d8z   d9|iz  }t        t        j                  |            dx}x}} d0d
d:dd0d
d;dd0d
d<dd0d
d=dd0d
d>dg}|D ]  }t        ||       \  }}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d?|       dz   d|iz  }t        t        j                  |            dx}}d}||u}|st        j                  d!|fd"||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d@|       dz   d|iz  }t        t        j                  |            dx}}dA}|j                  } |       }||v }|st        j                  d%|fd&||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d'z  }t        j                  dB|       d)z   d*|iz  }t        t        j                  |            dx}x}x}} d	dCdd}t        ||       \  }}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  dD      dz   d|iz  }t        t        j                  |            dx}}|dE   }t        |t               }|st        j                  dF      dGz   dHt	        j
                         v st        j                  t              rt        j                  t              ndHt        j                  |      dIt	        j
                         v st        j                  t               rt        j                  t               ndIt        j                  |      dJz  }t        t        j                  |            dx}}dK}t        ||       \  }}}d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  dL      dz   d|iz  }t        t        j                  |            dx}}dM}|j                  } |       }||v }|st        j                  d%|fd&||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d'z  }t        j                  dN      d)z   d*|iz  }t        t        j                  |            dx}x}x}}y)Oz:Test API input validation with security pattern detection.Tr       )typerequired
min_length
max_length   rd   r   )r   	camera_idcamera_nametestuser123123456789012zTest Camerar   r   r   r   z"Valid input should pass validationr   r   NrI   z!Valid input should not have errorrJ   )z%(py0)s == %(py2)sr~   
valid_datar   rc   z(Valid input should be returned unchanged
>assert %(py4)sr   r   Fz#Missing required fields should failrh   rj   z(Missing fields should have error messageobaveznorS   rU   rV   z(Should have required field error messagerY   rZ   xyTest	prekratak2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxu   predugačakr   123451234567890123z#Length validation should fail for: )zD%(py0)s in %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s.lower
}()
}expected_error)r   rc   r   r   zShould have length error for: r   r   z<script>alert("xss")</script>z'; DROP TABLE cameras; --z UNION SELECT password FROM userszjavascript:alert("xss")zonload=alert("xss")z#Malicious input should be blocked: z#Malicious input should have error: zneispravna vrijednostz%Should have invalid value error for: l   2}r z0Type conversion should work for compatible typesr   z'Camera ID should be converted to stringr_   r`   strrb   znot a dictionaryz!Non-dict input should be rejectedzneispravni podacizShould have invalid data error)r   r
   r%   r&   r'   r(   r)   r*   r+   r,   r-   rk   r`   )test_schemar   r   rI   r~   r7   r8   r9   r:   @py_format3r   incomplete_datarp   rq   rr   rs   rt   length_testsr   r   r   r   r   r   malicious_inputsmalicious_datatype_conversion_datainvalid_datas                               rB   test_validate_api_inputr    sw    	
 	
 	
K. "#$J "4J!LHeYA8tAAA8tAAAAAA8AAA8AAAtAAAAAAAAAA=5D====5D======5===5===D==========
"NNN9
NNNNNN9NNN9NNNNNN
NNN
NNNN$NNNNNNN 	MO
 "4O[!QHeYC8uCCC8uCCCCCC8CCC8CCCuCCCCCCCCCCH5HHH5HHHHHH5HHH5HHHHHHHHHHHHHRRR:&RRR:RRR:RRRRRRRRRRRRRRRRRR(RRRRRRRR 	OQ\]^F	SUbc wv	NP[\ v	VXef	L &2!	>%7	;%O"% Sx5 SSSx5SSSSSSxSSSxSSS5SSS$G	{"SSSSSSS!&\\~.\\\~\\\\\\~\\\~\\\\\\\\\\\\\\\\\\2PQZP[0\\\\\\\\ &2  nMlmnMhinMopnMfgnMbc +%7%T"% Xx5 XXXx5XXXXXXxXXXxXXX5XXX$GGW"XXXXXXX XuD XXXuDXXXXXXuXXXuXXXDXXX$GGW"XXXXXXX&q%++q+-q&-7qqq&-qqq&qqqqqq%qqq%qqq+qqq-qqq;`ao`p9qqqqqqqq	 + "!$ "44H+!VHeYO8tOOO8tOOOOOO8OOO8OOOtOOOOOOOOOO,]:,c2]2]]4]]]]]]]:]]]:]]],]]]]]]c]]]c]]]2]]]]]] &L!3L+!NHeYA8uAAA8uAAAAAA8AAA8AAAuAAAAAAAAAAQ%++Q+-Q-/QQQ-QQQQQQQQQ%QQQ%QQQ+QQQ-QQQ1QQQQQQQQrD   c                  $
    G d d      }  |        }t        |      }g d}|D ]  }|j                  }||v }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	|       d
z   d|iz  }t        t        j                  |            dx}} |j                  d   }	g d}
|
D ]  }||	v }|st        j                  d|fd||	f      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |	      rt        j                  |	      nddz  }t        j                  d|       dz   d|iz  }t        t        j                  |            d} |j                  d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d      d
z   d|iz  }t        t        j                  |            dx}x}}|j                  d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d      d
z   d|iz  }t        t        j                  |            dx}x}}d}|j                  d    }||v }|st        j                  d|fd!||f      t        j                  |      t        j                  |      dz  }t        j                  d"      d
z   d|iz  }t        t        j                  |            dx}x}} |        }d#|j                  d$<   t        |      }d$}|j                  }||v}|st        j                  d%|fd&||f      t        j                  |      d't	        j
                         v st        j                  |      rt        j                  |      nd't        j                  |      d(z  }t        j                  d)      d*z   d+|iz  }t        t        j                  |            dx}x}}y),z/Test security headers middleware functionality.c                       e Zd Zd Zy)6test_security_headers_middleware.<locals>.MockResponsec                     i | _         y )N)headers)selfs    rB   __init__z?test_security_headers_middleware.<locals>.MockResponse.__init__  s	    DLrD   N)__name__
__module____qualname__r   rD   rB   MockResponser	    s    	rD   r  )Content-Security-PolicyX-Frame-OptionsX-Content-Type-OptionsX-XSS-ProtectionzReferrer-PolicyzPermissions-PolicyrS   )z/%(py0)s in %(py4)s
{%(py4)s = %(py2)s.headers
}headerenhanced_responser   z"Required security header missing: r   r   Nr  )	zdefault-src 'self'zscript-src 'self'zstyle-src 'self'zimg-src 'self'zfont-src 'self'zconnect-src 'self'zframe-ancestors 'none'zbase-uri 'self'zform-action 'self')z%(py0)s in %(py2)s	directivecspr   zCSP directive missing: r   r   r  DENYrJ   r   r   z#X-Frame-Options should deny framingr  nosniffzShould prevent MIME sniffingz
mode=blockr  )z%(py1)s in %(py4)sz#XSS protection should block attackszFlask/2.0.1 Werkzeug/2.0.1Serverr|   )z3%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.headers
}enhanced)rW   r   r   zServer header should be removedr   rX   )r   r  r%   r&   r'   r(   r)   r*   r+   r,   r-   )r  responser  required_headersr  r   r8   r   r   r  csp_directivesr  r   rp   r7   response_with_serverr  rq   r:   rs   s                       rB    test_security_headers_middlewarer#    sE   
  ~H 4H= #*22av22aaav2aaaaaavaaavaaaaaa*aaa*aaa2aaa6XY_X`4aaaaaaaa # 
#
#$=
>C
N $	CFFFyCFFFFFFyFFFyFFFFFFCFFFCFFFF#:9+!FFFFFFF $ $$%67h6h76Ahhh76hhh7hhh6hhhChhhhhhhh$$%=>k)k>)Kkkk>)kkk>kkk)kkkMkkkkkkkko,445GHo<HHooo<Hooo<oooHoooJoooooooo (>-I  **+?@HN8++N8++NNN8+NNN8NNNNNN8NNN8NNN+NNN-NNNNNNNNrD   ) __doc__builtinsr'   _pytest.assertion.rewrite	assertionrewriter%   pytestr/   r   r   !app_modules.security_enhancementsr   r   r   r   r   r   r	   r
   r   marksecurityrC   rx   r   r   r   r   r   r  r#  r  rD   rB   <module>r-     sU  0     
 
 
 6A 6Ar QN QNh 2\ 2\j TA TAn ^ ^> 0 0f Q Q< [R [R| 6O 6OrD   