a oe@sdZddlZddlZddlmZddlZddlZddlm Z ddl Z ddl m Z ddl Z ddlZddlZddlmZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZed ZedZe j edZ!e"ddddej"#dZ$Gddde j%Z&Gddde j'Z(Gddde j%Z)Gddde j%Z*e+dkr|e,e-ej.dde/gdS)zTests for acme.client.N)Dict)mock) challenges)errors)jws)messages) messages_test) test_util) ClientNetwork)ClientV2z cert-san.pemz csr-mixed.pemzrsa512_key.pemz1https://www.letsencrypt-demo.org/acme/new-account/https://www.letsencrypt-demo.org/acme/new-noncez/https://www.letsencrypt-demo.org/acme/new-orderz1https://www.letsencrypt-demo.org/acme/revoke-cert) newAccountnewNonceZnewOrder revokeCertmetac@sTeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ e dddZe dddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Z d9d:Z!e dd;d<Z"e dd=d>Z#e dd?d@Z$e ddAdBZ%dCdDZ&dES)F ClientV2TestzTests for acme.client.ClientV2.cCstjdtjiid|_t|_|j|jj_|j|jj_t j t j dd|_ d|_ t j|j td}t|}t jfi||_t j|dd|_d }t j|d t jtjtd d d }t j||d|_t jt j t j dd|fd|_t j |j|d|_!d|_"t#|_$t%|j$|j|_&|jj'dd|_d|_(|jj't j t j ddt j)d|_*t j |j*|j(d|_+t j,|jj |j*j ft j)|j!j-|j(fdd|_.t j/|j.d|j!|j+gt0d|_1dS)NT)ok status_codeheaderslinksz example.com)typvalue)zmailto:cert-admin@example.comztel:+12025551212)contactkey+https://www.letsencrypt-demo.org/acme/reg/1bodyuriz-https://www.letsencrypt-demo.org/acme/authz/1z/1z+evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA)token)rstatusZchall)r authzr_uri) identifierr)Zterms_of_service_agreedz-https://www.letsencrypt-demo.org/acme/authz/2zwww.example.com)r!rz=https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize)Z identifiersrauthorizationsfinalizez4https://www.letsencrypt-demo.org/acme/acct/1/order/1)rrr#Zcsr_pem)2r MagicMock http_clientOKresponsenetpost return_valuegetrZ IdentifierZIDENTIFIER_FQDNr!rZ RegistrationKEYZ public_keydictZNewRegistrationnew_regZRegistrationResourceregrZ ChallengeBody STATUS_VALIDrZDNSjose b64decodeZChallengeResourcechallrZ AuthorizationauthzAuthorizationResourceauthzrrsn DIRECTORY_V2 directoryr clientupdate authzr_uri2ZSTATUS_PENDINGauthz2authzr2ZOrderrorderZ OrderResource CSR_MIXED_PEMorderr)selfZregZthe_argr challbrEAC:\Program Files\Certbot\pkgs\acme\_internal\tests\client_test.pysetUp)sz         zClientV2Test.setUpcCsHtj|j_|jj|jj_|jj |jj d<|j|j |j ksDJdSNLocation)r&CREATEDr(rr0rto_jsonjsonr+rrr; new_accountr/rCrErErFtest_new_accountes zClientV2Test.test_new_accountcCs^tj|j_|jj|jj_|jj |jj d<|jj dddii|j |jjdksZJdS)NrIzterms-of-serviceurlz$https://www.letsencrypt-demo.org/tos)r&rJr(rr0rrKrLr+rrrr<r;rMr/Zterms_of_servicerNrErErFtest_new_account_tos_linkls z&ClientV2Test.test_new_account_tos_linkcCsXtj|j_|jj|jjd<tt j |j |j Wdn1sJ0YdSrH)r&r'r(rr0rrpytestraisesr ConflictErrorr;rMr/rNrErErFtest_new_account_conflictxs z&ClientV2Test.test_new_account_conflictcCs^|jj|jjjddd}|j|jj_tj|j_ |jj |jj d<|j |j|ksZJdS)NZ deactivatedrrrI)r0r<rrKr(rLr+r&r'rrrr;Zdeactivate_registration)rCZdeactivated_regrrErErFtest_deactivate_account~s z$ClientV2Test.test_deactivate_accountcCs|jj|jjjtjdd}|j|jj_|j |j}|j|jksJJ|j j j j dks^J|jj|j j jddvs|JdS)NrVrWr"r)r7r<rrZSTATUS_DEACTIVATEDrKr(rLr+r;Zdeactivate_authorizationr)r* call_countrcall_args_list)rCZdeactivated_authzr7rErErFtest_deactivate_authorizationsz*ClientV2Test.test_deactivate_authorizationcCst|j}tj|_|j|j_ |j j |j d<||j j_ t|j}|j|j_ |jj |j d<|j}|j|j_ |jj |j d<td0}||f|_|jt|j ksJWdn1s0YdS)NrIz!acme.client.ClientV2._post_as_get)copydeepcopyr(r&rJrr@rKrLr+rBrrr)r*r5r7r>r?rpatch side_effectr;Z new_orderrA)rCZorder_responseZauthz_responseZauthz_response2Zmock_post_as_getrErErFtest_new_orders     zClientV2Test.test_new_ordercCsd|jji|jjd<|jj|jj_tj dd}|j |jj|t tj*|j |jjjdd|Wdn1s0YdS)NrPZupZ validationfoo)r)r4r r(rrrKrLr+r DNSResponser;answer_challengerRrSrUnexpectedUpdater<)rCZchall_responserErErFtest_answer_challeges  z!ClientV2Test.test_answer_challegecCsJttj*|j|jjtj ddWdn1s<0YdS)Nra) rRrSr ClientErrorr;rdr4rrrcrNrErErF"test_answer_challenge_missing_nextsz/ClientV2Test.test_answer_challenge_missing_nextzacme.client.datetimecCstddd|jj_tj|_|jtjdd}tj|jd|j_tj|jd|j_ |j |j|jksnJ|jj |j||jj |j|dS)NZZsecondsr+) datetimenowr+ timedeltarZMockrBr;poll_authorizationsfinalize_orderZpoll_and_finalizeassert_called_once_with)rC mock_datetimeZexpected_deadlinerErErFtest_poll_and_finalizesz#ClientV2Test.test_poll_and_finalizecCstdddtdddtdddg}||jj_|j|j|jg|jj_t t j $|j |j|dWdn1s0YdS)Nrirjrkr")rorpr_r5rKr>r(rLrRrSr TimeoutErrorr;rrrB)rCruZnow_side_effectrErErF test_poll_authorizations_timeouts     z-ClientV2Test.test_poll_authorizations_timeoutcCstddd}|jjjtjtjdd}|jjtj|fd}| |j j _ t tj |j|j|Wdn1s~0YdS)N' unauthorized)rerror)rr)ror4rr<rSTATUS_INVALIDError with_coder5rKr(rLr+rRrSrZValidationErrorr;rrrB)rCdeadlinerDr5rErErF test_poll_authorizations_failures  z-ClientV2Test.test_poll_authorizations_failurecCs~tddd}|jjtjd}tj||jd}|jj|j|gd}|j |j | f|j j _ |j|j||kszJdS)Nr{r|rVr)r#)ror>r<rr1r6r=rBr7r5rKr(rLr_r;rr)rCrZupdated_authz2Zupdated_authzr2updated_orderrrErErF test_poll_authorizations_successs z-ClientV2Test.test_poll_authorizations_successcCsd|jj|jjddd}||jj_tt j |j |j Wdn1sV0YdS)Nrbr)r!)r5r<r!rKr(rLr+rRrSrrer;pollr7)rCZ updated_authzrErErFtest_poll_unexpected_updatesz(ClientV2Test.test_poll_unexpected_updatecCsb|jjdtjd}|jj|td}||jj_ t|j_ t ddd}|j |j||ks^JdS)N+https://www.letsencrypt-demo.org/acme/cert/Z certificater)r fullchain_pemr{r|)r@r<rr1rB CERT_SAN_PEMrKr(rLr+textror;rs)rC updated_orderrrrErErFtest_finalize_order_successsz(ClientV2Test.test_finalize_order_successcCsv|jjtjdtjd}||jj_ t ddd}t t j |j|j|Wdn1sh0YdS)Nr}r~rr{r|)r@r<rrrrrKr(rLr+rorRrSrZ IssuanceErrorr;rsrB)rCrrrErErFtest_finalize_order_errors z&ClientV2Test.test_finalize_order_errorc Csn|jjdtjd}||jj_tj t j dd*|j |jtdddWdn1s`0YdS)NrzThe certificate order failed)matchr{r|)r@r<rrrKr(rLr+rRrSrrr;rsrBro)rCr@rErErF"test_finalize_order_invalid_statussz/ClientV2Test.test_finalize_order_invalid_statuscCsVtjtjdd}ttj |j|j |Wdn1sH0YdS)N<rm) rorprqrRrSrryr;rsrB)rCrrErErFtest_finalize_order_timeoutsz(ClientV2Test.test_finalize_order_timeoutcCs|jjdtjd}|jj|tttgd}||jj_ t|j_ d|jj d<t ddd}|j j|j|dd }|jjjd tjtjd |jjjd tjtjd ||ksJ|jj d=|j j|j|dd }||jgd ksJdS)Nrr)rralternative_fullchains_pemz;rel="alternate", ;rel="index", ;title="foo";rel="alternate"ZLinkr{r|T)Zfetch_alternative_chainszhttps://example.com/acme/cert/1 new_nonce_urlzhttps://example.com/acme/cert/2)r)r@r<rr1rBrrKr(rLr+rrror;rsr)r*Zassert_any_callrANY)rCrrrZresprErErFtest_finalize_order_alt_chainss2     z+ClientV2Test.test_finalize_order_alt_chainscCs6|jtj|j|jjj|jdt j t dddS)Nrrr) r;revokerCERTr8r)r*rtr:rrr9rNrErErF test_revokeszClientV2Test.test_revokecCsLtj|j_ttj"|j t j |j Wdn1s>0YdSN) r&METHOD_NOT_ALLOWEDr(rrRrSrrgr;rrrr8rNrErErF#test_revoke_bad_status_raises_error$s   z0ClientV2Test.test_revoke_bad_status_raises_errorcCs|jj|jjd<|jj|jj_|j|j |jks:J|jj j dusLJ|jj j j dks`Jtj|j j jddvs|J|jjjdd|jj_dS)NrIrjrrE)r)r0rr(rrrKrLr+r;Zupdate_registrationr)accountr*rYr9r rZr<rNrErErFtest_update_registration*sz%ClientV2Test.test_update_registrationcCs.tdtjjddi|j_|js*JdS)NrTexternal_account_requiredr DirectoryMetar;r:rrNrErErF#test_external_account_required_true6s z0ClientV2Test.test_external_account_required_truecCs.tdtjjddi|j_|jr*JdS)NrFrrrNrErErF$test_external_account_required_false=s z1ClientV2Test.test_external_account_required_falsecCs|jrJdSr)r;rrNrErErF&test_external_account_required_defaultDsz3ClientV2Test.test_external_account_required_defaultcCs:|jj|jj_d|jjd<|j|j|jks6JdS)NrrI) r0rrKr(rLr+rr;Zquery_registrationrNrErErFtest_query_registration_clientGs z+ClientV2Test.test_query_registration_clientcCsltdN}|j|_|j|j|jjjj|jj ddd|jjj Wdn1s^0YdS)Nz*acme.client.ClientV2._authzr_from_responser r) rr^r?r+r;rr)r*rtrr,Zassert_not_called)rCZ mock_clientrErErFtest_post_as_getLs  zClientV2Test.test_post_as_getcCs:d|jjd<tdddddd|jj|jdd ks6JdS) NzFri, 31 Dec 1999 23:59:59 GMT Retry-Afteri ; r(default)r(rror; retry_afterrNrErErFtest_retry_after_dateWs z"ClientV2Test.test_retry_after_datecCsVtddd|jj_tj|_d|jjd<tdddddd|jj|jddksRJdS) NZfoooorrrrrorpr+rqr(rr;rrCZdt_mockrErErFtest_retry_after_invalid\s  z%ClientV2Test.test_retry_after_invalidcCs`tddd|jj_tj|_tj|j_d|jjd<tdddddd|jj|jddks\JdS) NrrrzTue, 116 Feb 2016 11:50:00 MSTrrrr) rorpr+rqr_r(rr;rrrErErFtest_retry_after_overflowes  z&ClientV2Test.test_retry_after_overflowcCsVtddd|jj_tj|_d|jjd<tdddddd|jj|jdd ksRJdS) NrrrZ50rr2rrrrrErErFtest_retry_after_secondsos  z%ClientV2Test.test_retry_after_secondscCsJtddd|jj_tj|_tdddddd|jj|jddksFJdS)Nrrrrrr)rorpr+rqr;rr(rrErErFtest_retry_after_missingxs z%ClientV2Test.test_retry_after_missingcCs0t|jj_ttd|jks,JdS)Nzhttps://example.com/dir) r9rKr(rLr+to_partial_jsonr Z get_directoryr)rNrErErFtest_get_directoryszClientV2Test.test_get_directoryN)'__name__ __module__ __qualname____doc__rGrOrQrUrXr[r`rfrhrr^rvrzrrrrrrrrrrrrrrrrrrrrrrrErErErFr&sP<               rc@s(eZdZddZddZeddZdS)MockJSONDeSerializablecCs ||_dSrr)rCrrErErF__init__szMockJSONDeSerializable.__init__cCs d|jiS)NrbrrNrErErFrsz&MockJSONDeSerializable.to_partial_jsoncCsdSrrE)clsZjobjrErErF from_jsonsz MockJSONDeSerializable.from_jsonN)rrrrr classmethodrrErErErFrsrc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ e dddZe dddZddZddZddZe ddd Zd!d"Zd#d$Zd%d&Zd'd(Zd3d*d+Zd,d-Ze d.d/d0Zd1d2Zd)S)4ClientNetworkTestz$Tests for acme.client.ClientNetwork.cCsXt|_tjtjjd|_tttj |jdd|_ tjdt j d|_ i|j _i|j _dS)Nrnacme-python-test)ralg verify_sslZ user_agentTrr)rr%rsentinelwrappedZ wrap_in_jwsr r-r2ZRS256r)r&r'r(rrrNrErErFrGs  zClientNetworkTest.setUpcCs|jj|jusJdSr)r)rrNrErErF test_initszClientNetworkTest.test_initcCsT|jjtdddd}tj|}t|j ddiks>J|j j j dksPJdS)NrbTgrPnoncerP) r) _wrap_in_jwsracme_jwsJWS json_loadsrLloadspayloaddecode signaturecombinedrrCZjws_dumprrErErFtest_wrap_in_jwss   z"ClientNetworkTest.test_wrap_in_jwscCsddi|j_|jjtdddd}tj|}t|j ddiksJJ|j j j dks\J|j j jdksnJ|j j jdksJdS)Nrzacct-urirbrrPr)r)rrrrrrrLrrrrrrZkidrPrrErErFtest_wrap_in_jws_v2s   z%ClientNetworkTest.test_wrap_in_jws_v2c Csd|j_i|jj_tdR}tj|_t t j |j |jWdn1sV0YWdn1st0YdS)NFz$acme.client.messages.Error.from_json)r(rrLr+rr^r2ZDeserializationErrorr_rRrSrrgr)_check_response)rCrrErErF(test_check_response_not_ok_jobj_no_errors   z:ClientNetworkTest.test_check_response_not_ok_jobj_no_errorcCsbd|j_tjjdddd|jj_t tj|j |jWdn1sT0YdS)NFZserverInternalrbz some title)Zdetailtitle) r(rrrrrKrLr+rRrSr)rrNrErErF%test_check_response_not_ok_jobj_errors z7ClientNetworkTest.test_check_response_not_ok_jobj_errorcCsPd|j_t|jj_ttj|j |jWdn1sB0YdS)NF) r(r ValueErrorrLr_rRrSrrgr)rrNrErErF"test_check_response_not_ok_no_jobjs z4ClientNetworkTest.test_check_response_not_ok_no_jobjc Csnt|jj_|jjdfD]R}||jjd<tt j &|jj |j|jjdWdq1s^0YqdS)Nrb Content-Type content_type) rr(rLr_r)JSON_CONTENT_TYPErrRrSrrgrrCZ response_ctrErErF*test_check_response_ok_no_jobj_ct_requireds   z.send_request)r_rn)r r)rr%r&r'r(rrcheckedrr#objZ wrapped_objrrr2 b64encode all_noncesr$rr)check_responserr)rCr)rErNrFrGzs,     z)ClientNetworkWithMockedResponseTest.setUpcCs6|j|ksJ|j|ksJ|jjs(Jd|j_|jS)NT)r(rrr*)rCr(rrErErFr.s  z2ClientNetworkWithMockedResponseTest.check_responsecCs4|j|jjddddksJ|jjddddddS)Nrrbrrr)r#r)headr)rtrNrErErF test_heads   z-ClientNetworkWithMockedResponseTest.test_headcCs4|j|jjddddksJ|jjddddddS)Nr"rbrrr)r(r)r/r)rtrNrErErF test_head_v2s   z0ClientNetworkWithMockedResponseTest.test_head_v2cCs@|j|jjd|jddksJ|jjs*J|jjdddddS)Nrr)rrr r)r(r)r,rr*r)rtrNrErErFtest_gets   z,ClientNetworkWithMockedResponseTest.test_getcCs4|jj|_|j|jd|jks$J|jjs0JdS)Nr)r)ZJOSE_CONTENT_TYPErr(r*r+r*rNrErErFtest_post_no_content_types z=ClientNetworkWithMockedResponseTest.test_post_no_content_typecCs|j|jjd|j|jdks J|jjs,J|jj|jt |j dg|_ t tj&|jjd|j|jdWdn1s0Y|jj|jt |j ddS)Nrr)r(r)r*r+rr*rrtr2r3r-r%r$rRrSrZ MissingNoncerrNrErErF test_posts   4z-ClientNetworkWithMockedResponseTest.test_postcCsVdtdg|_ttj&|jjd|j |j dWdn1sH0YdS)Nfgoodrr r2r,r$rRrSrZBadNoncer)r*r+rrNrErErFtest_post_wrong_initial_nonces zAClientNetworkWithMockedResponseTest.test_post_wrong_initial_noncecCsVtddg|_ttj&|jjd|j |j dWdn1sH0YdS)Nr6r5rrr7rNrErErF#test_post_wrong_post_response_nonces zGClientNetworkWithMockedResponseTest.test_post_wrong_post_response_noncecCsdt}tjd|_||j_t tj&|jj d|j |j dWdn1sV0YdSNZbadNoncerr) rr%rrrr_r)rrRrSr*r+rrCr.rErErFtest_post_failed_retrysz:ClientNetworkWithMockedResponseTest.test_post_failed_retrycCsjt}tjd|jg|_||j_t tj&|jj d|j |j dWdn1s\0YdS)NZ malformedrr)rr%rrrr(r_r)rrRrSr*r+rr;rErErFtest_post_not_retrieds z9ClientNetworkWithMockedResponseTest.test_post_not_retriedcCs@t}tjd|jg|_|j|jjd|j |j dksClientNetworkWithMockedResponseTest.test_post_successful_retryc Cstjj|j_|jj|jjfD]<}t tjj|ddWdq1sN0Yqt tjj"|jj d|j dWdn1s0YdS)Nr r)r+) rrrr)r_r)r/r,rRrSr*r+)rCr(rErErF$test_head_get_post_error_passthroughs  *zHClientNetworkWithMockedResponseTest.test_head_get_post_error_passthroughcCstjdtjd}t|j_||jj_d|_t}||j_t t j (|jj d|j|jddWdn1sv0Y|jdksJdS)NFrrr"rrr")rr%r&ZSERVICE_UNAVAILABLEr)rr+rrrRrSrrgr*r+rY)rCZ bad_responser.rErErFtest_post_bad_nonce_heads  $zClientNetworkWithMockedResponseTest.test_new_nonce_uri_removedN)rrrrrGr.r0r1r2r3r4r8r9r<r=r>r?rArBrErErErFr!ws +   r!__main__r")0rr\roZ http.clientr;r&rLsystypingrZunittestrZjosepyr2rRrZacmerrrrrZacme._internal.testsrr Z acme.clientr r Z load_vectorrrAZJWKRSAloadr-rrr9ZTestCaserZJSONDeSerializablerrr!rexitmainargv__file__rErErErFsN              b e#