pyauth / pyotp
Showing 3 of 6 files from the diff.
Other files ignored by Codecov
test.py has changed.
setup.py has changed.
docs/index.rst has changed.

@@ -3,6 +3,7 @@
Loading
3 3
from typing import Any, Dict, Sequence
4 4
from urllib.parse import unquote, urlparse, parse_qsl
5 5
6 +
from . import contrib  # noqa:F401
6 7
from .compat import random
7 8
from .hotp import HOTP as HOTP
8 9
from .otp import OTP as OTP

@@ -0,0 +1,43 @@
Loading
1 +
from typing import Optional
2 +
import hashlib
3 +
4 +
from ..totp import TOTP
5 +
6 +
STEAM_CHARS = "23456789BCDFGHJKMNPQRTVWXY"  # steam's custom alphabet
7 +
STEAM_DEFAULT_DIGITS = 5  # Steam TOTP code length
8 +
9 +
10 +
class Steam(TOTP):
11 +
    """
12 +
    Steam's custom TOTP. Subclass of `pyotp.totp.TOTP`.
13 +
    """
14 +
15 +
    def __init__(self, s: str, name: Optional[str] = None,
16 +
                 issuer: Optional[str] = None, interval: int = 30) -> None:
17 +
        """
18 +
        :param s: secret in base32 format
19 +
        :param interval: the time interval in seconds for OTP. This defaults to 30.
20 +
        :param name: account name
21 +
        :param issuer: issuer
22 +
        """
23 +
        self.interval = interval
24 +
        super().__init__(s=s, digits=10, digest=hashlib.sha1, name=name, issuer=issuer)
25 +
26 +
    def generate_otp(self, input: int) -> str:
27 +
        """
28 +
        :param input: the HMAC counter value to use as the OTP input.
29 +
            Usually either the counter, or the computed integer based on the Unix timestamp
30 +
        """
31 +
        str_code = super().generate_otp(input)
32 +
        int_code = int(str_code)
33 +
34 +
        steam_code = ""
35 +
        total_chars = len(STEAM_CHARS)
36 +
37 +
        for _ in range(STEAM_DEFAULT_DIGITS):
38 +
            pos = int_code % total_chars
39 +
            char = STEAM_CHARS[int(pos)]
40 +
            steam_code += char
41 +
            int_code //= total_chars
42 +
43 +
        return steam_code

@@ -0,0 +1, @@
Loading
1 +
from .steam import Steam  # noqa:F401
Files Coverage
src/pyotp 98.03%
Project Totals (8 files) 98.03%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading