3 گaM@sdZddlmZddlZddlZddlZddlmZddlZddl Z ddl Z ddl m Z ddl m Z ddl mZddl mZdd l mZdd l mZdd l mZdd l mZddlZddlZdd lmZddlmZddlZddlmZddlZddlm Z ddlm!Z!ddl"m#Z#ddl"m$Z$ddl"m%Z%ddl&m'Z(ddl)m*Z*ddl)m+Z+ddl,m!Z-ddl.m/Z/yddl0Z0ej1de2Wn"e3k rddlm0Z0YnXGddde/j4Z5e6e6dddZ7e6e8dd d!Z9e6e:e:e:d"d#d$Z;e6ejdd'd(Z?e6ej@dd)d*ZAe6ejBdd+d,ZCe6ejDdd-d.ZEdZe6e6eFe6d0d1d2ZGd[e6e0jHd4d5d6ZId\e6eee0jHd7d8d9ZJe0jHd:d;d<ZKd]eee0jHd=d>d?ZLGd@dAdAZMeMd:dBdCZNeeMd=dDdEZOe e ddFdGdHZPGdIdJdJejQZRGdKdLdLeRZSejTejTe6ddMdNdOZUe ge fe6ddPdQdRZVe6e e dSe fge dSe ffdTdUdVZWe6e6dWdXdYZXdS)^zTest utilities.)reloadN) synchronize)Any)Callable)cast)IO)Iterable)List)Optional)Union)default_backend) serialization)crypto) configuration)util) constants)lock)storage)obj) filesystem)os)commonzThe external mock module is being used for backwards compatibility since it is available, however, future versions of Certbot's tests will use unittest.mock. Be sure to update your code accordingly.)mockc@seZdZdZeedddZeeeeeddddZdeeee e eefdd d d Z e edd d Z deee ddddZddddZddddZeed ddddZddddZedddZdS)!DummyInstallerz(Dummy installer plugin for test purpose.)returncCsdS)N)selfrr/usr/lib/python3.6/util.py get_all_names7szDummyInstaller.get_all_namesN)domain cert_pathkey_path chain_pathfullchain_pathrcCsdS)Nr)rrr r!r"r#rrr deploy_cert:szDummyInstaller.deploy_cert)r enhancementoptionsrcCsdS)Nr)rrr%r&rrrenhance>szDummyInstaller.enhancecCsdS)Nr)rrrrsupported_enhancementsBsz%DummyInstaller.supported_enhancementsF)title temporaryrcCsdS)Nr)rr)r*rrrsaveEszDummyInstaller.savecCsdS)Nr)rrrr config_testHszDummyInstaller.config_testcCsdS)Nr)rrrrrestartKszDummyInstaller.restart.)addrcCsdS)Nr)clsr.rrradd_parser_argumentsNsz#DummyInstaller.add_parser_argumentscCsdS)Nr)rrrrprepareRszDummyInstaller.preparecCsdS)Nr)rrrr more_infoUszDummyInstaller.more_info)N)NF).N)__name__ __module__ __qualname____doc__rstrrr$r r r r'r(boolr+r,r- classmethodrr0r1r2rrrrr5s&r)namesrcGstjttjjd|S)zPath to a test vector.testdata)r;) pkg_resourcesZresource_filenamer3rpathjoin)r:rrr vector_pathYsr?c GsFtjttjjd|}y|jjddjSt k r@|SXdS)zLoad contents of a test vector.r;z  N)r;) r<Zresource_stringr3rr=r>decodereplaceencode ValueError)r:datarrr load_vector_s rF)filename loader_pem loader_derrcCs<tjj|\}}|jdkr |S|jdkr0|StddS)Nz.pemz.derz1Loader could not be recognized based on extension)rr=splitextlowerrD)rGrHrI_Zextrrr _guess_loaderms   rMcGs$t|dtjtj}tj|t|S)zLoad certificate.)rMr FILETYPE_PEM FILETYPE_ASN1Zload_certificaterF)r:loaderrrr load_certvsrScGs$t|dtjtj}tj|t|S)zLoad certificate request.rNrO)rMrrPrQZload_certificate_requestrF)r:rRrrrload_csr}srTcGstjt|S)z(Load ComparableX509 certificate request.)joseComparableX509rT)r:rrrload_comparable_csrsrWcGsFt|dtjtj}|tjkr&tj}ntj}tj|t |dt dS)zLoad RSA private key.rNN)ZpasswordZbackendrO) rMrrPrQr Zload_pem_private_keyZload_der_private_keyrUComparableRSAKeyrFr )r:rRZ loader_fnrrrload_rsa_private_keys  rYcGs$t|dtjtj}tj|t|S)zLoad pyOpenSSL private key.rNrO)rMrrPrQZload_privatekeyrF)r:rRrrrload_pyopenssl_private_keysrZF) config_dirtestfileecrc sP|dtd }tjjtj}tjjtj|}tjjtj|}x(|||fD]}tjj|sRt j |qRWt dj |r~dnd}x2tj |D]$} tjtjj|| tjj|| qWx:tjD]0} tjtjj|dj | tjj|dj | qWtjj||} tt |4} t| d} | jfd d | DWdQRXWdQRX| S) aCreates a lineage defined by testfile. This creates the archive, live, and renewal directories if necessary and creates a simple lineage. :param str config_dir: path to the configuration directory :param str testfile: configuration file to base the lineage on :param bool ec: True if we generate the lineage with an ECDSA key :returns: path to the renewal conf file for the created lineage :rtype: str Nz.confzsample-archive{}z-ecz{0}1.pemz{0}.pemwc3s|]}|jdVqdS)ZMAGICDIRN)rB).0line)r[rr szmake_lineage..)lenrr=r>rZRENEWAL_CONFIGS_DIRZ ARCHIVE_DIRZLIVE_DIRexistsrmakedirsr?formatlistdirshutilZcopyfilerZALL_FOURsymlinkopen writelines) r[r\r]Z lineage_nameZconf_dirZ archive_dirZlive_dirZ directoryZsample_archiveZkindZ conf_pathsrcdstr)r[r make_lineages.      (rnzope.component.getUtility)targetrcCs tjdttjtj|tdS)zDeprecated, patch certbot.display.util directly or use patch_display_util instead. :param str target: path to patch :returns: mock zope.component.getUtility :rtype: mock.MagicMock zDecorator certbot.tests.util.patch_get_utility is deprecated. You should now patch certbot.display.util yourself directly or use certbot.tests.util.patch_display_util as a temporary workaround.) new_callable)warningswarnrr MagicMockpatch_create_display_util_mock)rprrrpatch_get_utilitys rw)rpstdoutrcCs8tjd|r|ntj}t|}ttjtj||dS)aEDeprecated, patch certbot.display.util directly or use patch_display_util_with_stdout instead. :param str target: path to patch :param object stdout: object to write standard output to; it is expected to have a `write` method :returns: mock zope.component.getUtility :rtype: mock.MagicMock zDecorator certbot.tests.util.patch_get_utility_with_stdout is deprecated. You should now patch certbot.display.util yourself directly or use use certbot.tests.util.patch_display_util_with_stdout as a temporary workaround.)new) rrrsioStringIO%_create_display_util_mock_with_stdoutrrrtru)rprxZfreezable_mockrrrpatch_get_utility_with_stdouts r})rcCsttjtjdtdS)aPatch certbot.display.util to use a special mock display utility. The mock display utility works like a regular mock object, except it also also asserts that methods are called with valid arguments. The mock created by this patch mocks out Certbot internals so this can be used like the old patch_get_utility function. That is, the mock object will be called by the certbot.display.util functions and the mock returned by that call will be used as the display utility. This was done to simplify the transition from zope.component and mocking certbot.display.util functions directly in test code should be preferred over using this function in the future. See https://github.com/certbot/certbot/issues/8948 :returns: patch on the function used internally by certbot.display.util to get a display utility instance :rtype: mock.MagicMock z)certbot._internal.display.obj.get_display)rq)rrrtrurvrrrrpatch_display_utils r~)rxrcCs*|r|ntj}ttjtjdt|dS)aWPatch certbot.display.util to use a special mock display utility. The mock display utility works like a regular mock object, except it also asserts that methods are called with valid arguments. The mock created by this patch mocks out Certbot internals so this can be used like the old patch_get_utility function. That is, the mock object will be called by the certbot.display.util functions and the mock returned by that call will be used as the display utility. This was done to simplify the transition from zope.component and mocking certbot.display.util functions directly in test code should be preferred over using this function in the future. See https://github.com/certbot/certbot/issues/8948 The `message` argument passed to the display utility methods is passed to stdout's write method. :param object stdout: object to write standard output to; it is expected to have a `write` method :returns: patch on the function used internally by certbot.display.util to get a display utility instance :rtype: mock.MagicMock z)certbot._internal.display.obj.get_display)ry)rzr{rrrtrur|)rxrrrpatch_display_util_with_stdouts rc@s|eZdZdZddejjfeede fe ddddZ ddd d Z e e ej d d d Z ee dddZee ddddZdS) FreezableMockaMock object with the ability to freeze attributes. This class works like a regular mock.MagicMock object, except attributes and behavior set before the object is frozen cannot be changed during tests. If a func argument is provided to the constructor, this function is called first when an instance of FreezableMock is called, followed by the usual behavior defined by MagicMock. The return value of func is ignored. FN.)frozenfunc return_valuercCs>|r tndh|_||_tj|_|tjjkr4||_||_ dS)Nfreeze) set _frozen_set_funcrrt_mocksentinelDEFAULTr_frozen)rrrrrrr__init__5s   zFreezableMock.__init__)rcCs d|_dS)z)Freeze object preventing further changes.TN)r)rrrrr>szFreezableMock.freeze)argskwargsrcOs"|jdk r|j|||j||S)N)rr)rrrrrr__call__Bs  zFreezableMock.__call__)namerc Csz|dkr,y tj||Stk r(dSXnJ|dkrFttj|d|S|dksX||jkrdtj||Sttj|d|SdS)NrFr side_effectrr)rr)object__getattribute__AttributeErrorgetattrr)rrrrrrGs  zFreezableMock.__getattribute__)rvaluercCsb|jr*||jkrtd|t|j||S|dkr>|jj||dkrTt|j||Stj|||S)a Before it is frozen, attributes are set on the FreezableMock instance and added to the _frozen_set. Attributes in the _frozen_set cannot be changed after the FreezableMock is frozen. In this case, they are set on the underlying _mock. In cases of return_value and side_effect, these attributes are always passed through to the instance's _mock and added to the _frozen_set before the object is frozen. zCannot change frozen attribute rrr)rr)rrrsetattrrr.r __setattr__)rrrrrrrTs    zFreezableMock.__setattr__)r3r4r5r6rrrr8rrrrrtrr7rrrrrrr(s $ rcCs\t}ddttjD}x,|D]$}|dkr tdtd}t|||q W|jtd|dS)NcSs,g|]$}tttj|r|jd r|qS)__)callabler display_obj FileDisplay startswith)r`rrrr psz-_create_display_util_mock.. notificationT)rr)rr)rdirrr_assert_valid_callrr)display method_listmethod frozen_mockrrrrvms  rvcstttddfdd ttddfdd }t}ddttjD}x:|D]2}|d krhtd d }n td |d }t|||qNW|jtd |d S) N)message unused_args unused_kwargsrcs|rj|dS)z$Write to message to stdout. N)write)rrr)rxrr _write_msg|sz9_create_display_util_mock_with_stdout.._write_msg)rrrcst||||dS)z< Mock function for display utility methods. N)r)rr)rrr mock_methods z:_create_display_util_mock_with_stdout..mock_methodcSs,g|]$}tttj|r|jd r|qS)r)rrrrr)r`rrrrrsz9_create_display_util_mock_with_stdout..rT)rr)rr)r7rrrrrrr)rxrrrrrr)rrxrr|{s  r|)rrrcOsZ|r |dn|dg}i}|jdd|d<|jdd|d<|jdd|d<tj||dS)NrrdefaultZcli_flagZforce_interactiveF)get display_utilZassert_valid_call)rrZ assert_argsZ assert_kwargsrrrrs rc@s,eZdZdZddddZddddZdS)TempDirTestCasezBBase test class which sets up and tears down a temporary directoryN)rcCstj|_dS)zExecute before testN)tempfileZmkdtemptempdir)rrrrsetUpszTempDirTestCase.setUpcCs*tjgtj_tjtj|jdS)zExecute after testN) loggingZshutdownZ getLoggerZhandlersrZ_release_locksrhZrmtreer)rrrrtearDowns zTempDirTestCase.tearDown)r3r4r5r6rrrrrrrsrcs&eZdZdZddfdd ZZS)ConfigTestCasez2Test class which sets up a NamespaceConfig object.N)rcstjtjtjftj|_d|jj _ t j j |jd|jj _t j j |jd|jj _t j j |jd|jj _tjd|jj _tjd|jj _tjd|jj _d|jj _dS)NZcertonlyconfigZworkZlogsZauth_cert_pathZauth_chain_pathzhttps://example.com)superrrZNamespaceConfigrrtrZ CLI_DEFAULTSr namespaceZverbrr=r>rr[Zwork_dirZlogs_dirr r#r"Zserver)r) __class__rrrs  zConfigTestCase.setUp)r3r4r5r6r __classcell__rr)rrrsr)event_in event_outr=rc CsRtjj|rtj|}n tj|}z |j|jdds@tdWd|j XdS)a Acquire a file lock on given path, then wait to release it. This worker is coordinated using events to signal when the lock should be acquired and released. :param multiprocessing.Event event_in: event object to signal when to release the lock :param multiprocessing.Event event_out: event object to signal when the lock is acquired :param path: the path to lock )timeoutz*Timeout while waiting to release the lock.N) rr=isdirrZlock_dirZLockFilerwaitAssertionErrorrelease)rrr=Zmy_lockrrr _handle_locks   r)callback path_to_lockrcCsttttj}tj}tjt|||fd}|j|jddsHtd||j |j dd|j dksptdS)z Grab a lock on path_to_lock from a foreign process then execute the callback. :param callable callback: object to call after acquiring the lock :param str path_to_lock: path to file or directory to lock )rpr )rz*Timeout while waiting to acquire the lock.rN) reload_modulermultiprocessingEventZProcessrstartrrrr>Zexitcode)rrZ emit_eventZ receive_eventZprocessrrr lock_and_calls r.)reasonrcs(tdtftdtfdfdd }|S)zFDecorator to skip permanently a test on Windows. A reason is required..)functionrcstjtjdk|S)zWrapped versionZwin32)unittestZskipIfsysplatform)r)rrrwrappersz skip_on_windows..wrapper)rr)rrr)rrskip_on_windowss$r)r=rcCstjjtj|S)z Return the given path joined to the tempdir path for the current platform Eg.: 'cert' => /tmp/cert (Linux) or 'C:\Users\currentuser\AppData\Temp\cert' (Windows) )rr=r>rZ gettempdir)r=rrr temp_joinsr)F)ro)roN)N)Yr6 importlibrrrzrrrrhrrZtypingrrrrrr r r rrrZcryptography.hazmat.backendsr Zcryptography.hazmat.primitivesr ZjosepyrUZOpenSSLrr<ZcertbotrrZcertbot._internalrrrZcertbot._internal.displayrrZcertbot.compatrrZcertbot.displayrZcertbot.pluginsrrrsPendingDeprecationWarning ImportErrorZ Installerrr7r?bytesrFintrMZX509rSZX509ReqrTrVrWrXrYZPKeyrZr8rnrtrwr}r~rrrvr|rZTestCaserrrrrrrrrrrs                        $  - E *