4f6950f50ec0762fa2f9f378739379b71f23ac11
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py    1) # SPDX-FileCopyrightText: 2024 Marco Ricci <m@the13thletter.info>
src/derivepassphrase/types.py    2) #
src/derivepassphrase/types.py    3) # SPDX-License-Identifier: MIT
src/derivepassphrase/types.py    4) 
Marco Ricci Update documentation to use...

Marco Ricci authored 1 month ago

src/derivepassphrase/_types.py   5) """Types used by derivepassphrase."""
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py    6) 
src/derivepassphrase/types.py    7) from __future__ import annotations
src/derivepassphrase/types.py    8) 
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 1 month ago

src/derivepassphrase/_types.py   9) import enum
src/derivepassphrase/_types.py  10) from typing import NamedTuple, TypeGuard
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py   11) 
Marco Ricci Support Python 3.10 and PyP...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   12) from typing_extensions import (
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py   13)     Any,
src/derivepassphrase/types.py   14)     NotRequired,
src/derivepassphrase/types.py   15)     Required,
src/derivepassphrase/types.py   16)     TypedDict,
Marco Ricci Support Python 3.10 and PyP...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   17) )
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   18) 
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 1 month ago

src/derivepassphrase/_types.py  19) __all__ = (
src/derivepassphrase/_types.py  20)     'SSH_AGENT',
src/derivepassphrase/_types.py  21)     'SSH_AGENTC',
src/derivepassphrase/_types.py  22)     'KeyCommentPair',
src/derivepassphrase/_types.py  23)     'VaultConfig',
src/derivepassphrase/_types.py  24)     'is_vault_config',
src/derivepassphrase/_types.py  25) )
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   26) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py   27) 
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   28) class VaultConfigGlobalSettings(TypedDict, total=False):
src/derivepassphrase/types.py   29)     r"""Configuration for vault: global settings.
src/derivepassphrase/types.py   30) 
src/derivepassphrase/types.py   31)     Attributes:
src/derivepassphrase/types.py   32)         key:
src/derivepassphrase/types.py   33)             The base64-encoded ssh public key to use, overriding the
src/derivepassphrase/types.py   34)             master passphrase. Optional.
src/derivepassphrase/types.py   35)         phrase:
src/derivepassphrase/types.py   36)             The master passphrase. Optional.
src/derivepassphrase/types.py   37) 
src/derivepassphrase/types.py   38)     """
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py   39) 
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   40)     key: NotRequired[str]
src/derivepassphrase/types.py   41)     phrase: NotRequired[str]
src/derivepassphrase/types.py   42) 
src/derivepassphrase/types.py   43) 
src/derivepassphrase/types.py   44) class VaultConfigServicesSettings(VaultConfigGlobalSettings, total=False):
src/derivepassphrase/types.py   45)     r"""Configuration for vault: services settings.
src/derivepassphrase/types.py   46) 
src/derivepassphrase/types.py   47)     Attributes:
src/derivepassphrase/types.py   48)         notes:
src/derivepassphrase/types.py   49)             Optional notes for this service, to display to the user when
src/derivepassphrase/types.py   50)             generating the passphrase.
src/derivepassphrase/types.py   51)         length:
src/derivepassphrase/types.py   52)             Desired passphrase length.
src/derivepassphrase/types.py   53)         repeat:
src/derivepassphrase/types.py   54)             The maximum number of immediate character repetitions
src/derivepassphrase/types.py   55)             allowed in the passphrase.  Disabled if set to 0.
src/derivepassphrase/types.py   56)         lower:
src/derivepassphrase/types.py   57)             Optional constraint on ASCII lowercase characters.  If
src/derivepassphrase/types.py   58)             positive, include this many lowercase characters
src/derivepassphrase/types.py   59)             somewhere in the passphrase.  If 0, avoid lowercase
src/derivepassphrase/types.py   60)             characters altogether.
src/derivepassphrase/types.py   61)         upper:
src/derivepassphrase/types.py   62)             Same as `lower`, but for ASCII uppercase characters.
src/derivepassphrase/types.py   63)         number:
src/derivepassphrase/types.py   64)             Same as `lower`, but for ASCII digits.
src/derivepassphrase/types.py   65)         space:
src/derivepassphrase/types.py   66)             Same as `lower`, but for the space character.
src/derivepassphrase/types.py   67)         dash:
src/derivepassphrase/types.py   68)             Same as `lower`, but for the hyphen-minus and underscore
src/derivepassphrase/types.py   69)             characters.
src/derivepassphrase/types.py   70)         symbol:
src/derivepassphrase/types.py   71)             Same as `lower`, but for all other hitherto unlisted
src/derivepassphrase/types.py   72)             ASCII printable characters (except backquote).
src/derivepassphrase/types.py   73) 
src/derivepassphrase/types.py   74)     """
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py   75) 
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   76)     notes: NotRequired[str]
src/derivepassphrase/types.py   77)     length: NotRequired[int]
src/derivepassphrase/types.py   78)     repeat: NotRequired[int]
src/derivepassphrase/types.py   79)     lower: NotRequired[int]
src/derivepassphrase/types.py   80)     upper: NotRequired[int]
src/derivepassphrase/types.py   81)     number: NotRequired[int]
src/derivepassphrase/types.py   82)     space: NotRequired[int]
src/derivepassphrase/types.py   83)     dash: NotRequired[int]
src/derivepassphrase/types.py   84)     symbol: NotRequired[int]
src/derivepassphrase/types.py   85) 
src/derivepassphrase/types.py   86) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py   87) _VaultConfig = TypedDict(
src/derivepassphrase/types.py   88)     '_VaultConfig',
src/derivepassphrase/types.py   89)     {'global': NotRequired[VaultConfigGlobalSettings]},
src/derivepassphrase/types.py   90)     total=False,
src/derivepassphrase/types.py   91) )
src/derivepassphrase/types.py   92) 
src/derivepassphrase/types.py   93) 
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py   94) class VaultConfig(TypedDict, _VaultConfig, total=False):
src/derivepassphrase/types.py   95)     r"""Configuration for vault.
src/derivepassphrase/types.py   96) 
src/derivepassphrase/types.py   97)     Usually stored as JSON.
src/derivepassphrase/types.py   98) 
src/derivepassphrase/types.py   99)     Attributes:
src/derivepassphrase/types.py  100)         global (NotRequired[VaultConfigGlobalSettings]):
src/derivepassphrase/types.py  101)             Global settings.
src/derivepassphrase/types.py  102)         services (Required[dict[str, VaultConfigServicesSettings]]):
src/derivepassphrase/types.py  103)             Service-specific settings.
src/derivepassphrase/types.py  104) 
src/derivepassphrase/types.py  105)     """
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py  106) 
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py  107)     services: Required[dict[str, VaultConfigServicesSettings]]
src/derivepassphrase/types.py  108) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

src/derivepassphrase/types.py  109) 
Marco Ricci Move typing classes into se...

Marco Ricci authored 2 months ago

src/derivepassphrase/types.py  110) def is_vault_config(obj: Any) -> TypeGuard[VaultConfig]:
src/derivepassphrase/types.py  111)     """Check if `obj` is a valid vault config, according to typing.
src/derivepassphrase/types.py  112) 
src/derivepassphrase/types.py  113)     Args:
src/derivepassphrase/types.py  114)         obj: The object to test.
src/derivepassphrase/types.py  115) 
src/derivepassphrase/types.py  116)     Returns:
src/derivepassphrase/types.py  117)         True if this is a vault config, false otherwise.
src/derivepassphrase/types.py  118) 
src/derivepassphrase/types.py  119)     """
src/derivepassphrase/types.py  120)     if not isinstance(obj, dict):
src/derivepassphrase/types.py  121)         return False
src/derivepassphrase/types.py  122)     if 'global' in obj:
src/derivepassphrase/types.py  123)         o_global = obj['global']
src/derivepassphrase/types.py  124)         if not isinstance(o_global, dict):
src/derivepassphrase/types.py  125)             return False
src/derivepassphrase/types.py  126)         for key in ('key', 'phrase'):
src/derivepassphrase/types.py  127)             if key in o_global and not isinstance(o_global[key], str):
src/derivepassphrase/types.py  128)                 return False
src/derivepassphrase/types.py  129)         if 'key' in o_global and 'phrase' in o_global:
src/derivepassphrase/types.py  130)             return False
src/derivepassphrase/types.py  131)     if not isinstance(obj.get('services'), dict):
src/derivepassphrase/types.py  132)         return False
src/derivepassphrase/types.py  133)     for sv_name, service in obj['services'].items():
src/derivepassphrase/types.py  134)         if not isinstance(sv_name, str):
src/derivepassphrase/types.py  135)             return False
src/derivepassphrase/types.py  136)         if not isinstance(service, dict):
src/derivepassphrase/types.py  137)             return False
src/derivepassphrase/types.py  138)         for key, value in service.items():
src/derivepassphrase/types.py  139)             match key:
src/derivepassphrase/types.py  140)                 case 'notes' | 'phrase' | 'key':
src/derivepassphrase/types.py  141)                     if not isinstance(value, str):
src/derivepassphrase/types.py  142)                         return False
src/derivepassphrase/types.py  143)                 case 'length':
src/derivepassphrase/types.py  144)                     if not isinstance(value, int) or value < 1:
src/derivepassphrase/types.py  145)                         return False
src/derivepassphrase/types.py  146)                 case _:
src/derivepassphrase/types.py  147)                     if not isinstance(value, int) or value < 0:
src/derivepassphrase/types.py  148)                         return False
src/derivepassphrase/types.py  149)         if 'key' in service and 'phrase' in service:
src/derivepassphrase/types.py  150)             return False
src/derivepassphrase/types.py  151)     return True