diff options
| author | Simeon Simeonov | 2020-04-07 12:24:52 +0200 |
|---|---|---|
| committer | Simeon Simeonov | 2020-04-07 12:24:52 +0200 |
| commit | 49b1c3e2cfb9b0224712e6891a12950f725c3b13 (patch) | |
| tree | 97e42ec2a43f9a17a68ea10e613945bb845e7e18 | |
| parent | e297c0696cf594f8f700dd82fdcdda582e348eda (diff) | |
Improve README.md and docstrings for Sphinx
| -rw-r--r-- | README.md | 16 | ||||
| -rw-r--r-- | otp2289/__main__.py | 12 | ||||
| -rw-r--r-- | otp2289/generator.py | 18 | ||||
| -rw-r--r-- | otp2289/server.py | 27 | ||||
| -rw-r--r-- | sphinx_conf.py | 84 |
5 files changed, 127 insertions, 30 deletions
| @@ -21,6 +21,13 @@ I decided to license the library under the | |||
| 21 | I hope that somebody will find it useful. | 21 | I hope that somebody will find it useful. |
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | ## Installation | ||
| 25 | |||
| 26 | ```bash | ||
| 27 | pip install pyotp2289 | ||
| 28 | ``` | ||
| 29 | |||
| 30 | |||
| 24 | ## Overview of RFC-2289 | 31 | ## Overview of RFC-2289 |
| 25 | 32 | ||
| 26 | RFC-2289 describes a one-time password authentication system (OTP): | 33 | RFC-2289 describes a one-time password authentication system (OTP): |
| @@ -146,6 +153,10 @@ RFC-2289 consists of interactions between them. | |||
| 146 | # etc. etc... | 153 | # etc. etc... |
| 147 | ``` | 154 | ``` |
| 148 | 155 | ||
| 156 | Please visit the [API documentation] | ||
| 157 | (http://gnulover.simeonov.no/docs/api/pyotp2289/latest/) for a complete | ||
| 158 | reference. | ||
| 159 | |||
| 149 | If you don't care about developing applications in Python and only care about | 160 | If you don't care about developing applications in Python and only care about |
| 150 | generating one-time passwords (tokens / hex digests) and authenticating with | 161 | generating one-time passwords (tokens / hex digests) and authenticating with |
| 151 | existing solutions (f.i. FreeBSD servers), pyotp2289 comes with a simple CLI: | 162 | 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: | |||
| 164 | starting from (and including) 498. | 175 | starting from (and including) 498. |
| 165 | 176 | ||
| 166 | 177 | ||
| 178 | ## Support and contributing | ||
| 179 | |||
| 180 | pyotp2289 is hosted on GitHub: https://github.com/blackm0re/pyotp2289 | ||
| 181 | |||
| 182 | |||
| 167 | ## Author | 183 | ## Author |
| 168 | 184 | ||
| 169 | Simeon Simeonov - sgs @ Freenode | 185 | 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): | |||
| 55 | :param args: The arguments assigned from argparse | 55 | :param args: The arguments assigned from argparse |
| 56 | :type args: argparse.Namespace | 56 | :type args: argparse.Namespace |
| 57 | 57 | ||
| 58 | :raises OTPChallengeException: In case of invalid challenge | 58 | :raises otp2289.OTPChallengeException: If the challenge is invalid |
| 59 | 59 | ||
| 60 | :raises OTPGeneratorException: In case of wrong generator parameters | 60 | :raises otp2289.OTPGeneratorException: If generator parameters are wrong |
| 61 | 61 | ||
| 62 | :return: The response string | 62 | :return: The response string |
| 63 | :rtype: str | 63 | :rtype: str |
| @@ -89,9 +89,9 @@ def generate_otp_range(args): | |||
| 89 | :param args: The arguments assigned from argparse | 89 | :param args: The arguments assigned from argparse |
| 90 | :type args: argparse.Namespace | 90 | :type args: argparse.Namespace |
| 91 | 91 | ||
| 92 | :raises OTPChallengeException: In case of invalid challenge | 92 | :raises otp2289.OTPChallengeException: If the challenge is invalid |
| 93 | 93 | ||
| 94 | :raises OTPGeneratorException: In case of wrong generator parameters | 94 | :raises otp2289.OTPGeneratorException: If generator parameters are wrong |
| 95 | 95 | ||
| 96 | :return: The responses string | 96 | :return: The responses string |
| 97 | :rtype: str | 97 | :rtype: str |
| @@ -137,9 +137,9 @@ def initiate_new_sequence(args): | |||
| 137 | :param args: The arguments assigned from argparse | 137 | :param args: The arguments assigned from argparse |
| 138 | :type args: argparse.Namespace | 138 | :type args: argparse.Namespace |
| 139 | 139 | ||
| 140 | :raises OTPChallengeException: In case of invalid challenge | 140 | :raises otp2289.OTPChallengeException: If the challenge is invalid |
| 141 | 141 | ||
| 142 | :raises OTPGeneratorException: In case of wrong generator parameters | 142 | :raises otp2289.OTPGeneratorException: If generator parameters are wrong |
| 143 | 143 | ||
| 144 | :return: The response string | 144 | :return: The response string |
| 145 | :rtype: str | 145 | :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: | |||
| 310 | """ | 310 | """ |
| 311 | Constructs an OTPGenerator object with a given password and seed. | 311 | Constructs an OTPGenerator object with a given password and seed. |
| 312 | 312 | ||
| 313 | Keyword Arguments: | ||
| 314 | :param password: The password string | 313 | :param password: The password string |
| 315 | :type password: bytes | 314 | :type password: bytes |
| 316 | 315 | ||
| @@ -320,7 +319,7 @@ class OTPGenerator: | |||
| 320 | :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 | 319 | :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 |
| 321 | :type hash_algo: int or str | 320 | :type hash_algo: int or str |
| 322 | 321 | ||
| 323 | :raises OTPGeneratorException: In case the input does not validate | 322 | :raises otp2289.OTPGeneratorException: If the input does not validate |
| 324 | """ | 323 | """ |
| 325 | # enforce the rfc2289 constraints | 324 | # enforce the rfc2289 constraints |
| 326 | self._seed = seed | 325 | self._seed = seed |
| @@ -389,7 +388,7 @@ class OTPGenerator: | |||
| 389 | :param challenge: The challenge string described in RFC-2289 | 388 | :param challenge: The challenge string described in RFC-2289 |
| 390 | :type challenge: str | 389 | :type challenge: str |
| 391 | 390 | ||
| 392 | :raises OTPChallengeException: When the challenge string is invalid | 391 | :raises otp2289.OTPChallengeException: If the challenge is invalid |
| 393 | 392 | ||
| 394 | :return: (seed, hash_algo, step) tuple. | 393 | :return: (seed, hash_algo, step) tuple. |
| 395 | :rtype: tuple | 394 | :rtype: tuple |
| @@ -485,7 +484,7 @@ class OTPGenerator: | |||
| 485 | :param tokens_str: String representing 6 words tokens | 484 | :param tokens_str: String representing 6 words tokens |
| 486 | :type tokens_str: str | 485 | :type tokens_str: str |
| 487 | 486 | ||
| 488 | :raises OTPGeneratorException: When the tokens_str is invalid | 487 | :raises otp2289.OTPGeneratorException: When the tokens_str is invalid |
| 489 | 488 | ||
| 490 | :return: 6 words tokens | 489 | :return: 6 words tokens |
| 491 | :rtype: bytes | 490 | :rtype: bytes |
| @@ -529,7 +528,7 @@ class OTPGenerator: | |||
| 529 | :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 | 528 | :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 |
| 530 | :type hash_algo: int or str | 529 | :type hash_algo: int or str |
| 531 | 530 | ||
| 532 | :raises OTPGeneratorException: In case hash_algo does not validate | 531 | :raises otp2289.OTPGeneratorException: If hash_algo does not validate |
| 533 | 532 | ||
| 534 | :return: The validated hash_algo in str-form | 533 | :return: The validated hash_algo in str-form |
| 535 | :rtype: str | 534 | :rtype: str |
| @@ -556,7 +555,7 @@ class OTPGenerator: | |||
| 556 | :param seed: The seed received from the challenge, defaults to '' | 555 | :param seed: The seed received from the challenge, defaults to '' |
| 557 | :type seed: str | 556 | :type seed: str |
| 558 | 557 | ||
| 559 | :raises OTPGeneratorException: In case seed does not validate | 558 | :raises otp2289.OTPGeneratorException: If seed does not validate |
| 560 | 559 | ||
| 561 | :return: The validated (and very same) seed | 560 | :return: The validated (and very same) seed |
| 562 | :rtype: str | 561 | :rtype: str |
| @@ -580,7 +579,7 @@ class OTPGenerator: | |||
| 580 | :param seed: The step received from the challenge | 579 | :param seed: The step received from the challenge |
| 581 | :type seed: int | 580 | :type seed: int |
| 582 | 581 | ||
| 583 | :raises OTPGeneratorException: In case step does not validate | 582 | :raises otp2289.OTPGeneratorException: If step does not validate |
| 584 | 583 | ||
| 585 | :return: The validated (and very same) step | 584 | :return: The validated (and very same) step |
| 586 | :rtype: int | 585 | :rtype: int |
| @@ -595,7 +594,6 @@ class OTPGenerator: | |||
| 595 | """ | 594 | """ |
| 596 | Generates the OTP hexdigest for the given step. | 595 | Generates the OTP hexdigest for the given step. |
| 597 | 596 | ||
| 598 | Keyword Arguments: | ||
| 599 | :param step: The step to generate OTP for | 597 | :param step: The step to generate OTP for |
| 600 | :type step: int | 598 | :type step: int |
| 601 | 599 | ||
| @@ -614,7 +612,6 @@ class OTPGenerator: | |||
| 614 | extract these parameters. The syntax of the challenge is: | 612 | extract these parameters. The syntax of the challenge is: |
| 615 | otp-<algorithm identifier> <sequence integer> <seed> | 613 | otp-<algorithm identifier> <sequence integer> <seed> |
| 616 | 614 | ||
| 617 | Keyword Arguments: | ||
| 618 | :param challenge: The challenge string | 615 | :param challenge: The challenge string |
| 619 | :type challenge: str | 616 | :type challenge: str |
| 620 | 617 | ||
| @@ -630,7 +627,6 @@ class OTPGenerator: | |||
| 630 | """ | 627 | """ |
| 631 | Generates the OTP six words token for the given step. | 628 | Generates the OTP six words token for the given step. |
| 632 | 629 | ||
| 633 | Keyword Arguments: | ||
| 634 | :param step: The step to generate OTP for | 630 | :param step: The step to generate OTP for |
| 635 | :type step: int | 631 | :type step: int |
| 636 | 632 | ||
| @@ -649,7 +645,6 @@ class OTPGenerator: | |||
| 649 | extract these parameters. The syntax of the challenge is: | 645 | extract these parameters. The syntax of the challenge is: |
| 650 | otp-<algorithm identifier> <sequence integer> <seed> | 646 | otp-<algorithm identifier> <sequence integer> <seed> |
| 651 | 647 | ||
| 652 | Keyword Arguments: | ||
| 653 | :param challenge: The challenge string | 648 | :param challenge: The challenge string |
| 654 | :type challenge: str | 649 | :type challenge: str |
| 655 | 650 | ||
| @@ -709,7 +704,6 @@ class OTPGenerator: | |||
| 709 | """ | 704 | """ |
| 710 | Generates the OTP bytes for the given step. | 705 | Generates the OTP bytes for the given step. |
| 711 | 706 | ||
| 712 | Keyword Arguments: | ||
| 713 | :param step: The step to generate OTP for | 707 | :param step: The step to generate OTP for |
| 714 | :type step: int | 708 | :type step: int |
| 715 | 709 | ||
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: | |||
| 71 | :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 | 71 | :param hash_algo: The hash algo, defaults to OTP_ALGO_MD5 |
| 72 | :type hash_algo: int or str | 72 | :type hash_algo: int or str |
| 73 | 73 | ||
| 74 | :raises OTPStateException: In case the input does not validate | 74 | :raises otp2289.OTPStateException: If the input does not validate |
| 75 | """ | 75 | """ |
| 76 | # enforce the rfc2289 constraints | 76 | # enforce the rfc2289 constraints |
| 77 | try: | 77 | try: |
| @@ -126,7 +126,7 @@ class OTPState: | |||
| 126 | :type dict_obj: dict | 126 | :type dict_obj: dict |
| 127 | 127 | ||
| 128 | :return: A new OTPState object | 128 | :return: A new OTPState object |
| 129 | :rtype: OTPStore | 129 | :rtype: otp2289.OTPStore |
| 130 | """ | 130 | """ |
| 131 | return cls(**dict_obj) | 131 | return cls(**dict_obj) |
| 132 | 132 | ||
| @@ -144,8 +144,9 @@ class OTPState: | |||
| 144 | :param response: The response to this state (its challenge) | 144 | :param response: The response to this state (its challenge) |
| 145 | :type response: str | 145 | :type response: str |
| 146 | 146 | ||
| 147 | :raises OTPInvalidResponse: If the response is corrupt / illegal, | 147 | :raises otp2289.OTPInvalidResponse: If the response is corrupt/illegal, |
| 148 | but not if it simply does not validate | 148 | but not if it simply does not |
| 149 | validate | ||
| 149 | 150 | ||
| 150 | :return: The bytes representation of response (if any) | 151 | :return: The bytes representation of response (if any) |
| 151 | :rtype: bytes | 152 | :rtype: bytes |
| @@ -168,7 +169,7 @@ class OTPState: | |||
| 168 | :param ot_hex: The one-time hex to validate | 169 | :param ot_hex: The one-time hex to validate |
| 169 | :type ot_hex: str | 170 | :type ot_hex: str |
| 170 | 171 | ||
| 171 | :raises OTPStateException: In case hex does not validate | 172 | :raises otp2289.OTPStateException: If hex does not validate |
| 172 | 173 | ||
| 173 | :return: The validated hex (without leading 0x) converted to bytes | 174 | :return: The validated hex (without leading 0x) converted to bytes |
| 174 | :rtype: bytes | 175 | :rtype: bytes |
| @@ -194,7 +195,7 @@ class OTPState: | |||
| 194 | where step -= 1 and ot_hex = self._new_digest_hex | 195 | where step -= 1 and ot_hex = self._new_digest_hex |
| 195 | 196 | ||
| 196 | :return: The next OTPState if validated, None otherwise | 197 | :return: The next OTPState if validated, None otherwise |
| 197 | :rtype: OTPState or None | 198 | :rtype: otp2289.OTPState or None |
| 198 | """ | 199 | """ |
| 199 | if self._new_digest_hex is None: | 200 | if self._new_digest_hex is None: |
| 200 | return None | 201 | return None |
| @@ -213,7 +214,8 @@ class OTPState: | |||
| 213 | :param store_valid_response: Should a valid response be stored | 214 | :param store_valid_response: Should a valid response be stored |
| 214 | :type store_valid_response: bool | 215 | :type store_valid_response: bool |
| 215 | 216 | ||
| 216 | :raises OTPInvalidResponse: If the response does not match this state | 217 | :raises otp2289.OTPInvalidResponse: If the response does not match |
| 218 | this state | ||
| 217 | 219 | ||
| 218 | :return: Returns True if response validates, False otherwise | 220 | :return: Returns True if response validates, False otherwise |
| 219 | :rtype: bool | 221 | :rtype: bool |
| @@ -328,9 +330,9 @@ class OTPStore: | |||
| 328 | :type key: str | 330 | :type key: str |
| 329 | 331 | ||
| 330 | :param state: The OTPState object | 332 | :param state: The OTPState object |
| 331 | :type state: OTPState | 333 | :type state: otp2289.OTPState |
| 332 | 334 | ||
| 333 | :raises OTPStoreException: On failure | 335 | :raises otp2289.OTPStoreException: On failure |
| 334 | """ | 336 | """ |
| 335 | if not isinstance(key, str): | 337 | if not isinstance(key, str): |
| 336 | raise OTPStoreException('key must be a str') | 338 | raise OTPStoreException('key must be a str') |
| @@ -356,10 +358,10 @@ class OTPStore: | |||
| 356 | 358 | ||
| 357 | :raises KeyError: If key does not exist | 359 | :raises KeyError: If key does not exist |
| 358 | 360 | ||
| 359 | :raises OTPStoreException: On failure | 361 | :raises otp2289.OTPStoreException: On failure |
| 360 | 362 | ||
| 361 | :return: The state corresponding to the key | 363 | :return: The state corresponding to the key |
| 362 | :rtype: OTPState | 364 | :rtype: otp2289.OTPState |
| 363 | """ | 365 | """ |
| 364 | if not isinstance(key, str): | 366 | if not isinstance(key, str): |
| 365 | raise OTPStoreException('key must be a str') | 367 | raise OTPStoreException('key must be a str') |
| @@ -387,7 +389,8 @@ class OTPStore: | |||
| 387 | 389 | ||
| 388 | :raises KeyError: If the key is not present | 390 | :raises KeyError: If the key is not present |
| 389 | 391 | ||
| 390 | :raises OTPInvalidResponse: If the response does not match this state | 392 | :raises otp2289.OTPInvalidResponse: If the response does not match |
| 393 | this state | ||
| 391 | 394 | ||
| 392 | :return: Returns True if response validates, False otherwise | 395 | :return: Returns True if response validates, False otherwise |
| 393 | :rtype: bool | 396 | :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 @@ | |||
| 1 | # Configuration file for the Sphinx documentation builder. | ||
| 2 | # | ||
| 3 | # This file only contains a selection of the most common options. For a full | ||
| 4 | # list see the documentation: | ||
| 5 | # http://www.sphinx-doc.org/en/master/config | ||
| 6 | |||
| 7 | # -- Path setup -------------------------------------------------------------- | ||
| 8 | |||
| 9 | # If extensions (or modules to document with autodoc) are in another directory, | ||
| 10 | # add these directories to sys.path here. If the directory is relative to the | ||
| 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. | ||
| 12 | # | ||
| 13 | # import os | ||
| 14 | # import sys | ||
| 15 | # sys.path.insert(0, '/home/sgs/development/gitprogs/python/pyotp2289/otp2289') | ||
| 16 | |||
| 17 | |||
| 18 | # -- Project information ----------------------------------------------------- | ||
| 19 | |||
| 20 | project = 'pyotp2289' | ||
| 21 | copyright = '2020, Simeon Simeonov' | ||
| 22 | author = 'Simeon Simeonov' | ||
| 23 | |||
| 24 | # The short X.Y version | ||
| 25 | version = '1.0.0' | ||
| 26 | |||
| 27 | # The full version, including alpha/beta/rc tags | ||
| 28 | release = '1.0.0' | ||
| 29 | |||
| 30 | |||
| 31 | # -- General configuration --------------------------------------------------- | ||
| 32 | |||
| 33 | # Add any Sphinx extension module names here, as strings. They can be | ||
| 34 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom | ||
| 35 | # ones. | ||
| 36 | extensions = [ | ||
| 37 | 'sphinx.ext.autodoc', | ||
| 38 | 'sphinx.ext.viewcode', | ||
| 39 | 'sphinx.ext.todo', | ||
| 40 | ] | ||
| 41 | |||
| 42 | # Add any paths that contain templates here, relative to this directory. | ||
| 43 | templates_path = ['_templates'] | ||
| 44 | |||
| 45 | # The suffix(es) of source filenames. | ||
| 46 | # You can specify multiple suffix as a list of string: | ||
| 47 | # | ||
| 48 | source_suffix = ['.rst', '.md'] | ||
| 49 | |||
| 50 | # The language for content autogenerated by Sphinx. Refer to documentation | ||
| 51 | # for a list of supported languages. | ||
| 52 | # | ||
| 53 | # This is also used if you do content translation via gettext catalogs. | ||
| 54 | # Usually you set "language" from the command line for these cases. | ||
| 55 | language = 'en' | ||
| 56 | |||
| 57 | # List of patterns, relative to source directory, that match files and | ||
| 58 | # directories to ignore when looking for source files. | ||
| 59 | # This pattern also affects html_static_path and html_extra_path. | ||
| 60 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] | ||
| 61 | |||
| 62 | |||
| 63 | # -- Options for HTML output ------------------------------------------------- | ||
| 64 | |||
| 65 | # The theme to use for HTML and HTML Help pages. See the documentation for | ||
| 66 | # a list of builtin themes. | ||
| 67 | # | ||
| 68 | html_theme = 'nature' | ||
| 69 | |||
| 70 | # Add any paths that contain custom static files (such as style sheets) here, | ||
| 71 | # relative to this directory. They are copied after the builtin static files, | ||
| 72 | # so a file named "default.css" will overwrite the builtin "default.css". | ||
| 73 | html_static_path = ['_static'] | ||
| 74 | |||
| 75 | |||
| 76 | # -- Extension configuration ------------------------------------------------- | ||
| 77 | |||
| 78 | # -- Options for todo extension ---------------------------------------------- | ||
| 79 | |||
| 80 | # If true, `todo` and `todoList` produce output, else they produce nothing. | ||
| 81 | todo_include_todos = True | ||
| 82 | |||
| 83 | # Generated by running: sphinx-apidoc with: | ||
| 84 | # -P -F -o html -H pyotp2289 -A "Simeon Simeonov" -V "1.0.0" otp2289 | ||
