From 49b1c3e2cfb9b0224712e6891a12950f725c3b13 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Tue, 7 Apr 2020 12:24:52 +0200 Subject: Improve README.md and docstrings for Sphinx --- README.md | 16 ++++++++++ otp2289/__main__.py | 12 ++++---- otp2289/generator.py | 18 ++++------- otp2289/server.py | 27 +++++++++-------- sphinx_conf.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 30 deletions(-) create mode 100644 sphinx_conf.py diff --git a/README.md b/README.md index 5811b54..aa30c38 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,13 @@ I decided to license the library under the I hope that somebody will find it useful. +## Installation + + ```bash + pip install pyotp2289 + ``` + + ## Overview of RFC-2289 RFC-2289 describes a one-time password authentication system (OTP): @@ -146,6 +153,10 @@ RFC-2289 consists of interactions between them. # etc. etc... ``` +Please visit the [API documentation] +(http://gnulover.simeonov.no/docs/api/pyotp2289/latest/) for a complete +reference. + If you don't care about developing applications in Python and only care about generating one-time passwords (tokens / hex digests) and authenticating with existing solutions (f.i. FreeBSD servers), pyotp2289 comes with a simple CLI: @@ -164,6 +175,11 @@ existing solutions (f.i. FreeBSD servers), pyotp2289 comes with a simple CLI: starting from (and including) 498. +## Support and contributing + +pyotp2289 is hosted on GitHub: https://github.com/blackm0re/pyotp2289 + + ## Author Simeon Simeonov - sgs @ Freenode diff --git a/otp2289/__main__.py b/otp2289/__main__.py index 2962d29..7c71040 100644 --- a/otp2289/__main__.py +++ b/otp2289/__main__.py @@ -55,9 +55,9 @@ def generate_otp_response(args): :param args: The arguments assigned from argparse :type args: argparse.Namespace - :raises OTPChallengeException: In case of invalid challenge + :raises otp2289.OTPChallengeException: If the challenge is invalid - :raises OTPGeneratorException: In case of wrong generator parameters + :raises otp2289.OTPGeneratorException: If generator parameters are wrong :return: The response string :rtype: str @@ -89,9 +89,9 @@ def generate_otp_range(args): :param args: The arguments assigned from argparse :type args: argparse.Namespace - :raises OTPChallengeException: In case of invalid challenge + :raises otp2289.OTPChallengeException: If the challenge is invalid - :raises OTPGeneratorException: In case of wrong generator parameters + :raises otp2289.OTPGeneratorException: If generator parameters are wrong :return: The responses string :rtype: str @@ -137,9 +137,9 @@ def initiate_new_sequence(args): :param args: The arguments assigned from argparse :type args: argparse.Namespace - :raises OTPChallengeException: In case of invalid challenge + :raises otp2289.OTPChallengeException: If the challenge is invalid - :raises OTPGeneratorException: In case of wrong generator parameters + :raises otp2289.OTPGeneratorException: If generator parameters are wrong :return: The response string :rtype: str diff --git a/otp2289/generator.py b/otp2289/generator.py index ac3bb3c..4623dc0 100644 --- a/otp2289/generator.py +++ b/otp2289/generator.py @@ -310,7 +310,6 @@ class OTPGenerator: """ Constructs an OTPGenerator object with a given password and seed. - Keyword Arguments: :param password: The password string :type password: bytes @@ -320,7 +319,7 @@ class OTPGenerator: :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 :type hash_algo: int or str - :raises OTPGeneratorException: In case the input does not validate + :raises otp2289.OTPGeneratorException: If the input does not validate """ # enforce the rfc2289 constraints self._seed = seed @@ -389,7 +388,7 @@ class OTPGenerator: :param challenge: The challenge string described in RFC-2289 :type challenge: str - :raises OTPChallengeException: When the challenge string is invalid + :raises otp2289.OTPChallengeException: If the challenge is invalid :return: (seed, hash_algo, step) tuple. :rtype: tuple @@ -485,7 +484,7 @@ class OTPGenerator: :param tokens_str: String representing 6 words tokens :type tokens_str: str - :raises OTPGeneratorException: When the tokens_str is invalid + :raises otp2289.OTPGeneratorException: When the tokens_str is invalid :return: 6 words tokens :rtype: bytes @@ -529,7 +528,7 @@ class OTPGenerator: :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 :type hash_algo: int or str - :raises OTPGeneratorException: In case hash_algo does not validate + :raises otp2289.OTPGeneratorException: If hash_algo does not validate :return: The validated hash_algo in str-form :rtype: str @@ -556,7 +555,7 @@ class OTPGenerator: :param seed: The seed received from the challenge, defaults to '' :type seed: str - :raises OTPGeneratorException: In case seed does not validate + :raises otp2289.OTPGeneratorException: If seed does not validate :return: The validated (and very same) seed :rtype: str @@ -580,7 +579,7 @@ class OTPGenerator: :param seed: The step received from the challenge :type seed: int - :raises OTPGeneratorException: In case step does not validate + :raises otp2289.OTPGeneratorException: If step does not validate :return: The validated (and very same) step :rtype: int @@ -595,7 +594,6 @@ class OTPGenerator: """ Generates the OTP hexdigest for the given step. - Keyword Arguments: :param step: The step to generate OTP for :type step: int @@ -614,7 +612,6 @@ class OTPGenerator: extract these parameters. The syntax of the challenge is: otp- - Keyword Arguments: :param challenge: The challenge string :type challenge: str @@ -630,7 +627,6 @@ class OTPGenerator: """ Generates the OTP six words token for the given step. - Keyword Arguments: :param step: The step to generate OTP for :type step: int @@ -649,7 +645,6 @@ class OTPGenerator: extract these parameters. The syntax of the challenge is: otp- - Keyword Arguments: :param challenge: The challenge string :type challenge: str @@ -709,7 +704,6 @@ class OTPGenerator: """ Generates the OTP bytes for the given step. - Keyword Arguments: :param step: The step to generate OTP for :type step: int diff --git a/otp2289/server.py b/otp2289/server.py index fca3f06..119fbff 100644 --- a/otp2289/server.py +++ b/otp2289/server.py @@ -71,7 +71,7 @@ class OTPState: :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 :type hash_algo: int or str - :raises OTPStateException: In case the input does not validate + :raises otp2289.OTPStateException: If the input does not validate """ # enforce the rfc2289 constraints try: @@ -126,7 +126,7 @@ class OTPState: :type dict_obj: dict :return: A new OTPState object - :rtype: OTPStore + :rtype: otp2289.OTPStore """ return cls(**dict_obj) @@ -144,8 +144,9 @@ class OTPState: :param response: The response to this state (its challenge) :type response: str - :raises OTPInvalidResponse: If the response is corrupt / illegal, - but not if it simply does not validate + :raises otp2289.OTPInvalidResponse: If the response is corrupt/illegal, + but not if it simply does not + validate :return: The bytes representation of response (if any) :rtype: bytes @@ -168,7 +169,7 @@ class OTPState: :param ot_hex: The one-time hex to validate :type ot_hex: str - :raises OTPStateException: In case hex does not validate + :raises otp2289.OTPStateException: If hex does not validate :return: The validated hex (without leading 0x) converted to bytes :rtype: bytes @@ -194,7 +195,7 @@ class OTPState: where step -= 1 and ot_hex = self._new_digest_hex :return: The next OTPState if validated, None otherwise - :rtype: OTPState or None + :rtype: otp2289.OTPState or None """ if self._new_digest_hex is None: return None @@ -213,7 +214,8 @@ class OTPState: :param store_valid_response: Should a valid response be stored :type store_valid_response: bool - :raises OTPInvalidResponse: If the response does not match this state + :raises otp2289.OTPInvalidResponse: If the response does not match + this state :return: Returns True if response validates, False otherwise :rtype: bool @@ -328,9 +330,9 @@ class OTPStore: :type key: str :param state: The OTPState object - :type state: OTPState + :type state: otp2289.OTPState - :raises OTPStoreException: On failure + :raises otp2289.OTPStoreException: On failure """ if not isinstance(key, str): raise OTPStoreException('key must be a str') @@ -356,10 +358,10 @@ class OTPStore: :raises KeyError: If key does not exist - :raises OTPStoreException: On failure + :raises otp2289.OTPStoreException: On failure :return: The state corresponding to the key - :rtype: OTPState + :rtype: otp2289.OTPState """ if not isinstance(key, str): raise OTPStoreException('key must be a str') @@ -387,7 +389,8 @@ class OTPStore: :raises KeyError: If the key is not present - :raises OTPInvalidResponse: If the response does not match this state + :raises otp2289.OTPInvalidResponse: If the response does not match + this state :return: Returns True if response validates, False otherwise :rtype: bool diff --git a/sphinx_conf.py b/sphinx_conf.py new file mode 100644 index 0000000..c7247ee --- /dev/null +++ b/sphinx_conf.py @@ -0,0 +1,84 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, '/home/sgs/development/gitprogs/python/pyotp2289/otp2289') + + +# -- Project information ----------------------------------------------------- + +project = 'pyotp2289' +copyright = '2020, Simeon Simeonov' +author = 'Simeon Simeonov' + +# The short X.Y version +version = '1.0.0' + +# The full version, including alpha/beta/rc tags +release = '1.0.0' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.viewcode', + 'sphinx.ext.todo', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +source_suffix = ['.rst', '.md'] + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'nature' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + +# Generated by running: sphinx-apidoc with: +# -P -F -o html -H pyotp2289 -A "Simeon Simeonov" -V "1.0.0" otp2289 -- cgit v1.3