From 59a7559c05bd44eb44fac690991664c4d19762a6 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Sun, 30 Nov 2014 01:20:36 +0100 Subject: [PATCH] Unify docs --- docs/conf.py | 2 + letsencrypt/client/acme.py | 37 +--- letsencrypt/client/apache_configurator.py | 236 +++++++++------------- letsencrypt/client/augeas_configurator.py | 46 ++--- letsencrypt/client/challenge.py | 37 ++-- letsencrypt/client/client.py | 69 +++---- letsencrypt/client/configurator.py | 19 +- letsencrypt/client/crypto_util.py | 38 ++-- letsencrypt/client/le_util.py | 33 ++- letsencrypt/client/logger.py | 1 + 10 files changed, 207 insertions(+), 311 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 8a630edd1..fd089d14b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -285,3 +285,5 @@ texinfo_documents = [ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} + +todo_include_todos = True diff --git a/letsencrypt/client/acme.py b/letsencrypt/client/acme.py index 58dd0bc9b..50ab26e8b 100644 --- a/letsencrypt/client/acme.py +++ b/letsencrypt/client/acme.py @@ -29,12 +29,10 @@ SCHEMATA = dict([ def acme_object_validate(json_string, schemata=None): """Validate a JSON string against the ACME protocol using JSON Schema. - :param json_string: Well-formed input JSON string. - :type json_string: str + :param str json_string: Well-formed input JSON string. - :param schemata: Mapping from type name to JSON Schema definition. - Useful for testing. - :type schemata: dict + :param dict schemata: Mapping from type name to JSON Schema + definition. Useful for testing. :returns: None if validation was successful. @@ -66,14 +64,12 @@ def pretty(json_string): def challenge_request(name): """Create ACME "challengeRequest message. - :param name: Domain name - :type name: unicode + :param unicode name: Domain name :returns: ACME "challengeRequest" message. :rtype: dict """ - return { "type": "challengeRequest", "identifier": name, @@ -84,19 +80,10 @@ def authorization_request(req_id, name, server_nonce, responses, key_file): """Create ACME "authorizationRequest" message. :param req_id: TODO - :type req_id: TODO - :param name: TODO - :type name: TODO - :param server_nonce: TODO - :type server_nonce: TODO - :param responses: TODO - :type response: TODO - :param key_file: TODO - :type key_file: TODO :returns: ACME "authorizationRequest" message. :rtype: dict @@ -115,11 +102,8 @@ def authorization_request(req_id, name, server_nonce, responses, key_file): def certificate_request(csr_der, key): """Create ACME "certificateRequest" message. - :param csr_der: DER encoded CSR. - :type csr_der: str - + :param str csr_der: DER encoded CSR. :param key: TODO - :type key: TODO :returns: ACME "certificateRequest" message. :rtype: dict @@ -135,12 +119,10 @@ def certificate_request(csr_der, key): def revocation_request(key_file, cert_der): """Create ACME "revocationRequest" message. - :param key_file: Path to a file containing RSA key. Accepted formats - are the same as for `Crypto.PublicKey.RSA.importKey`. - :type key_file: str + :param str key_file: Path to a file containing RSA key. Accepted + formats are the same as for `Crypto.PublicKey.RSA.importKey`. - :param cert_der: DER encoded certificate. - :type cert_der: str + :param str cert_der: DER encoded certificate. :returns: ACME "revocationRequest" message. :rtype: dict @@ -156,8 +138,7 @@ def revocation_request(key_file, cert_der): def status_request(token): """Create ACME "statusRequest" message. - :param token: Token provided in ACME "defer" message. - :type token: str + :param str token: Token provided in ACME "defer" message. :returns: ACME "statusRequest" message. :rtype: dict diff --git a/letsencrypt/client/apache_configurator.py b/letsencrypt/client/apache_configurator.py index f5ebf6be7..1277bcc41 100644 --- a/letsencrypt/client/apache_configurator.py +++ b/letsencrypt/client/apache_configurator.py @@ -44,6 +44,8 @@ from letsencrypt.client import logger # transactional due to the use of register_file_creation() class VH(object): + """Virtual host.""" + def __init__(self, filename_path, vh_path, vh_addrs, is_ssl, is_enabled): self.file = filename_path self.path = vh_path @@ -129,25 +131,22 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Deploys certificate to specified virtual host. Currently tries to find the last directives to deploy the cert in - the given virtualhost. If it can't find the directives, it searches - the "included" confs. The function verifies that it has located + the given virtualhost. If it can't find the directives, it searches + the "included" confs. The function verifies that it has located the three directives and finally modifies them to point to the correct destination - TODO: Make sure last directive is changed - TODO: Might be nice to remove chain directive if none exists - * This shouldn't happen within letsencrypt though + + .. todo:: Make sure last directive is changed + + .. todo:: Might be nice to remove chain directive if none exists + This shouldn't happen within letsencrypt though :param vhost: ssl vhost to deploy certificate - :type vhost: VH + :type vhost: :class:`VH` - :param cert: certificate filename - :type cert: str - - :param key: private key filename - :type key: str - - :param cert_chain: certificate chain filename - :type cert_chain: str + :param strcert: certificate filename + :param str key: private key filename + :param str cert_chain: certificate chain filename :returns: Success :rtype: bool @@ -196,13 +195,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def choose_virtual_host(self, name, ssl=True): """ Chooses a virtual host based on the given domain name. - TODO: This should maybe return list if no obvious answer is presented + .. todo:: This should maybe return list if no obvious answer is presented - :param name: domain name - :type name: str + :param str name: domain name :returns: ssl vhost associated with name - :rtype: VH + :rtype: :class:`VH` """ # Allows for domain names to be associated with a virtual host @@ -244,11 +242,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Helps to choose an appropriate vhost - :param domain: domain name to associate - :type domain: str + :param str domain: domain name to associate :param vhost: virtual host to associate with domain - :type vhost: VH + :type vhost: :class:`VH` """ self.assoc[dn] = vh @@ -257,7 +254,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Returns all names found in the Apache Configuration. :returns: All ServerNames, ServerAliases, and reverse DNS entries for - virtual host addresses + virtual host addresses :rtype: set """ @@ -286,10 +283,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def _set_user_config_file(self, filename=''): """Set the appropriate user configuration file - TODO: This will have to be updated for other distros versions + .. todo:: This will have to be updated for other distros versions - :param filename: optional filename that will be used as the user config - :type filename: str + :param str filename: optional filename that will be used as the user config """ if filename: @@ -309,7 +305,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Helper function for get_virtual_hosts(). :param host: In progress vhost whose names will be added - :type host: VH + :type host: :class:`VH` """ nameMatch = self.aug.match(("%s//*[self::directive=~regexp('%s')] | " @@ -326,11 +322,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def _create_vhost(self, path): """Used by get_virtual_hosts to create vhost objects - :param path: Augeas path to virtual host - :type path: str + :param str path: Augeas path to virtual host :returns: newly created vhost - :rtype: VH + :rtype: :class:`VH` """ addrs = [] @@ -353,7 +348,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def get_virtual_hosts(self): """Returns list of virtual hosts found in the Apache configuration. - :returns: List of VH objects found in configuration + :returns: List of :class:`VH` objects found in configuration :rtype: list """ @@ -372,8 +367,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Checks if addr has a NameVirtualHost directive in the Apache config - :param addr: vhost address ie. *:443 - :type addr: str + :param str addr: vhost address ie. \*:443 :returns: Success :rtype: bool @@ -403,8 +397,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Directive is added to ports.conf unless the file doesn't exist It is added to httpd.conf as a backup - :param addr: Address that will be added as NameVirtualHost directive - :type addr: str + :param str addr: Address that will be added as NameVirtualHost directive """ aug_file_path = "/files%sports.conf" % self.server_root @@ -429,14 +422,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): an IfMod mod_ssl.c block. If the IfMod block does not exist in the file, it is created. - :param aug_conf_path: Desired Augeas config path to add directive - :type aug_conf_path: str - - :param directive: Directive you would like to add - :type directive: str - - :param val: Value of directive ie. Listen 443, 443 is the value - :type val: str + :param str aug_conf_path: Desired Augeas config path to add directive + :param str directive: Directive you would like to add + :param str val: Value of directive ie. Listen 443, 443 is the value """ # TODO: Add error checking code... does the path given even exist? @@ -451,13 +439,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def make_server_sni_ready(self, vhost, default_addr="*:443"): """Checks to see if the server is ready for SNI challenges. - TODO: This should largely depend on the version of Apache + .. todo:: This should largely depend on the version of Apache :param vhost: VHost to check SNI compatibility - :type vhost: VH + :type vhost: :class:`VH` - :param default_addr: TODO - investigate function further - :type default_addr: str + :param str default_addr: TODO - investigate function further """ # Check if mod_ssl is loaded @@ -498,11 +485,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def get_ifmod(self, aug_conf_path, mod): """Returns the path to and creates one if it doesn't exist. - :param aug_conf_path: Augeas configuration path - :type aug_conf_path: str - - :param mod: module ie. mod_ssl.c - :type mod: str + :param str aug_conf_path: Augeas configuration path + :param str mod: module ie. mod_ssl.c """ ifMods = self.aug.match(("%s/IfModule/*[self::arg='%s']" % @@ -520,14 +504,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Note: Not added to AugeasConfigurator because it may depend on the lens - :param aug_conf_path: Augeas configuration path to add directive - :type aug_conf_path: str + :param str aug_conf_path: Augeas configuration path to add directive + :param str directive: Directive to add + :param str arg: Value of the directive. ie. Listen 443, 443 is arg - :param directive: Directive to add - :type directive: str - - :param arg: Value of the directive. ie. Listen 443, 443 is arg - :type arg: str """ self.aug.set(aug_conf_path + "/directive[last() + 1]", directive) @@ -544,7 +524,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Recursively searches through config files to find directives Directives should be in the form of a case insensitive regex currently - TODO: arg should probably be a list + + .. todo:: arg should probably be a list Note: Augeas is inherently case sensitive while Apache is case insensitive. Augeas 1.0 allows case insensitive regexes like @@ -553,15 +534,13 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): transformation by calling case_i() on everything to maintain compatibility. - :param directive: Directive to look for - :type directive: str + :param str directive: Directive to look for :param arg: Specific value direcitve must have, None if all should be considered :type arg: str or None - :param start: Beginning Augeas path to begin looking - :type start: str + :param str start: Beginning Augeas path to begin looking """ # Cannot place member variable in the definition of the function so... @@ -606,13 +585,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Converts an Apache Include directive argument into an Augeas searchable path - TODO: convert to use os.path.join() - :param cur_dir: current working directory - :type cur_dir: str + .. todo:: convert to use os.path.join() - :param arg: Argument of Include directive - :type arg: str + :param str cur_dir: current working directory + + :param str arg: Argument of Include directive :returns: Augeas path string :rtype: str @@ -676,7 +654,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Checks to see if mod_ssl is loaded Currently uses apache2ctl to get loaded module list - TODO: This function is likely fragile to versions/distros + + .. todo:: This function is likely fragile to versions/distros :returns: If ssl_module is included and active in Apache :rtype: bool @@ -704,10 +683,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): New vhost will reside as (nonssl_vhost.path) + CONFIG.LE_VHOST_EXT :param nonssl_vhost: Valid VH that doesn't have SSLEngine on - :type nonssl_vhost: VH + :type nonssl_vhost: :class:`VH` :returns: SSL vhost - :rtype: VH + :rtype: :class:`VH` """ avail_fp = nonssl_vhost.file @@ -809,10 +788,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): The function then adds the directive :param ssl_vhost: Destination of traffic, an ssl enabled vhost - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: Success, general_vhost (HTTP vhost) - :rtype: bool, VH + :rtype: (bool, :class:`VH`) """ # TODO: Enable check to see if it is already there @@ -858,7 +837,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): -1 is also returned in case of no redirection/rewrite directives :param vhost: vhost to check - :type vhost: VH + :type vhost: :class:`VH` :returns: Success, code value... see documentation :rtype: bool, int @@ -889,10 +868,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Creates an http_vhost specifically to redirect for the ssl_vhost. :param ssl_vhost: ssl vhost - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: Success, vhost - :rtype: bool, VH + :rtype: (bool, :class:`VH`) """ # Consider changing this to a dictionary check @@ -973,7 +952,7 @@ LogLevel warn \n\ if not conflict: returns space separated list of new host addrs :param ssl_vhost: SSL Vhost to check for possible port 80 redirection - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: TODO :rtype: TODO @@ -1012,10 +991,10 @@ LogLevel warn \n\ Consider changing this into a dict check :param ssl_vhost: ssl vhost to check - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: HTTP vhost or None if unsuccessful - :rtype: VH or None + :rtype: :class:`VH` or None """ # _default_:443 check @@ -1090,8 +1069,7 @@ LogLevel warn \n\ Takes in Augeas path and returns the file name - :param vhost_path: Augeas virtual host path - :type vhost_path: str + :param str vhost_path: Augeas virtual host path :returns: filename of vhost :rtype: str @@ -1116,10 +1094,9 @@ LogLevel warn \n\ def is_site_enabled(self, avail_fp): """Checks to see if the given site is enabled. - TODO: fix hardcoded sites-enabled + .. todo:: fix hardcoded sites-enabled - :param avail_fp: Complete file path of available site - :type avail_fp: str + :param str avail_fp: Complete file path of available site :returns: Success :rtype: bool @@ -1135,11 +1112,12 @@ LogLevel warn \n\ def enable_site(self, vhost): """Enables an available site, Apache restart required. - TODO: This function should number subdomains before the domain vhost - TODO: Make sure link is not broken... + .. todo:: This function should number subdomains before the domain vhost + + .. todo:: Make sure link is not broken... :param vhost: vhost to enable - :type vhost: VH + :type vhost: :class:`VH` :returns: Success :rtype: bool @@ -1164,8 +1142,7 @@ LogLevel warn \n\ Both enables and restarts Apache so module is active. - :param mod_name: Name of the module to enable - :type mod_name: str + :param str mod_name: Name of the module to enable """ try: @@ -1185,8 +1162,7 @@ LogLevel warn \n\ def fnmatch_to_re(self, clean_fn_match): """Method converts Apache's basic fnmatch to regular expression. - :param clean_fn_match: Apache style filename match, similar to globs - :type clean_fn_match: str + :param str clean_fn_match: Apache style filename match, similar to globs :returns: regex suitable for augeas :rtype: str @@ -1212,8 +1188,7 @@ LogLevel warn \n\ Checks to see if file_path is parsed by Augeas If file_path isn't parsed, the file is added and Augeas is reloaded - :param file_path: Apache config file path - :type file_path: str + :param str file_path: Apache config file path """ # Test if augeas included file for Httpd.lens @@ -1313,8 +1288,7 @@ LogLevel warn \n\ This function will correctly add a transform to augeas The existing augeas.add_transform in python is broken. - :param incl: TODO - :type incl: str + :param str incl: TODO """ lastInclude = self.aug.match("/augeas/load/Httpd/incl [last()]") @@ -1354,8 +1328,7 @@ LogLevel warn \n\ def perform(self, chall_dict): """Perform the configuration related challenge. - :param chall_dict: Dictionary representing a challenge. - :type chall_dict: dict + :param dict chall_dict: Dictionary representing a challenge. """ @@ -1366,13 +1339,16 @@ LogLevel warn \n\ def dvsni_perform(self, chall_dict): """Peform a DVSNI challenge. - Composed of - listSNITuple: List of tuples with form (addr, r, nonce) - addr (string), r (base64 string), nonce (hex string) - dvsni_key: string - File path to key + Composed of: - :param chall_dict: dvsni challenge - see documentation - :type chall_dict: dict + listSNITuple + List of tuples with form (addr, r, nonce) + addr (string), r (base64 string), nonce (hex string) + + dvsni_key + string - File path to key + + :param dict chall_dict: dvsni challenge - see documentation """ # Save any changes to the configuration as a precaution @@ -1437,8 +1413,7 @@ LogLevel warn \n\ def dvsni_get_cert_file(self, nonce): """Returns standardized name for challenge certificate. - :param nonce: hex form of nonce - :type nonce: str + :param str nonce: hex form of nonce :returns: certificate file name :rtype: str @@ -1449,14 +1424,9 @@ LogLevel warn \n\ def _get_config_text(self, nonce, ip_addrs, key): """Chocolate virtual server configuration text - :param nonce: hex form of nonce - :type nonce: str - - :param ip_addrs: addresses of challenged domain - :type ip_addrs: str - - :param key: file path to key - :type key: str + :param str nonce: hex form of nonce + :param str ip_addrs: addresses of challenged domain + :param str key: file path to key :returns: virtual host configuration text :rtype: str @@ -1483,18 +1453,14 @@ LogLevel warn \n\ Result: Apache config includes virtual servers for issued challs - :param mainConfig: file path to Apache user config file - :type mainConfig: str + :param str mainConfig: file path to Apache user config file - :param listSNITuple: list of tuples with the form (addr, y, nonce) - addr (string), y (byte array), nonce (hex string) - :type listSNITuple: lsit + :param list listSNITuple: list of tuples with the form (addr, y, nonce) + addr (string), y (byte array), nonce (hex string) - :param dvsni_key: file path to key - :type dvsni_key: str + :param str dvsni_key: file path to key - :param listlistAddrs: list of list of addresses to apply - :type listlistAddrs: list + :param list listlistAddrs: list of list of addresses to apply """ # WARNING: THIS IS A POTENTIAL SECURITY VULNERABILITY @@ -1527,8 +1493,7 @@ LogLevel warn \n\ Adds DVSNI challenge include file if it does not already exist within mainConfig - :param mainConfig: file path to main user apache config file - :type mainConfig: str + :param str mainConfig: file path to main user apache config file """ if len(self.find_directive( @@ -1542,11 +1507,8 @@ LogLevel warn \n\ Certificate created at dvsni_get_cert_file(nonce) - :param nonce: hex form of nonce - :type nonce: str - - :param key_file: absolute path to key file - :type key: str + :param str nonce: hex form of nonce + :param str key_file: absolute path to key file """ try: @@ -1566,11 +1528,8 @@ LogLevel warn \n\ def dvsni_gen_ext(self, r, s): """Generates z extension to be placed in certificate extension. - :param r: DVSNI r value - :type r: byte array - - :param s: DVSNI s value - :type s: byte array + :param bytearray r: DVSNI r value + :param bytearray s: DVSNI s value result: returns z + CONFIG.INVALID_EXT @@ -1591,8 +1550,7 @@ def case_i(string): May be replaced by a more proper /i once augeas 1.0 is widely supported. - :param string: string to make case i regex - :type string: str + :param str string: string to make case i regex """ return "".join(["["+c.upper()+c.lower()+"]" @@ -1602,10 +1560,10 @@ def case_i(string): def strip_dir(path): """Returns directory of file path. - TODO: Replace this with Python standard function + .. todo:: Replace this with Python standard function - :param path: path is a file path. not an augeas section or directive path - :type path: str + :param str path: path is a file path. not an augeas section or + directive path :returns: directory :rtype: str diff --git a/letsencrypt/client/augeas_configurator.py b/letsencrypt/client/augeas_configurator.py index 8bfd4c1ff..e304966c2 100644 --- a/letsencrypt/client/augeas_configurator.py +++ b/letsencrypt/client/augeas_configurator.py @@ -12,6 +12,7 @@ from letsencrypt.client import logger class AugeasConfigurator(configurator.Configurator): + """Augeas configurator.""" def __init__(self): super(AugeasConfigurator, self).__init__() @@ -24,8 +25,7 @@ class AugeasConfigurator(configurator.Configurator): def check_parsing_errors(self, lens): """Verify Augeas can parse all of the lens files. - :param lens: lens to check for errors - :type lens: str + :param str lens: lens to check for errors """ error_files = self.aug.match("/augeas//error") @@ -48,14 +48,12 @@ class AugeasConfigurator(configurator.Configurator): all configuration changes made will be saved. According to the function parameters. - :param title: The title of the save. If a title is given, the - configuration will be saved as a new checkpoint - and put in a timestamped directory. - :type title: str + :param str title: The title of the save. If a title is given, the + configuration will be saved as a new checkpoint and put in a + timestamped directory. - :param temporary: Indicates whether the changes made will be quickly - reversed in the future (ie. challenges) - :type temporary: bool + :param bool temporary: Indicates whether the changes made will + be quickly reversed in the future (ie. challenges) """ save_state = self.aug.get("/augeas/save") @@ -141,8 +139,7 @@ class AugeasConfigurator(configurator.Configurator): def rollback_checkpoints(self, rollback=1): """Revert 'rollback' number of configuration checkpoints. - :param rollback: Number of checkpoints to reverse - :type rollback: int + :param int rollback: Number of checkpoints to reverse """ try: @@ -222,8 +219,7 @@ class AugeasConfigurator(configurator.Configurator): Adds title to cp_dir CHANGES_SINCE Move cp_dir to Backups directory and rename with timestamp - :param cp_dir: "IN PROGRESS" directory - :type cp_dir: str + :param str cp_dir: "IN PROGRESS" directory :returns: Success :rtype: bool @@ -250,11 +246,8 @@ class AugeasConfigurator(configurator.Configurator): def add_to_checkpoint(self, cp_dir, save_files): """Add save files to checkpoint directory. - :param cp_dir: Checkpoint directory filepath - :type cp_dir: str - - :param save_files: set of files to save - :type save_files: set + :param str cp_dir: Checkpoint directory filepath + :param set save_files: set of files to save """ le_util.make_or_verify_dir(cp_dir, 0o755) @@ -289,8 +282,7 @@ class AugeasConfigurator(configurator.Configurator): Recover a specific checkpoint provided by cp_dir Note: this function does not reload augeas. - :param cp_dir: checkpoint directory file path - :type cp_dir: str + :param str cp_dir: checkpoint directory file path :returns: 0 success, 1 Unable to revert, -1 Unable to delete :rtype: int @@ -322,8 +314,7 @@ class AugeasConfigurator(configurator.Configurator): def check_tempfile_saves(self, save_files): """Verify save isn't overwriting any temporary files. - :param save_files: Set of files about to be saved. - :type save_files: set + :param set save_files: Set of files about to be saved. :returns: Success, error message :rtype: bool, str @@ -347,12 +338,10 @@ class AugeasConfigurator(configurator.Configurator): file will be cleaned up if the program exits unexpectedly. (Before a save occurs) - :param temporary: If the file creation registry is for a temp or - permanent save. - :type temporary: bool + :param bool temporary: If the file creation registry is for + a temp or permanent save. - :param *files: file paths to be registered - :type *files: str + :param \*files: file paths (str) to be registered """ if temporary: @@ -395,8 +384,7 @@ class AugeasConfigurator(configurator.Configurator): def _remove_contained_files(self, file_list): """Erase all files contained within file_list. - :param file_list: file containing list of file paths to be deleted - :type file_list: str + :param str file_list: file containing list of file paths to be deleted :returns: Success :rtype: bool diff --git a/letsencrypt/client/challenge.py b/letsencrypt/client/challenge.py index 0f44f7af9..6eaee82f7 100644 --- a/letsencrypt/client/challenge.py +++ b/letsencrypt/client/challenge.py @@ -23,18 +23,16 @@ class Challenge(object): def gen_challenge_path(challenges, combos=None): """Generate a plan to get authority over the identity. - TODO: Make sure that the challenges are feasible... - Example: Do you have the recovery key? + .. todo:: Make sure that the challenges are feasible... + Example: Do you have the recovery key? - :param challenges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challenges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. :param combos: A collection of sets of challenges from ACME - "challenge" server message ("combinations"), - each of which would be sufficient to prove - possession of the identifier. + "challenge" server message ("combinations"), each of which would + be sufficient to prove possession of the identifier. :type combos: list or None :returns: List of indices from `challenges`. @@ -49,19 +47,17 @@ def gen_challenge_path(challenges, combos=None): def _find_smart_path(challenges, combos): """ - Can be called if combinations is included + Can be called if combinations is included Function uses a simple ranking system to choose the combo with the lowest cost - :param challenges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challenges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. :param combos: A collection of sets of challenges from ACME - "challenge" server message ("combinations"), - each of which would be sufficient to prove - possession of the identifier. + "challenge" server message ("combinations"), each of which would + be sufficient to prove possession of the identifier. :type combos: list or None :returns: List of indices from `challenges`. @@ -102,10 +98,9 @@ def _find_dumb_path(challenges): This function returns the best path that does not contain multiple mutually exclusive challenges - :param challanges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challanges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. :returns: List of indices from `challenges`. :rtype: list diff --git a/letsencrypt/client/client.py b/letsencrypt/client/client.py index 9df815fc2..403360f57 100644 --- a/letsencrypt/client/client.py +++ b/letsencrypt/client/client.py @@ -157,9 +157,12 @@ class Client(object): def acme_challenge(self): """Handle ACME "challenge" phase. - TODO: Handle more than one domain name in self.names + + .. todo:: Handle more than one domain name in self.names + :returns: ACME "challenge" message. :rtype: dict + """ return self.send_and_receive_expected( acme.challenge_request(self.names[0]), "challenge") @@ -167,14 +170,10 @@ class Client(object): def acme_authorization(self, challenge_msg, chal_objs, responses): """Handle ACME "authorization" phase. - :param challenge_msg: ACME "challenge" message. - :type challenge_msg: dict + :param dict challenge_msg: ACME "challenge" message. :param chal_objs: TODO - :type chal_objs: TODO - :param responses: TODO - :type responses: TODO :returns: ACME "authorization" message. :rtype: dict @@ -196,8 +195,7 @@ class Client(object): def acme_certificate(self, csr_der): """Handle ACME "certificate" phase. - :param csr_der: CSR in DER format. - :type csr_der: str + :param str csr_der: CSR in DER format. :returns: ACME "certificate" message. :rtype: dict @@ -210,8 +208,7 @@ class Client(object): def acme_revocation(self, cert): """Handle ACME "revocation" phase. - :param cert: TODO - :type cert: dict + :param dict cert: TODO :returns: ACME "revocation" message. :rtype: dict @@ -235,8 +232,7 @@ class Client(object): def send(self, msg): """Send ACME message to server. - :param msg: ACME message (JSON serializable). - :type msg: dict + :param dict msg: ACME message (JSON serializable). :returns: Server response message. :rtype: dict @@ -274,11 +270,8 @@ class Client(object): def send_and_receive_expected(self, msg, expected): """Send ACME message to server and return expected message. - :param msg: ACME message (JSON serializable). - :type msg: dict - - :param expected: Name of the expected response ACME message type. - :type expected: str + :param dict msg: ACME message (JSON serializable). + :param str expected: Name of the expected response ACME message type. :returns: ACME response message of expected type. :rtype: dict @@ -296,19 +289,15 @@ class Client(object): def is_expected_msg(self, response, expected, delay=3, rounds=20): """Is reponse expected ACME message? - :param response: ACME response message from server. - :type response: dict + :param dict response: ACME response message from server. - :param expected: Name of the expected response ACME message type. - :type expected: str + :param str expected: Name of the expected response ACME message type. - :param delay: Number of seconds to delay before next round in case - of ACME "defer" response message. - :type delay: int + :param int delay: Number of seconds to delay before next round + in case of ACME "defer" response message. - :param rounds: Number of resend attempts in case of ACME "defer" - reponse message. - :type rounds: int + :param int rounds: Number of resend attempts in case of ACME "defer" + reponse message. :returns: ACME response message from server. :rtype: dict @@ -387,8 +376,7 @@ class Client(object): def choose_certs(self, certs): """Display choose certificates menu. - :param certs: List of cert dicts. - :type certs: list + :param list certs: List of cert dicts. """ code, tag = display.display_certs(certs) @@ -478,8 +466,7 @@ class Client(object): def verify_identity(self, challenge_msg): """Verify identity. - :param challenge_msg: ACME "challenge" message. - :type challenge_msg: dict + :param dict challenge_msg: ACME "challenge" message. :returns: TODO :rtype: dict @@ -519,11 +506,9 @@ class Client(object): def store_cert_key(self, cert_file, encrypt=False): """Store certificate key. - :param cert_file: Path to a certificate file. - :type cert_file: str + :param str cert_file: Path to a certificate file. - :param encrypt: Should the certificate key be encrypted? - :type encrypt: bool + :param bool encrypt: Should the certificate key be encrypted? :returns: True if key file was stored successfully, False otherwise. :rtype: bool @@ -584,15 +569,12 @@ class Client(object): """ :param name: TODO - :type name: TODO - :param challenges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challenges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. - :param path: List of indices from `challenges`. - :type path: list + :param list path: List of indices from `challenges`. :returns: A pair of TODO :rtype: tuple @@ -748,8 +730,7 @@ class Client(object): def remove_cert_key(cert): """Remove certificate key. - :param cert: - :type cert: dict + :param dict cert: """ list_file = os.path.join(CONFIG.CERT_KEY_BACKUP, "LIST") diff --git a/letsencrypt/client/configurator.py b/letsencrypt/client/configurator.py index 30972c0e8..5adec3a67 100644 --- a/letsencrypt/client/configurator.py +++ b/letsencrypt/client/configurator.py @@ -11,6 +11,13 @@ class Configurator(object): """ def deploy_cert(self, vhost, cert, key, cert_chain=None): + """Deploy certificate. + + :param vhost + :param str cert: CSR + :param str key: Private key + + """ raise NotImplementedError() def choose_virtual_host(self, name): @@ -53,12 +60,12 @@ class Configurator(object): intended to be permanent, but the save is not ready to be a full checkpoint - title: string - The title of the save. If a title is given, the - configuration will be saved as a new checkpoint - and put in a timestamped directory. - `title` has no effect if temporary is true. - temporary: boolean - Indicates whether the changes made will be - quickly reversed in the future (challenges) + :param str title: The title of the save. If a title is given, the + configuration will be saved as a new checkpoint and put in a + timestamped directory. `title` has no effect if temporary is true. + + :param bool temporary: Indicates whether the changes made will + be quickly reversed in the future (challenges) """ raise NotImplementedError() diff --git a/letsencrypt/client/crypto_util.py b/letsencrypt/client/crypto_util.py index f2bb4c6f7..c945b4414 100644 --- a/letsencrypt/client/crypto_util.py +++ b/letsencrypt/client/crypto_util.py @@ -25,23 +25,22 @@ def b64_cert_to_pem(b64_der_cert): def create_sig(msg, key_str, nonce=None, nonce_len=CONFIG.NONCE_SIZE): """Create signature with nonce prepended to the message. - TODO: Change this over to M2Crypto... PKey - Protect against crypto unicode errors... is this sufficient? - Do I need to escape? + .. todo:: Change this over to M2Crypto... PKey - :param msg: Message to be signed - :type msg: Anything with __str__ method + .. todo::Protect against crypto unicode errors... is this sufficient? + Do I need to escape? - :param key_str: Key in string form. Accepted formats - are the same as for `Crypto.PublicKey.RSA.importKey`. + :param str key_str: Key in string form. Accepted formats + are the same as for `Crypto.PublicKey.RSA.importKey`. :type key_str: str + :param str msg: Message to be signed + :param nonce: Nonce to be used. If None, nonce of `nonce_len` size will be randomly genereted. :type nonce: str or None - :param nonce_len: Size of the automaticaly generated nonce. - :type nonce_len: int + :param int nonce_len: Size of the automaticaly generated nonce. :returns: Signature. :rtype: dict @@ -176,8 +175,7 @@ def make_ss_cert(key_str, domains): def get_cert_info(filename): """Get certificate info. - :param filename: Name of file containing certificate in PEM format. - :type filename: str + :param str filename: Name of file containing certificate in PEM format. :rtype: dict @@ -213,8 +211,7 @@ def valid_csr(csr): Check if `csr` is a valid CSR for the given domains. - :param csr: CSR file contents - :type csr: str + :param str csr: CSR file contents :returns: Validity of CSR. :rtype: bool @@ -233,11 +230,10 @@ def csr_matches_names(csr, domains): M2Crypto currently does not expose the OpenSSL interface to also check the SAN extension. This is insufficient for full testing - :param csr: CSR file contents + :param str csr: CSR file contents :type csr: str - :param domains: Domains the CSR should contain. - :type domains: list + :param list domains: Domains the CSR should contain. :returns: If the CSR subject contains one of the domains :rtype: bool @@ -253,8 +249,7 @@ def csr_matches_names(csr, domains): def valid_privkey(privkey): """Is valid RSA private key? - :param privkey: Private key file contents - :type privkey: str + :param str privkey: Private key file contents :returns: Validity of private key. :rtype: bool @@ -269,11 +264,8 @@ def valid_privkey(privkey): def csr_matches_pubkey(csr, privkey): """Does private key correspond to the subject public key in the CSR? - :param csr: CSR file contents - :type csr: str - - :param privkey: Private key file contents - :type privkey: str + :param str csr: CSR file contents + :param str privkey: Private key file contents :returns: Correspondence of private key to CSR subject public key. :rtype: bool diff --git a/letsencrypt/client/le_util.py b/letsencrypt/client/le_util.py index 4d76a5d21..a5b289446 100644 --- a/letsencrypt/client/le_util.py +++ b/letsencrypt/client/le_util.py @@ -10,14 +10,9 @@ from letsencrypt.client import errors def make_or_verify_dir(directory, mode=0o755, uid=0): """Make sure directory exists with proper permissions. - :param directory: Path to a directry. - :type directory: str - - :param mode: Diretory mode. - :type mode: int - - :param uid: Directory owner. - :type uid: int + :param str directory: Path to a directry. + :param int mode: Diretory mode. + :param int uid: Directory owner. :raises LetsEncryptClientError: if a directory already exists, but has wrong permissions or owner @@ -38,16 +33,12 @@ def make_or_verify_dir(directory, mode=0o755, uid=0): def check_permissions(filepath, mode, uid=0): """Check file or directory permissions. - :param filepath: Path to the tested file (or directory). - :type filepath: str + :param str filepath: Path to the tested file (or directory). + :param int mode: Expected file mode. + :param int uid: Expected file owner. - :param mode: Expected file mode. - :type mode: int - - :param uid: Expected file owner. - :type uid: int - - :returns: bool -- True if `mode` and `uid` match, False otherwise. + :returns: True if `mode` and `uid` match, False otherwise. + :rtype: bool """ file_stat = os.stat(filepath) @@ -94,11 +85,11 @@ def jose_b64encode(data): :param data: Data to be encoded. :type data: str or bytearray - :raises TypeError: if input is of incorrect type - :returns: JOSE Base64 string. :rtype: str + :raises TypeError: if `data` is of incorrect type + """ if not isinstance(data, str): raise TypeError('argument should be str or bytearray') @@ -112,11 +103,11 @@ def jose_b64decode(data): only ASCII characters are allowed. :type data: str or unicode + :returns: Decoded data. + :raises TypeError: if input is of incorrect type :raises ValueError: if unput is unicode with non-ASCII characters - :returns: Decoded data. - """ if isinstance(data, unicode): try: diff --git a/letsencrypt/client/logger.py b/letsencrypt/client/logger.py index 3a67aef9d..5444c3ce0 100644 --- a/letsencrypt/client/logger.py +++ b/letsencrypt/client/logger.py @@ -1,3 +1,4 @@ +"""Logger.""" import logger import textwrap import time