mirror of
https://github.com/enpaul/spectrepy.git
synced 2025-04-22 02:43:33 +00:00
Compare commits
No commits in common. "1c34dc41a0721a06061241b012c2c6961d2d4a9d" and "b32bcf597aab94abbfa40243e581ea005daf3962" have entirely different histories.
1c34dc41a0
...
b32bcf597a
@ -1,79 +0,0 @@
|
|||||||
---
|
|
||||||
# All of the pre-commit hooks here actually use the `pytyhon` pre-commit language
|
|
||||||
# setting. However, for the python language setting, pre-commit will create and manage
|
|
||||||
# a cached virtual environment for each hook ID and do a bare `pip install <repo>` into
|
|
||||||
# the venv to setup the hook. This can result in conflicting dependency versions between
|
|
||||||
# the version installed to the pre-commit venv and the version installed to the Poetry
|
|
||||||
# venv specified in the lockfile.
|
|
||||||
#
|
|
||||||
# The solution is to specify `language: system` for all hooks and then install the
|
|
||||||
# required dependencies to the Poetry venv. The `system` language skips the isolated
|
|
||||||
# venv creation and looks for the entrypoint specified by the hook in the global
|
|
||||||
# environment which, if running in the Poetry venv, will find the entrypoint provided
|
|
||||||
# by the Poetry-managed dependency.
|
|
||||||
#
|
|
||||||
repos:
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
name: end-of-file-fixer
|
|
||||||
entry: end-of-file-fixer
|
|
||||||
language: system
|
|
||||||
types:
|
|
||||||
- text
|
|
||||||
|
|
||||||
- id: fix-encoding-pragma
|
|
||||||
name: fix-encoding-pragma
|
|
||||||
entry: fix-encoding-pragma
|
|
||||||
language: system
|
|
||||||
args:
|
|
||||||
- "--remove"
|
|
||||||
types:
|
|
||||||
- python
|
|
||||||
|
|
||||||
- id: trailing-whitespace-fixer
|
|
||||||
name: trailing-whitespace-fixer
|
|
||||||
entry: trailing-whitespace-fixer
|
|
||||||
language: system
|
|
||||||
types:
|
|
||||||
- text
|
|
||||||
|
|
||||||
- id: check-merge-conflict
|
|
||||||
name: check-merge-conflict
|
|
||||||
entry: check-merge-conflict
|
|
||||||
language: system
|
|
||||||
types:
|
|
||||||
- text
|
|
||||||
|
|
||||||
- id: reorder-python-imports
|
|
||||||
name: reorder-python-imports
|
|
||||||
entry: reorder-python-imports
|
|
||||||
language: system
|
|
||||||
args:
|
|
||||||
- "--unclassifiable-application-module=tox_poetry_installer"
|
|
||||||
types:
|
|
||||||
- python
|
|
||||||
|
|
||||||
- id: black
|
|
||||||
name: black
|
|
||||||
entry: black
|
|
||||||
language: system
|
|
||||||
types:
|
|
||||||
- python
|
|
||||||
|
|
||||||
- id: blacken-docs
|
|
||||||
name: blacken-docs
|
|
||||||
entry: blacken-docs
|
|
||||||
language: system
|
|
||||||
types:
|
|
||||||
- text
|
|
||||||
|
|
||||||
- id: mdformat
|
|
||||||
name: mdformat
|
|
||||||
entry: mdformat
|
|
||||||
language: system
|
|
||||||
args:
|
|
||||||
- "--number"
|
|
||||||
- "--wrap=90"
|
|
||||||
types:
|
|
||||||
- markdown
|
|
@ -11,6 +11,7 @@
|
|||||||
# --disable=W"
|
# --disable=W"
|
||||||
disable=logging-fstring-interpolation
|
disable=logging-fstring-interpolation
|
||||||
,logging-format-interpolation
|
,logging-format-interpolation
|
||||||
|
,bad-continuation
|
||||||
,line-too-long
|
,line-too-long
|
||||||
,ungrouped-imports
|
,ungrouped-imports
|
||||||
,typecheck
|
,typecheck
|
||||||
|
@ -27,10 +27,9 @@ Examples of unacceptable behavior include:
|
|||||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
- Public or private harassment
|
- Public or private harassment
|
||||||
- Publishing others' private information, such as a physical or email address, without
|
- Publishing others' private information, such as a physical or email address, without their
|
||||||
their explicit permission
|
explicit permission
|
||||||
- Other conduct which could reasonably be considered inappropriate in a professional
|
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
@ -53,8 +52,8 @@ offline event.
|
|||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the
|
||||||
community leaders responsible for enforcement at \[INSERT CONTACT METHOD\]. All complaints
|
community leaders responsible for enforcement at \[INSERT CONTACT METHOD\]. All
|
||||||
will be reviewed and investigated promptly and fairly.
|
complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the reporter of
|
All community leaders are obligated to respect the privacy and security of the reporter of
|
||||||
any incident.
|
any incident.
|
||||||
@ -106,8 +105,8 @@ toward or disparagement of classes of individuals.
|
|||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
|
||||||
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
https://www.contributor-covenant.org/faq. Translations are available at
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
40
Makefile
40
Makefile
@ -1,40 +0,0 @@
|
|||||||
# spectrepy makefile
|
|
||||||
|
|
||||||
.PHONY: help
|
|
||||||
# Put it first so that "make" without argument is like "make help"
|
|
||||||
# Adapted from:
|
|
||||||
# https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
|
||||||
help: ## List Makefile targets
|
|
||||||
$(info Makefile documentation)
|
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-10s\033[0m %s\n", $$1, $$2}'
|
|
||||||
|
|
||||||
clean-tox:
|
|
||||||
rm --recursive --force ./.mypy_cache
|
|
||||||
rm --recursive --force ./.tox
|
|
||||||
rm --recursive --force tests/__pycache__/
|
|
||||||
rm --recursive --force .pytest_cache/
|
|
||||||
rm --force .coverage
|
|
||||||
|
|
||||||
clean-py:
|
|
||||||
rm --recursive --force ./dist
|
|
||||||
rm --recursive --force ./build
|
|
||||||
rm --recursive --force ./*.egg-info
|
|
||||||
rm --recursive --force ./**/__pycache__/
|
|
||||||
|
|
||||||
clean: clean-tox clean-py; ## Clean temp build/cache files and directories
|
|
||||||
|
|
||||||
wheel: ## Build Python binary distribution wheel package
|
|
||||||
poetry build --format wheel
|
|
||||||
|
|
||||||
source: ## Build Python source distribution package
|
|
||||||
poetry build --format sdist
|
|
||||||
|
|
||||||
test: ## Run the project testsuite(s)
|
|
||||||
poetry run tox --recreate --parallel
|
|
||||||
|
|
||||||
dev: ## Create the local dev environment
|
|
||||||
poetry install --with dev --sync
|
|
||||||
poetry run pre-commit install
|
|
||||||
|
|
||||||
publish: test wheel source ## Build and upload to pypi (requires $PYPI_API_KEY be set)
|
|
||||||
@poetry publish --username __token__ --password $(PYPI_API_KEY)
|
|
2720
poetry.lock
generated
2720
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,64 +1,14 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "spectrepy"
|
name = "spectrepy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
license = "MIT"
|
|
||||||
description = "Python bindings for the Spectre Password Manager"
|
description = "Python bindings for the Spectre Password Manager"
|
||||||
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
||||||
repository = "https://github.com/enpaul/spectrepy/"
|
license = "MIT"
|
||||||
packages = [
|
|
||||||
{include = "spectrepy.py"},
|
|
||||||
{include = "tests/*.py", format = "sdist"}
|
|
||||||
]
|
|
||||||
keywords = ["spectre", "mpw", "password", "manager", "masterpassword"]
|
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
classifiers = [
|
|
||||||
"Development Status :: 1 - Planning",
|
|
||||||
"Environment :: Console",
|
|
||||||
"Intended Audience :: Developers",
|
|
||||||
"Intended Audience :: Information Technology",
|
|
||||||
"Intended Audience :: System Administrators",
|
|
||||||
"License :: OSI Approved :: MIT License",
|
|
||||||
"Natural Language :: English",
|
|
||||||
"Operating System :: POSIX",
|
|
||||||
"Programming Language :: Python :: 3",
|
|
||||||
"Programming Language :: Python :: 3.7",
|
|
||||||
"Programming Language :: Python :: 3.8",
|
|
||||||
"Programming Language :: Python :: 3.9",
|
|
||||||
"Programming Language :: Python :: 3.10",
|
|
||||||
"Programming Language :: Python :: 3.11",
|
|
||||||
"Programming Language :: Python :: Implementation :: CPython"
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.7"
|
python = "^3.7"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
|
||||||
black = {version = "^23.3.0", python = "^3.10"}
|
|
||||||
blacken-docs = {version = "^1.13.0", python = "^3.10"}
|
|
||||||
ipython = {version = "^8.12.0", python = "^3.10"}
|
|
||||||
mdformat = {version = "^0.7.16", python = "^3.10"}
|
|
||||||
mdformat-gfm = {version = "^0.3.5", python = "^3.10"}
|
|
||||||
mypy = {version = "^1.1.1", python = "^3.10"}
|
|
||||||
pre-commit = {version = "^3.2.1", python = "^3.10"}
|
|
||||||
pre-commit-hooks = {version = "^4.4.0", python = "^3.10"}
|
|
||||||
pylint = {version = "^2.17.1", python = "^3.10"}
|
|
||||||
reorder-python-imports = {version = "^3.9.0", python = "^3.10"}
|
|
||||||
types-toml = {version = "^0.10.8.6", python = "^3.10"}
|
|
||||||
toml = {version = "^0.10.2", python = "^3.10"}
|
|
||||||
|
|
||||||
[tool.poetry.group.test.dependencies]
|
|
||||||
pytest = "^7.2.2"
|
|
||||||
pytest-cov = "^4.0.0"
|
|
||||||
toml = "^0.10.2"
|
|
||||||
typing-extensions = {version = "^4.5.0", python = "^3.8"}
|
|
||||||
|
|
||||||
[tool.poetry.group.ci.dependencies]
|
|
||||||
tox = "^3.20"
|
|
||||||
tox-poetry-installer = {extras = ["poetry"], version = "^0.10.2"}
|
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.group.security.dependencies]
|
|
||||||
bandit = {version = "^1.7.5", python = "^3.10"}
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
119
spectrepy.py
119
spectrepy.py
@ -1,119 +0,0 @@
|
|||||||
"""Python library bindings for the Spectre password manager"""
|
|
||||||
import enum
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Optional
|
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
|
|
||||||
__title__ = "spectrepy"
|
|
||||||
__summary__ = "Python bindings for the Spectre Password Manager"
|
|
||||||
__version__ = "0.1.0"
|
|
||||||
__url__ = "https://github.com/enpaul/spectrepy/"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"__title__",
|
|
||||||
"__summary__",
|
|
||||||
"__version__",
|
|
||||||
"__url__",
|
|
||||||
"__license__",
|
|
||||||
"__authors__",
|
|
||||||
"SpectrePasswordType",
|
|
||||||
"SpectreAlgorithmVersion",
|
|
||||||
"SpectrePassword",
|
|
||||||
"Spectre",
|
|
||||||
"generate",
|
|
||||||
"get_version",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class SpectrePasswordType(enum.Enum):
|
|
||||||
X = "maximum"
|
|
||||||
L = "long"
|
|
||||||
M = "medium"
|
|
||||||
B = "basic"
|
|
||||||
S = "short"
|
|
||||||
I = "pin"
|
|
||||||
N = "name"
|
|
||||||
P = "phrase"
|
|
||||||
K = "key"
|
|
||||||
|
|
||||||
|
|
||||||
class SpectreAlgorithmVersion(enum.Enum):
|
|
||||||
V0 = 0
|
|
||||||
V1 = 1
|
|
||||||
V2 = 2
|
|
||||||
V3 = 3
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class SpectrePassword:
|
|
||||||
site: str
|
|
||||||
identicon: str
|
|
||||||
password_type: SpectrePasswordType
|
|
||||||
username: str
|
|
||||||
algorithm_version: SpectreAlgorithmVersion
|
|
||||||
context: str
|
|
||||||
|
|
||||||
|
|
||||||
def generate(*args, **kwargs) -> SpectrePassword:
|
|
||||||
return Spectre(*args, **kwargs).generate()
|
|
||||||
|
|
||||||
|
|
||||||
def get_version(*args, **kwargs) -> str:
|
|
||||||
return Spectre(*args, **kwargs).version
|
|
||||||
|
|
||||||
|
|
||||||
def get_path(*args, **kwargs) -> Path:
|
|
||||||
return Spectre(*args, **kwargs).path
|
|
||||||
|
|
||||||
|
|
||||||
class Spectre:
|
|
||||||
def __init__(self, binary: Optional[Union[str, Path]] = None):
|
|
||||||
self._path: Path
|
|
||||||
self._version: str
|
|
||||||
|
|
||||||
self._path = (
|
|
||||||
Path(binary).resolve() if binary is not None else self._find_binary()
|
|
||||||
)
|
|
||||||
self._version = self._fetch_version()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def version(self) -> str:
|
|
||||||
return self._version
|
|
||||||
|
|
||||||
@property
|
|
||||||
def program(self) -> str:
|
|
||||||
return self._program
|
|
||||||
|
|
||||||
@property
|
|
||||||
def path(self) -> Path:
|
|
||||||
return self._path
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _find_binary() -> Path:
|
|
||||||
binary = shutil.which("spectre") or shutil.which("mpw")
|
|
||||||
|
|
||||||
if not binary:
|
|
||||||
raise RuntimeError
|
|
||||||
return Path(binary)
|
|
||||||
|
|
||||||
def generate(self) -> SpectrePassword:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _call(self, *args, raise_errors: bool = True) -> subprocess.CompletedProcess:
|
|
||||||
result = subprocess.run([str(self._path)] + [*args], capture_output=True)
|
|
||||||
|
|
||||||
if result.returncode != 0 and raise_errors:
|
|
||||||
raise RuntimeError
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _fetch_version(self) -> str:
|
|
||||||
out = self._call("-h")
|
|
||||||
raw = out.stderr.decode().split("\n")[0].strip().split(" ")
|
|
||||||
version = raw[-1]
|
|
||||||
return version
|
|
@ -1,37 +0,0 @@
|
|||||||
"""Ensure that the pyproject and module metadata never drift out of sync
|
|
||||||
|
|
||||||
The next best thing to having one source of truth is having a way to ensure all of your
|
|
||||||
sources of truth agree with each other.
|
|
||||||
"""
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import toml
|
|
||||||
|
|
||||||
import spectrepy
|
|
||||||
|
|
||||||
|
|
||||||
def test_metadata():
|
|
||||||
"""Test that module metadata matches pyproject poetry metadata"""
|
|
||||||
|
|
||||||
with (Path(__file__).resolve().parent / ".." / "pyproject.toml").open() as infile:
|
|
||||||
pyproject = toml.load(infile, _dict=dict)
|
|
||||||
|
|
||||||
assert pyproject["tool"]["poetry"]["name"] == spectrepy.__title__
|
|
||||||
assert pyproject["tool"]["poetry"]["version"] == spectrepy.__version__
|
|
||||||
assert pyproject["tool"]["poetry"]["license"] == spectrepy.__license__
|
|
||||||
assert pyproject["tool"]["poetry"]["description"] == spectrepy.__summary__
|
|
||||||
assert pyproject["tool"]["poetry"]["repository"] == spectrepy.__url__
|
|
||||||
assert (
|
|
||||||
all(
|
|
||||||
item in spectrepy.__authors__
|
|
||||||
for item in pyproject["tool"]["poetry"]["authors"]
|
|
||||||
)
|
|
||||||
is True
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
all(
|
|
||||||
item in pyproject["tool"]["poetry"]["authors"]
|
|
||||||
for item in spectrepy.__authors__
|
|
||||||
)
|
|
||||||
is True
|
|
||||||
)
|
|
63
tox.ini
63
tox.ini
@ -1,63 +0,0 @@
|
|||||||
[tox]
|
|
||||||
envlist = py3{7,8,9,10,11}, static, static-tests, security
|
|
||||||
isolated_build = true
|
|
||||||
skip_missing_interpreters = true
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
description = Run the tests
|
|
||||||
require_locked_deps = true
|
|
||||||
require_poetry = true
|
|
||||||
poetry_dep_groups =
|
|
||||||
test
|
|
||||||
commands =
|
|
||||||
pytest {toxinidir}/tests/ \
|
|
||||||
--cov spectrepy \
|
|
||||||
--cov-config {toxinidir}/.coveragerc \
|
|
||||||
--cov-report term-missing
|
|
||||||
|
|
||||||
[testenv:static]
|
|
||||||
description = Static formatting and quality enforcement
|
|
||||||
basepython = python3.10
|
|
||||||
platform = linux
|
|
||||||
ignore_errors = true
|
|
||||||
poetry_dep_groups =
|
|
||||||
dev
|
|
||||||
commands =
|
|
||||||
pre-commit run \
|
|
||||||
--all-files
|
|
||||||
pylint {toxinidir}/spectrepy.py \
|
|
||||||
--rcfile {toxinidir}/.pylintrc
|
|
||||||
mypy {toxinidir}/spectrepy.py \
|
|
||||||
--ignore-missing-imports \
|
|
||||||
--no-strict-optional
|
|
||||||
|
|
||||||
[testenv:static-tests]
|
|
||||||
description = Static formatting and quality enforcement for the tests
|
|
||||||
basepython = python3.10
|
|
||||||
platform = linux
|
|
||||||
ignore_errors = true
|
|
||||||
poetry_dep_groups =
|
|
||||||
dev
|
|
||||||
commands =
|
|
||||||
pylint {toxinidir}/tests/ \
|
|
||||||
--rcfile {toxinidir}/.pylintrc
|
|
||||||
mypy {toxinidir}/tests/ \
|
|
||||||
--ignore-missing-imports \
|
|
||||||
--no-strict-optional
|
|
||||||
|
|
||||||
[testenv:security]
|
|
||||||
description = Security checks
|
|
||||||
basepython = python3.10
|
|
||||||
platform = linux
|
|
||||||
ignore_errors = true
|
|
||||||
skip_install = true
|
|
||||||
poetry_dep_groups =
|
|
||||||
security
|
|
||||||
commands =
|
|
||||||
bandit {toxinidir}/spectrepy.py \
|
|
||||||
--recursive \
|
|
||||||
--quiet
|
|
||||||
bandit {toxinidir}/tests/ \
|
|
||||||
--recursive \
|
|
||||||
--quiet \
|
|
||||||
--skip B101
|
|
Loading…
x
Reference in New Issue
Block a user