format everything with black
This commit is contained in:
@@ -1 +1 @@
|
|||||||
skips: ['B101']
|
skips: ["B101"]
|
||||||
|
|||||||
25
default.nix
25
default.nix
@@ -1,7 +1,22 @@
|
|||||||
{ pkgs ? import <nixpkgs> {} }:
|
{ buildPythonPackage, lib, pytest, }:
|
||||||
|
|
||||||
let
|
buildPythonPackage rec {
|
||||||
app = pkgs.poetry2nix.mkPoetryApplication {
|
pname = "pyrad3";
|
||||||
projectDir = ./.;
|
version = "3.0.0";
|
||||||
|
|
||||||
|
src = "./.";
|
||||||
|
|
||||||
|
checkInputs = [ pytest ];
|
||||||
|
|
||||||
|
checkPhase = ''
|
||||||
|
pytest
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Python RADIUS Implementation";
|
||||||
|
homepage = "";
|
||||||
|
license = [licenses.mit licenses.apache2];
|
||||||
|
maintainers = [ maintainers.lvkm ];
|
||||||
};
|
};
|
||||||
in app.dependencyEnv
|
}
|
||||||
|
|||||||
535
poetry.lock
generated
535
poetry.lock
generated
@@ -1,26 +1,26 @@
|
|||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "apipkg: namespace control and lazy-import mechanism"
|
|
||||||
name = "apipkg"
|
name = "apipkg"
|
||||||
|
version = "1.5"
|
||||||
|
description = "apipkg: namespace control and lazy-import mechanism"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "1.5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
|
||||||
name = "appdirs"
|
name = "appdirs"
|
||||||
|
version = "1.4.4"
|
||||||
|
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.4.4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "An abstract syntax tree for Python with inference support."
|
|
||||||
name = "astroid"
|
name = "astroid"
|
||||||
|
version = "2.4.2"
|
||||||
|
description = "An abstract syntax tree for Python with inference support."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "2.4.2"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
lazy-object-proxy = ">=1.4.0,<1.5.0"
|
lazy-object-proxy = ">=1.4.0,<1.5.0"
|
||||||
@@ -28,25 +28,25 @@ six = ">=1.12,<2.0"
|
|||||||
wrapt = ">=1.11,<2.0"
|
wrapt = ">=1.11,<2.0"
|
||||||
|
|
||||||
[package.dependencies.typed-ast]
|
[package.dependencies.typed-ast]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=1.4.0,<1.5"
|
version = ">=1.4.0,<1.5"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Atomic file writes."
|
|
||||||
marker = "sys_platform == \"win32\""
|
|
||||||
name = "atomicwrites"
|
name = "atomicwrites"
|
||||||
|
version = "1.4.0"
|
||||||
|
description = "Atomic file writes."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "1.4.0"
|
marker = "sys_platform == \"win32\""
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Classes Without Boilerplate"
|
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
|
version = "20.2.0"
|
||||||
|
description = "Classes Without Boilerplate"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "20.2.0"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"]
|
dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"]
|
||||||
@@ -55,97 +55,99 @@ tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six
|
|||||||
tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Security oriented static analyser for python code."
|
|
||||||
name = "bandit"
|
name = "bandit"
|
||||||
|
version = "1.6.2"
|
||||||
|
description = "Security oriented static analyser for python code."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.6.2"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
colorama = ">=0.3.9"
|
||||||
GitPython = ">=1.0.1"
|
GitPython = ">=1.0.1"
|
||||||
PyYAML = ">=3.13"
|
PyYAML = ">=3.13"
|
||||||
colorama = ">=0.3.9"
|
|
||||||
six = ">=1.10.0"
|
six = ">=1.10.0"
|
||||||
stevedore = ">=1.20.0"
|
stevedore = ">=1.20.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "The uncompromising code formatter."
|
|
||||||
name = "black"
|
name = "black"
|
||||||
|
version = "20.8b1"
|
||||||
|
description = "The uncompromising code formatter."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
version = "19.10b0"
|
|
||||||
|
[package.extras]
|
||||||
|
colorama = ["colorama (>=0.4.3)"]
|
||||||
|
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
appdirs = "*"
|
appdirs = "*"
|
||||||
attrs = ">=18.1.0"
|
click = ">=7.1.2"
|
||||||
click = ">=6.5"
|
mypy-extensions = ">=0.4.3"
|
||||||
pathspec = ">=0.6,<1"
|
pathspec = ">=0.6,<1"
|
||||||
regex = "*"
|
regex = ">=2020.1.8"
|
||||||
toml = ">=0.9.4"
|
toml = ">=0.10.1"
|
||||||
typed-ast = ">=1.4.0"
|
typed-ast = ">=1.4.0"
|
||||||
|
typing-extensions = ">=3.7.4"
|
||||||
[package.extras]
|
|
||||||
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Composable command line interface toolkit"
|
|
||||||
name = "click"
|
name = "click"
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|
||||||
version = "7.1.2"
|
version = "7.1.2"
|
||||||
|
description = "Composable command line interface toolkit"
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Cross-platform colored terminal text."
|
|
||||||
marker = "platform_system == \"Windows\" or sys_platform == \"win32\""
|
|
||||||
name = "colorama"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
version = "0.4.3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "colorama"
|
||||||
|
version = "0.4.3"
|
||||||
|
description = "Cross-platform colored terminal text."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Code coverage measurement for Python"
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
marker = "platform_system == \"Windows\" or sys_platform == \"win32\""
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "coverage"
|
name = "coverage"
|
||||||
|
version = "5.3"
|
||||||
|
description = "Code coverage measurement for Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||||
version = "5.2.1"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
toml = ["toml"]
|
toml = ["toml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "execnet: rapid multi-Python deployment"
|
|
||||||
name = "execnet"
|
name = "execnet"
|
||||||
|
version = "1.7.1"
|
||||||
|
description = "execnet: rapid multi-Python deployment"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "1.7.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
apipkg = ">=1.4"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
testing = ["pre-commit"]
|
testing = ["pre-commit"]
|
||||||
|
|
||||||
[[package]]
|
[package.dependencies]
|
||||||
category = "dev"
|
apipkg = ">=1.4"
|
||||||
description = "A platform independent file lock."
|
|
||||||
name = "filelock"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.0.12"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "filelock"
|
||||||
|
version = "3.0.12"
|
||||||
|
description = "A platform independent file lock."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "the modular source code checker: pep8 pyflakes and co"
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "flake8"
|
name = "flake8"
|
||||||
|
version = "3.8.3"
|
||||||
|
description = "the modular source code checker: pep8 pyflakes and co"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
||||||
version = "3.8.3"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mccabe = ">=0.6.0,<0.7.0"
|
mccabe = ">=0.6.0,<0.7.0"
|
||||||
@@ -153,215 +155,214 @@ pycodestyle = ">=2.6.0a1,<2.7.0"
|
|||||||
pyflakes = ">=2.2.0,<2.3.0"
|
pyflakes = ">=2.2.0,<2.3.0"
|
||||||
|
|
||||||
[package.dependencies.importlib-metadata]
|
[package.dependencies.importlib-metadata]
|
||||||
python = "<3.8"
|
|
||||||
version = "*"
|
version = "*"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Polyfill package for Flake8 plugins"
|
|
||||||
name = "flake8-polyfill"
|
name = "flake8-polyfill"
|
||||||
|
version = "1.0.2"
|
||||||
|
description = "Polyfill package for Flake8 plugins"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.0.2"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
flake8 = "*"
|
flake8 = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Git Object Database"
|
|
||||||
name = "gitdb"
|
name = "gitdb"
|
||||||
|
version = "4.0.5"
|
||||||
|
description = "Git Object Database"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.4"
|
python-versions = ">=3.4"
|
||||||
version = "4.0.5"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
smmap = ">=3.0.1,<4"
|
smmap = ">=3.0.1,<4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python Git Library"
|
|
||||||
name = "gitpython"
|
name = "gitpython"
|
||||||
|
version = "3.1.8"
|
||||||
|
description = "Python Git Library"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.4"
|
python-versions = ">=3.4"
|
||||||
version = "3.1.8"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
gitdb = ">=4.0.1,<5"
|
gitdb = ">=4.0.1,<5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Read metadata from Python packages"
|
|
||||||
marker = "python_version < \"3.8\""
|
|
||||||
name = "importlib-metadata"
|
name = "importlib-metadata"
|
||||||
|
version = "1.7.0"
|
||||||
|
description = "Read metadata from Python packages"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||||
version = "1.7.0"
|
marker = "python_version < \"3.8\""
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
zipp = ">=0.5"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinx", "rst.linker"]
|
docs = ["sphinx", "rst.linker"]
|
||||||
testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
|
testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
|
||||||
|
|
||||||
[[package]]
|
[package.dependencies]
|
||||||
category = "dev"
|
zipp = ">=0.5"
|
||||||
description = "iniconfig: brain-dead simple config-ini parsing"
|
|
||||||
name = "iniconfig"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.0.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "iniconfig"
|
||||||
|
version = "1.0.1"
|
||||||
|
description = "iniconfig: brain-dead simple config-ini parsing"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "A Python utility / library to sort Python imports."
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "isort"
|
name = "isort"
|
||||||
|
version = "5.5.3"
|
||||||
|
description = "A Python utility / library to sort Python imports."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6,<4.0"
|
python-versions = ">=3.6,<4.0"
|
||||||
version = "5.5.1"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
|
||||||
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
|
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
|
||||||
requirements_deprecated_finder = ["pipreqs", "pip-api"]
|
requirements_deprecated_finder = ["pipreqs", "pip-api"]
|
||||||
|
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "A fast and thorough lazy object proxy."
|
|
||||||
name = "lazy-object-proxy"
|
name = "lazy-object-proxy"
|
||||||
|
version = "1.4.3"
|
||||||
|
description = "A fast and thorough lazy object proxy."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "1.4.3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "McCabe checker, plugin for flake8"
|
|
||||||
name = "mccabe"
|
name = "mccabe"
|
||||||
|
version = "0.6.1"
|
||||||
|
description = "McCabe checker, plugin for flake8"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.6.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "More routines for operating on iterables, beyond itertools"
|
|
||||||
name = "more-itertools"
|
name = "more-itertools"
|
||||||
|
version = "8.5.0"
|
||||||
|
description = "More routines for operating on iterables, beyond itertools"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "8.5.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Optional static typing for Python"
|
|
||||||
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
|
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
|
version = "0.782"
|
||||||
|
description = "Optional static typing for Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "0.782"
|
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dmypy = ["psutil (>=4.0)"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mypy-extensions = ">=0.4.3,<0.5.0"
|
mypy-extensions = ">=0.4.3,<0.5.0"
|
||||||
typed-ast = ">=1.4.0,<1.5.0"
|
typed-ast = ">=1.4.0,<1.5.0"
|
||||||
typing-extensions = ">=3.7.4"
|
typing-extensions = ">=3.7.4"
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dmypy = ["psutil (>=4.0)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
|
||||||
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
|
|
||||||
name = "mypy-extensions"
|
name = "mypy-extensions"
|
||||||
|
version = "0.4.3"
|
||||||
|
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.4.3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Core utilities for Python packages"
|
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
|
version = "20.4"
|
||||||
|
description = "Core utilities for Python packages"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "20.4"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pyparsing = ">=2.0.2"
|
pyparsing = ">=2.0.2"
|
||||||
six = "*"
|
six = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Utility library for gitignore style pattern matching of file paths."
|
|
||||||
name = "pathspec"
|
name = "pathspec"
|
||||||
|
version = "0.8.0"
|
||||||
|
description = "Utility library for gitignore style pattern matching of file paths."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
version = "0.8.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python Build Reasonableness"
|
|
||||||
name = "pbr"
|
name = "pbr"
|
||||||
|
version = "5.5.0"
|
||||||
|
description = "Python Build Reasonableness"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.6"
|
python-versions = ">=2.6"
|
||||||
version = "5.5.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Check PEP-8 naming conventions, plugin for flake8"
|
|
||||||
name = "pep8-naming"
|
name = "pep8-naming"
|
||||||
|
version = "0.11.1"
|
||||||
|
description = "Check PEP-8 naming conventions, plugin for flake8"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.11.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
flake8-polyfill = ">=1.0.2,<2"
|
flake8-polyfill = ">=1.0.2,<2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "plugin and hook calling mechanisms for python"
|
|
||||||
name = "pluggy"
|
name = "pluggy"
|
||||||
|
version = "0.13.1"
|
||||||
|
description = "plugin and hook calling mechanisms for python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "0.13.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
[package.dependencies.importlib-metadata]
|
|
||||||
python = "<3.8"
|
|
||||||
version = ">=0.12"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["pre-commit", "tox"]
|
dev = ["pre-commit", "tox"]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
[package.dependencies.importlib-metadata]
|
||||||
|
version = ">=0.12"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
|
||||||
name = "py"
|
name = "py"
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python style guide checker"
|
|
||||||
name = "pycodestyle"
|
name = "pycodestyle"
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
description = "Python style guide checker"
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "passive checker of Python programs"
|
|
||||||
name = "pyflakes"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "2.2.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "pyflakes"
|
||||||
|
version = "2.2.0"
|
||||||
|
description = "passive checker of Python programs"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "python code static checker"
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "pylint"
|
name = "pylint"
|
||||||
|
version = "2.6.0"
|
||||||
|
description = "python code static checker"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5.*"
|
python-versions = ">=3.5.*"
|
||||||
version = "2.6.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
astroid = ">=2.4.0,<=2.5"
|
astroid = ">=2.4.0,<=2.5"
|
||||||
@@ -371,20 +372,24 @@ mccabe = ">=0.6,<0.7"
|
|||||||
toml = ">=0.7.1"
|
toml = ">=0.7.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python parsing module"
|
|
||||||
name = "pyparsing"
|
name = "pyparsing"
|
||||||
|
version = "2.4.7"
|
||||||
|
description = "Python parsing module"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
version = "2.4.7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "pytest: simple powerful testing with Python"
|
|
||||||
name = "pytest"
|
name = "pytest"
|
||||||
|
version = "6.0.2"
|
||||||
|
description = "pytest: simple powerful testing with Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "6.0.1"
|
|
||||||
|
[package.extras]
|
||||||
|
checkqa_mypy = ["mypy (0.780)"]
|
||||||
|
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
atomicwrites = ">=1.0"
|
atomicwrites = ">=1.0"
|
||||||
@@ -398,109 +403,105 @@ py = ">=1.8.2"
|
|||||||
toml = "*"
|
toml = "*"
|
||||||
|
|
||||||
[package.dependencies.importlib-metadata]
|
[package.dependencies.importlib-metadata]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=0.12"
|
version = ">=0.12"
|
||||||
|
python = "<3.8"
|
||||||
[package.extras]
|
|
||||||
checkqa_mypy = ["mypy (0.780)"]
|
|
||||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "A pytest plugin to enable format checking with black"
|
|
||||||
name = "pytest-black"
|
name = "pytest-black"
|
||||||
|
version = "0.3.11"
|
||||||
|
description = "A pytest plugin to enable format checking with black"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7"
|
python-versions = ">=2.7"
|
||||||
version = "0.3.11"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pytest = ">=3.5.0"
|
pytest = ">=3.5.0"
|
||||||
toml = "*"
|
toml = "*"
|
||||||
|
|
||||||
[package.dependencies.black]
|
[package.dependencies.black]
|
||||||
python = ">=3.6"
|
|
||||||
version = "*"
|
version = "*"
|
||||||
|
python = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Pytest plugin for measuring coverage."
|
|
||||||
name = "pytest-cov"
|
name = "pytest-cov"
|
||||||
|
version = "2.10.1"
|
||||||
|
description = "Pytest plugin for measuring coverage."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
version = "2.10.1"
|
|
||||||
|
[package.extras]
|
||||||
|
testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
coverage = ">=4.4"
|
coverage = ">=4.4"
|
||||||
pytest = ">=4.6"
|
pytest = ">=4.6"
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "pytest plugin to check FLAKE8 requirements"
|
|
||||||
name = "pytest-flake8"
|
name = "pytest-flake8"
|
||||||
|
version = "1.0.6"
|
||||||
|
description = "pytest plugin to check FLAKE8 requirements"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.0.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
flake8 = ">=3.5"
|
flake8 = ">=3.5"
|
||||||
pytest = ">=3.5"
|
pytest = ">=3.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "run tests in isolated forked subprocesses"
|
|
||||||
name = "pytest-forked"
|
name = "pytest-forked"
|
||||||
|
version = "1.3.0"
|
||||||
|
description = "run tests in isolated forked subprocesses"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
version = "1.3.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
py = "*"
|
py = "*"
|
||||||
pytest = ">=3.10"
|
pytest = ">=3.10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "py.test plugin to check import ordering using isort"
|
|
||||||
name = "pytest-isort"
|
name = "pytest-isort"
|
||||||
|
version = "1.2.0"
|
||||||
|
description = "py.test plugin to check import ordering using isort"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.2.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
isort = ">=4.0"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
tests = ["mock"]
|
tests = ["mock"]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
isort = ">=4.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Mypy static type checker plugin for Pytest"
|
|
||||||
name = "pytest-mypy"
|
name = "pytest-mypy"
|
||||||
|
version = "0.7.0"
|
||||||
|
description = "Mypy static type checker plugin for Pytest"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "0.7.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
filelock = ">=3.0"
|
filelock = ">=3.0"
|
||||||
pytest = ">=3.5"
|
pytest = ">=3.5"
|
||||||
|
|
||||||
[[package.dependencies.mypy]]
|
[[package.dependencies.mypy]]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=0.500"
|
version = ">=0.500"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package.dependencies.mypy]]
|
[[package.dependencies.mypy]]
|
||||||
python = ">=3.8"
|
|
||||||
version = ">=0.700"
|
version = ">=0.700"
|
||||||
|
python = ">=3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "pytest plugin to check source code with pylint"
|
|
||||||
name = "pytest-pylint"
|
name = "pytest-pylint"
|
||||||
|
version = "0.17.0"
|
||||||
|
description = "pytest plugin to check source code with pylint"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "0.17.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pylint = ">=2.3.0"
|
pylint = ">=2.3.0"
|
||||||
@@ -508,119 +509,118 @@ pytest = ">=5.4"
|
|||||||
toml = ">=0.7.1"
|
toml = ">=0.7.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "pytest xdist plugin for distributed testing and loop-on-failing modes"
|
|
||||||
name = "pytest-xdist"
|
name = "pytest-xdist"
|
||||||
|
version = "2.1.0"
|
||||||
|
description = "pytest xdist plugin for distributed testing and loop-on-failing modes"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "2.1.0"
|
|
||||||
|
[package.extras]
|
||||||
|
psutil = ["psutil (>=3.0)"]
|
||||||
|
testing = ["filelock"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
execnet = ">=1.1"
|
execnet = ">=1.1"
|
||||||
pytest = ">=6.0.0"
|
pytest = ">=6.0.0"
|
||||||
pytest-forked = "*"
|
pytest-forked = "*"
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
psutil = ["psutil (>=3.0)"]
|
|
||||||
testing = ["filelock"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "YAML parser and emitter for Python"
|
|
||||||
name = "pyyaml"
|
name = "pyyaml"
|
||||||
|
version = "5.3.1"
|
||||||
|
description = "YAML parser and emitter for Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
version = "5.3.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Alternative regular expression module, to replace re."
|
|
||||||
name = "regex"
|
name = "regex"
|
||||||
|
version = "2020.7.14"
|
||||||
|
description = "Alternative regular expression module, to replace re."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "2020.7.14"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
|
||||||
name = "six"
|
name = "six"
|
||||||
|
version = "1.15.0"
|
||||||
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
version = "1.15.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "A pure Python implementation of a sliding window memory map manager"
|
|
||||||
name = "smmap"
|
name = "smmap"
|
||||||
|
version = "3.0.4"
|
||||||
|
description = "A pure Python implementation of a sliding window memory map manager"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "3.0.4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Manage dynamic plugins for Python applications"
|
|
||||||
name = "stevedore"
|
name = "stevedore"
|
||||||
|
version = "3.2.2"
|
||||||
|
description = "Manage dynamic plugins for Python applications"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
version = "3.2.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
||||||
|
|
||||||
[package.dependencies.importlib-metadata]
|
[package.dependencies.importlib-metadata]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=1.7.0"
|
version = ">=1.7.0"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
|
||||||
name = "toml"
|
name = "toml"
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
|
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
|
||||||
name = "typed-ast"
|
name = "typed-ast"
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Backported and Experimental Type Hints for Python 3.5+"
|
|
||||||
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
|
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.7.4.3"
|
version = "3.7.4.3"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.5+"
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Module for decorators, wrappers and monkey patching."
|
|
||||||
name = "wrapt"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.12.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "wrapt"
|
||||||
|
version = "1.12.1"
|
||||||
|
description = "Module for decorators, wrappers and monkey patching."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
optional = false
|
||||||
marker = "python_version < \"3.8\""
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
|
version = "3.1.0"
|
||||||
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
version = "3.1.0"
|
marker = "python_version < \"3.8\""
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
||||||
testing = ["jaraco.itertools", "func-timeout"]
|
testing = ["jaraco.itertools", "func-timeout"]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "cae6ccf55d29594d147c60854e21a096ff99fb7ddd17eddad568138bfde22179"
|
|
||||||
lock-version = "1.0"
|
lock-version = "1.0"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
|
content-hash = "8dd6ef8098def46b656463f0ccb75b226e0aa719cb6fef709e1ef32bdf80e8a8"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
apipkg = [
|
apipkg = [
|
||||||
@@ -648,8 +648,7 @@ bandit = [
|
|||||||
{file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"},
|
{file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"},
|
||||||
]
|
]
|
||||||
black = [
|
black = [
|
||||||
{file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"},
|
{file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
|
||||||
{file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"},
|
|
||||||
]
|
]
|
||||||
click = [
|
click = [
|
||||||
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
|
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
|
||||||
@@ -660,40 +659,40 @@ colorama = [
|
|||||||
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
|
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
|
||||||
]
|
]
|
||||||
coverage = [
|
coverage = [
|
||||||
{file = "coverage-5.2.1-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:40f70f81be4d34f8d491e55936904db5c527b0711b2a46513641a5729783c2e4"},
|
{file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:675192fca634f0df69af3493a48224f211f8db4e84452b08d5fcebb9167adb01"},
|
{file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2fcc8b58953d74d199a1a4d633df8146f0ac36c4e720b4a1997e9b6327af43a8"},
|
{file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:64c4f340338c68c463f1b56e3f2f0423f7b17ba6c3febae80b81f0e093077f59"},
|
{file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27m-win32.whl", hash = "sha256:52f185ffd3291196dc1aae506b42e178a592b0b60a8610b108e6ad892cfc1bb3"},
|
{file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27m-win_amd64.whl", hash = "sha256:30bc103587e0d3df9e52cd9da1dd915265a22fad0b72afe54daf840c984b564f"},
|
{file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:9ea749fd447ce7fb1ac71f7616371f04054d969d412d37611716721931e36efd"},
|
{file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"},
|
||||||
{file = "coverage-5.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ce7866f29d3025b5b34c2e944e66ebef0d92e4a4f2463f7266daa03a1332a651"},
|
{file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"},
|
||||||
{file = "coverage-5.2.1-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:4869ab1c1ed33953bb2433ce7b894a28d724b7aa76c19b11e2878034a4e4680b"},
|
{file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"},
|
||||||
{file = "coverage-5.2.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a3ee9c793ffefe2944d3a2bd928a0e436cd0ac2d9e3723152d6fd5398838ce7d"},
|
{file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"},
|
||||||
{file = "coverage-5.2.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28f42dc5172ebdc32622a2c3f7ead1b836cdbf253569ae5673f499e35db0bac3"},
|
{file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"},
|
||||||
{file = "coverage-5.2.1-cp35-cp35m-win32.whl", hash = "sha256:e26c993bd4b220429d4ec8c1468eca445a4064a61c74ca08da7429af9bc53bb0"},
|
{file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"},
|
||||||
{file = "coverage-5.2.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4186fc95c9febeab5681bc3248553d5ec8c2999b8424d4fc3a39c9cba5796962"},
|
{file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"},
|
||||||
{file = "coverage-5.2.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:b360d8fd88d2bad01cb953d81fd2edd4be539df7bfec41e8753fe9f4456a5082"},
|
{file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"},
|
||||||
{file = "coverage-5.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:1adb6be0dcef0cf9434619d3b892772fdb48e793300f9d762e480e043bd8e716"},
|
{file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"},
|
||||||
{file = "coverage-5.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:098a703d913be6fbd146a8c50cc76513d726b022d170e5e98dc56d958fd592fb"},
|
{file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"},
|
||||||
{file = "coverage-5.2.1-cp36-cp36m-win32.whl", hash = "sha256:962c44070c281d86398aeb8f64e1bf37816a4dfc6f4c0f114756b14fc575621d"},
|
{file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"},
|
||||||
{file = "coverage-5.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1ed2bdb27b4c9fc87058a1cb751c4df8752002143ed393899edb82b131e0546"},
|
{file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"},
|
||||||
{file = "coverage-5.2.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:c890728a93fffd0407d7d37c1e6083ff3f9f211c83b4316fae3778417eab9811"},
|
{file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"},
|
||||||
{file = "coverage-5.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:538f2fd5eb64366f37c97fdb3077d665fa946d2b6d95447622292f38407f9258"},
|
{file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"},
|
||||||
{file = "coverage-5.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:27ca5a2bc04d68f0776f2cdcb8bbd508bbe430a7bf9c02315cd05fb1d86d0034"},
|
{file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"},
|
||||||
{file = "coverage-5.2.1-cp37-cp37m-win32.whl", hash = "sha256:aab75d99f3f2874733946a7648ce87a50019eb90baef931698f96b76b6769a46"},
|
{file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"},
|
||||||
{file = "coverage-5.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c2ff24df02a125b7b346c4c9078c8936da06964cc2d276292c357d64378158f8"},
|
{file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"},
|
||||||
{file = "coverage-5.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:304fbe451698373dc6653772c72c5d5e883a4aadaf20343592a7abb2e643dae0"},
|
{file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"},
|
||||||
{file = "coverage-5.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c96472b8ca5dc135fb0aa62f79b033f02aa434fb03a8b190600a5ae4102df1fd"},
|
{file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"},
|
||||||
{file = "coverage-5.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8505e614c983834239f865da2dd336dcf9d72776b951d5dfa5ac36b987726e1b"},
|
{file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"},
|
||||||
{file = "coverage-5.2.1-cp38-cp38-win32.whl", hash = "sha256:700997b77cfab016533b3e7dbc03b71d33ee4df1d79f2463a318ca0263fc29dd"},
|
{file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"},
|
||||||
{file = "coverage-5.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:46794c815e56f1431c66d81943fa90721bb858375fb36e5903697d5eef88627d"},
|
{file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"},
|
||||||
{file = "coverage-5.2.1-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:16042dc7f8e632e0dcd5206a5095ebd18cb1d005f4c89694f7f8aafd96dd43a3"},
|
{file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"},
|
||||||
{file = "coverage-5.2.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c1bbb628ed5192124889b51204de27c575b3ffc05a5a91307e7640eff1d48da4"},
|
{file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"},
|
||||||
{file = "coverage-5.2.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4f6428b55d2916a69f8d6453e48a505c07b2245653b0aa9f0dee38785939f5e4"},
|
{file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"},
|
||||||
{file = "coverage-5.2.1-cp39-cp39-win32.whl", hash = "sha256:9e536783a5acee79a9b308be97d3952b662748c4037b6a24cbb339dc7ed8eb89"},
|
{file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"},
|
||||||
{file = "coverage-5.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:b8f58c7db64d8f27078cbf2a4391af6aa4e4767cc08b37555c4ae064b8558d9b"},
|
{file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"},
|
||||||
{file = "coverage-5.2.1.tar.gz", hash = "sha256:a34cb28e0747ea15e82d13e14de606747e9e484fb28d63c999483f5d5188e89b"},
|
{file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"},
|
||||||
]
|
]
|
||||||
execnet = [
|
execnet = [
|
||||||
{file = "execnet-1.7.1-py2.py3-none-any.whl", hash = "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547"},
|
{file = "execnet-1.7.1-py2.py3-none-any.whl", hash = "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547"},
|
||||||
@@ -728,8 +727,8 @@ iniconfig = [
|
|||||||
{file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"},
|
{file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"},
|
||||||
]
|
]
|
||||||
isort = [
|
isort = [
|
||||||
{file = "isort-5.5.1-py3-none-any.whl", hash = "sha256:a200d47b7ee8b7f7d0a9646650160c4a51b6a91a9413fd31b1da2c4de789f5d3"},
|
{file = "isort-5.5.3-py3-none-any.whl", hash = "sha256:c16eaa7432a1c004c585d79b12ad080c6c421dd18fe27982ca11f95e6898e432"},
|
||||||
{file = "isort-5.5.1.tar.gz", hash = "sha256:92533892058de0306e51c88f22ece002a209dc8e80288aa3cec6d443060d584f"},
|
{file = "isort-5.5.3.tar.gz", hash = "sha256:6187a9f1ce8784cbc6d1b88790a43e6083a6302f03e9ae482acc0f232a98c843"},
|
||||||
]
|
]
|
||||||
lazy-object-proxy = [
|
lazy-object-proxy = [
|
||||||
{file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"},
|
{file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"},
|
||||||
@@ -823,8 +822,8 @@ pyparsing = [
|
|||||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||||
]
|
]
|
||||||
pytest = [
|
pytest = [
|
||||||
{file = "pytest-6.0.1-py3-none-any.whl", hash = "sha256:8b6007800c53fdacd5a5c192203f4e531eb2a1540ad9c752e052ec0f7143dbad"},
|
{file = "pytest-6.0.2-py3-none-any.whl", hash = "sha256:0e37f61339c4578776e090c3b8f6b16ce4db333889d65d0efb305243ec544b40"},
|
||||||
{file = "pytest-6.0.1.tar.gz", hash = "sha256:85228d75db9f45e06e57ef9bf4429267f81ac7c0d742cc9ed63d09886a9fe6f4"},
|
{file = "pytest-6.0.2.tar.gz", hash = "sha256:c8f57c2a30983f469bf03e68cdfa74dc474ce56b8f280ddcb080dfd91df01043"},
|
||||||
]
|
]
|
||||||
pytest-black = [
|
pytest-black = [
|
||||||
{file = "pytest-black-0.3.11.tar.gz", hash = "sha256:595eb0e7908b8a858a8564a5c8f0eae853c3926a4ec7b2afdfcedfa6fec65dd6"},
|
{file = "pytest-black-0.3.11.tar.gz", hash = "sha256:595eb0e7908b8a858a8564a5c8f0eae853c3926a4ec7b2afdfcedfa6fec65dd6"},
|
||||||
@@ -902,8 +901,8 @@ smmap = [
|
|||||||
{file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"},
|
{file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"},
|
||||||
]
|
]
|
||||||
stevedore = [
|
stevedore = [
|
||||||
{file = "stevedore-3.2.1-py3-none-any.whl", hash = "sha256:ddc09a744dc224c84ec8e8efcb70595042d21c97c76df60daee64c9ad53bc7ee"},
|
{file = "stevedore-3.2.2-py3-none-any.whl", hash = "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62"},
|
||||||
{file = "stevedore-3.2.1.tar.gz", hash = "sha256:a34086819e2c7a7f86d5635363632829dab8014e5fd7be2454c7cba84ac7514e"},
|
{file = "stevedore-3.2.2.tar.gz", hash = "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0"},
|
||||||
]
|
]
|
||||||
toml = [
|
toml = [
|
||||||
{file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"},
|
{file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"},
|
||||||
|
|||||||
@@ -6,21 +6,26 @@ build-backend = "poetry.masonry.api"
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pyrad3"
|
name = "pyrad3"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
readme = "README.md"
|
readme = "README.rst"
|
||||||
description = "RADIUS tools"
|
description = "RADIUS tools"
|
||||||
keywords = ["AAA", "authentication", "authorization", "accounting", "RADIUS"]
|
keywords = ["AAA", "authentication", "authorization", "accounting", "RADIUS"]
|
||||||
authors = ["Istvan Ruzman <istvan@ruzman.eu>"]
|
authors = ["Istvan Ruzman <istvan@ruzman.eu>"]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 4 - Beta",
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
|
"Intended Audience :: Information Technology",
|
||||||
|
"Intended Audience :: System Administrators",
|
||||||
"Intended Audience :: Telecommunications Industry",
|
"Intended Audience :: Telecommunications Industry",
|
||||||
"License :: OSI Approved :: Apache Software License",
|
"License :: OSI Approved :: Apache Software License",
|
||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Programming Language :: Python",
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Topic :: Software Development :: Libraries",
|
||||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||||
"Topic :: System :: Systems Administration :: Authentication/Directory"
|
"Topic :: System :: Networking",
|
||||||
|
"Topic :: System :: Systems Administration :: Authentication/Directory",
|
||||||
]
|
]
|
||||||
include = [
|
include = [
|
||||||
"LICENSE-APACHE",
|
"LICENSE-APACHE",
|
||||||
@@ -37,7 +42,7 @@ python = "^3.7"
|
|||||||
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
black = { version = "^19.3.10b0", allow-prereleases = true }
|
black = { version = "*", allow-prereleases = true }
|
||||||
bandit = "^1.6"
|
bandit = "^1.6"
|
||||||
pep8-naming = "^0.11"
|
pep8-naming = "^0.11"
|
||||||
pytest = "^6"
|
pytest = "^6"
|
||||||
@@ -51,14 +56,15 @@ pytest-xdist = "^2.1.0"
|
|||||||
|
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
line-length = 80
|
line-length = 90
|
||||||
include = '\.py'
|
include = '\.py'
|
||||||
|
target-version = ["py37"]
|
||||||
|
|
||||||
|
|
||||||
[tool.isort]
|
[tool.isort]
|
||||||
combine_as_imports = true
|
combine_as_imports = true
|
||||||
include_trailing_comma = true
|
include_trailing_comma = true
|
||||||
line_length = 80
|
line_length = 90
|
||||||
multi_line_output = 3
|
multi_line_output = 3
|
||||||
use_parentheses = true
|
use_parentheses = true
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ in pkgs.mkShell {
|
|||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
git
|
git
|
||||||
nixfmt
|
nixfmt
|
||||||
|
freeradius
|
||||||
gnumake
|
gnumake
|
||||||
python3
|
python3
|
||||||
python37
|
python37
|
||||||
@@ -17,6 +18,7 @@ in pkgs.mkShell {
|
|||||||
python3Packages.coveralls
|
python3Packages.coveralls
|
||||||
python3Packages.pep8-naming
|
python3Packages.pep8-naming
|
||||||
python3Packages.poetry
|
python3Packages.poetry
|
||||||
|
python3Packages.pygments
|
||||||
python3Packages.pytest
|
python3Packages.pytest
|
||||||
python3Packages.pytest-black
|
python3Packages.pytest-black
|
||||||
python3Packages.pytestcov
|
python3Packages.pytestcov
|
||||||
|
|||||||
@@ -74,9 +74,7 @@ class Client(H.Host):
|
|||||||
# have any implementation yet for non-Linux systems.
|
# have any implementation yet for non-Linux systems.
|
||||||
# Better to fail loudly than to do something unexpected silently.
|
# Better to fail loudly than to do something unexpected silently.
|
||||||
self._socket.setsockopt(
|
self._socket.setsockopt(
|
||||||
socket.SOL_SOCKET,
|
socket.SOL_SOCKET, socket.SO_BINDTODEVICE, self.interface.encode("utf-8"),
|
||||||
socket.SO_BINDTODEVICE,
|
|
||||||
self.interface.encode("utf-8"),
|
|
||||||
)
|
)
|
||||||
self._poll = select.poll()
|
self._poll = select.poll()
|
||||||
self._poll.register(self._socket, select.POLLIN)
|
self._poll.register(self._socket, select.POLLIN)
|
||||||
|
|||||||
@@ -28,11 +28,7 @@ class ParseError(Exception):
|
|||||||
"""RADIUS Dictionary Parser Error"""
|
"""RADIUS Dictionary Parser Error"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self, filename: str, msg: str = None, line: Optional[int] = None, **data,
|
||||||
filename: str,
|
|
||||||
msg: str = None,
|
|
||||||
line: Optional[int] = None,
|
|
||||||
**data,
|
|
||||||
):
|
):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
@@ -115,9 +111,7 @@ class Dictionary:
|
|||||||
loader = dict_loader(dictionary)
|
loader = dict_loader(dictionary)
|
||||||
self.read_dictionary(loader)
|
self.read_dictionary(loader)
|
||||||
|
|
||||||
def read_dictionary(
|
def read_dictionary(self, reader: Generator[Tuple[int, List[str]], None, None]):
|
||||||
self, reader: Generator[Tuple[int, List[str]], None, None]
|
|
||||||
):
|
|
||||||
"""Read and parse a (Free)RADIUS dictionary."""
|
"""Read and parse a (Free)RADIUS dictionary."""
|
||||||
self.filestack: List[str] = []
|
self.filestack: List[str] = []
|
||||||
for line_num, tokens in reader:
|
for line_num, tokens in reader:
|
||||||
@@ -131,9 +125,7 @@ class Dictionary:
|
|||||||
elif key == "FILE_OPENED":
|
elif key == "FILE_OPENED":
|
||||||
LOG.info("Parsing file: %s", tokens[1])
|
LOG.info("Parsing file: %s", tokens[1])
|
||||||
if tokens[1] in self.filestack:
|
if tokens[1] in self.filestack:
|
||||||
raise ParseError(
|
raise ParseError(self.filestack[-1], "Include recursion detected")
|
||||||
self.filestack[-1], "Include recursion detected"
|
|
||||||
)
|
|
||||||
self.filestack.append(tokens[1])
|
self.filestack.append(tokens[1])
|
||||||
elif key == "FILE_CLOSED":
|
elif key == "FILE_CLOSED":
|
||||||
filename = self.filestack.pop()
|
filename = self.filestack.pop()
|
||||||
@@ -156,17 +148,13 @@ class Dictionary:
|
|||||||
"END-TLV is deprecated and not supported by pyrad3"
|
"END-TLV is deprecated and not supported by pyrad3"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ParseError(
|
raise ParseError(self.filestack[-1], f"Invalid Token key {key}", line_num)
|
||||||
self.filestack[-1], f"Invalid Token key {key}", line_num
|
|
||||||
)
|
|
||||||
|
|
||||||
def _parse_vendor(self, tokens: Sequence[str], line_num: int):
|
def _parse_vendor(self, tokens: Sequence[str], line_num: int):
|
||||||
"""Parse the vendor definition"""
|
"""Parse the vendor definition"""
|
||||||
filename = self.filestack[-1]
|
filename = self.filestack[-1]
|
||||||
if len(tokens) not in [3, 4]:
|
if len(tokens) not in [3, 4]:
|
||||||
raise ParseError(
|
raise ParseError(filename, "Incorrect number of tokens for vendor statement")
|
||||||
filename, "Incorrect number of tokens for vendor statement"
|
|
||||||
)
|
|
||||||
vendor_name = tokens[1]
|
vendor_name = tokens[1]
|
||||||
vendor_id = int(tokens[2], 0)
|
vendor_id = int(tokens[2], 0)
|
||||||
continuation = False
|
continuation = False
|
||||||
@@ -227,9 +215,7 @@ class Dictionary:
|
|||||||
filename = self.filestack[-1]
|
filename = self.filestack[-1]
|
||||||
if self.cur_vendor != self.rfc_vendor:
|
if self.cur_vendor != self.rfc_vendor:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, "vendor-begin sections are not allowed to be nested", line_num,
|
||||||
"vendor-begin sections are not allowed to be nested",
|
|
||||||
line_num,
|
|
||||||
)
|
)
|
||||||
if len(tokens) != 2:
|
if len(tokens) != 2:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
@@ -252,9 +238,7 @@ class Dictionary:
|
|||||||
filename = self.filestack[-1]
|
filename = self.filestack[-1]
|
||||||
if len(tokens) != 2:
|
if len(tokens) != 2:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, "Incorrect number of tokens for end-vendor statement", line_num,
|
||||||
"Incorrect number of tokens for end-vendor statement",
|
|
||||||
line_num,
|
|
||||||
)
|
)
|
||||||
if self.cur_vendor.name != tokens[1]:
|
if self.cur_vendor.name != tokens[1]:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
@@ -284,9 +268,7 @@ class Dictionary:
|
|||||||
elif flag_len == 2:
|
elif flag_len == 2:
|
||||||
value = flag[1]
|
value = flag[1]
|
||||||
else:
|
else:
|
||||||
raise ParseError(
|
raise ParseError(filename, f"Incorrect attribute flag {flag}", line_num)
|
||||||
filename, f"Incorrect attribute flag {flag}", line_num
|
|
||||||
)
|
|
||||||
key = flag[0]
|
key = flag[0]
|
||||||
|
|
||||||
if key == "has_tag":
|
if key == "has_tag":
|
||||||
@@ -298,14 +280,10 @@ class Dictionary:
|
|||||||
encrypt = Encrypt(int(value)) # type: ignore
|
encrypt = Encrypt(int(value)) # type: ignore
|
||||||
except (ValueError, TypeError) as exc:
|
except (ValueError, TypeError) as exc:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, f"Illegal attribute encryption {value}", line_num,
|
||||||
f"Illegal attribute encryption {value}",
|
|
||||||
line_num,
|
|
||||||
) from exc
|
) from exc
|
||||||
else:
|
else:
|
||||||
raise ParseError(
|
raise ParseError(filename, "Unknown attribute flag {key}", line_num)
|
||||||
filename, "Unknown attribute flag {key}", line_num
|
|
||||||
)
|
|
||||||
|
|
||||||
return has_tag, encrypt
|
return has_tag, encrypt
|
||||||
|
|
||||||
@@ -328,9 +306,7 @@ class Dictionary:
|
|||||||
)
|
)
|
||||||
if code_num < 0:
|
if code_num < 0:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, "negative attribute codes are not allowed", line_num,
|
||||||
"negative attribute codes are not allowed",
|
|
||||||
line_num,
|
|
||||||
)
|
)
|
||||||
codes.append(code_num)
|
codes.append(code_num)
|
||||||
return codes
|
return codes
|
||||||
@@ -340,9 +316,7 @@ class Dictionary:
|
|||||||
filename = self.filestack[-1]
|
filename = self.filestack[-1]
|
||||||
if not len(tokens) in [4, 5]:
|
if not len(tokens) in [4, 5]:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, "Incorrect number of tokens for attribute definition", line_num,
|
||||||
"Incorrect number of tokens for attribute definition",
|
|
||||||
line_num,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
has_tag, encrypt = self._parse_attribute_flags(tokens, line_num)
|
has_tag, encrypt = self._parse_attribute_flags(tokens, line_num)
|
||||||
@@ -370,23 +344,15 @@ class Dictionary:
|
|||||||
try:
|
try:
|
||||||
attribute_type = Datatype[base_datatype]
|
attribute_type = Datatype[base_datatype]
|
||||||
except KeyError as exc:
|
except KeyError as exc:
|
||||||
raise ParseError(
|
raise ParseError(filename, f"Illegal type: {datatype}", line_num) from exc
|
||||||
filename, f"Illegal type: {datatype}", line_num
|
|
||||||
) from exc
|
|
||||||
|
|
||||||
attribute = Attribute(
|
attribute = Attribute(
|
||||||
name,
|
name, codes[-1], attribute_type, {}, has_tag, encrypt, len(codes) > 1,
|
||||||
codes[-1],
|
|
||||||
attribute_type,
|
|
||||||
{},
|
|
||||||
has_tag,
|
|
||||||
encrypt,
|
|
||||||
len(codes) > 1,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
attrcode: Union[int, Tuple[int, ...]] = codes[0] if len(
|
attrcode: Union[int, Tuple[int, ...]] = codes[0] if len(codes) == 1 else tuple(
|
||||||
codes
|
codes
|
||||||
) == 1 else tuple(codes)
|
)
|
||||||
self.cur_vendor.attrs[attrcode] = attribute
|
self.cur_vendor.attrs[attrcode] = attribute
|
||||||
|
|
||||||
if self.cur_vendor != self.rfc_vendor:
|
if self.cur_vendor != self.rfc_vendor:
|
||||||
@@ -398,9 +364,9 @@ class Dictionary:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
LOG.info("Register Attribute %s", attribute.name)
|
LOG.info("Register Attribute %s", attribute.name)
|
||||||
attrcode: Union[int, Tuple[int, ...]] = codes[0] if len(
|
attrcode: Union[int, Tuple[int, ...]] = codes[0] if len(codes) == 1 else tuple(
|
||||||
codes
|
codes
|
||||||
) == 1 else tuple(codes)
|
)
|
||||||
self.attrindex[attrcode] = attribute
|
self.attrindex[attrcode] = attribute
|
||||||
self.attrindex[name] = attribute
|
self.attrindex[name] = attribute
|
||||||
|
|
||||||
@@ -409,9 +375,7 @@ class Dictionary:
|
|||||||
filename = self.filestack[-1]
|
filename = self.filestack[-1]
|
||||||
if len(tokens) != 4:
|
if len(tokens) != 4:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, "Incorrect number of tokens for VALUE definition", line_num,
|
||||||
"Incorrect number of tokens for VALUE definition",
|
|
||||||
line_num,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(attr_name, key, vvalue) = tokens[1:]
|
(attr_name, key, vvalue) = tokens[1:]
|
||||||
@@ -429,9 +393,7 @@ class Dictionary:
|
|||||||
attribute = self.attrindex[attr_name]
|
attribute = self.attrindex[attr_name]
|
||||||
except KeyError as exc:
|
except KeyError as exc:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
filename,
|
filename, f"ATTRIBUTE {attr_name} has not been defined yet", line_num,
|
||||||
f"ATTRIBUTE {attr_name} has not been defined yet",
|
|
||||||
line_num,
|
|
||||||
) from exc
|
) from exc
|
||||||
try:
|
try:
|
||||||
datatype = str(attribute.datatype).split(".")[1]
|
datatype = str(attribute.datatype).split(".")[1]
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class Packet(OrderedDict):
|
|||||||
radius_id: int,
|
radius_id: int,
|
||||||
*,
|
*,
|
||||||
request: "Packet" = None,
|
request: "Packet" = None,
|
||||||
**attributes
|
**attributes,
|
||||||
):
|
):
|
||||||
super().__init__(**attributes)
|
super().__init__(**attributes)
|
||||||
self.code = code
|
self.code = code
|
||||||
@@ -79,9 +79,7 @@ class Packet(OrderedDict):
|
|||||||
raise PacketError("Packet has a wrong message authenticator")
|
raise PacketError("Packet has a wrong message authenticator")
|
||||||
except KeyError as exc:
|
except KeyError as exc:
|
||||||
if "EAP-Message" in reply:
|
if "EAP-Message" in reply:
|
||||||
raise PacketError(
|
raise PacketError("Packet is missing a message authenticator") from exc
|
||||||
"Packet is missing a message authenticator"
|
|
||||||
) from exc
|
|
||||||
return reply
|
return reply
|
||||||
|
|
||||||
def send(self):
|
def send(self):
|
||||||
@@ -134,11 +132,7 @@ class Packet(OrderedDict):
|
|||||||
|
|
||||||
if self.code in (Code.AccessRequest, Code.StatusServer):
|
if self.code in (Code.AccessRequest, Code.StatusServer):
|
||||||
hmac_builder.update(self.authenticator)
|
hmac_builder.update(self.authenticator)
|
||||||
elif self.code in (
|
elif self.code in (Code.AccessAccept, Code.AccessChallenge, Code.AccessReject,):
|
||||||
Code.AccessAccept,
|
|
||||||
Code.AccessChallenge,
|
|
||||||
Code.AccessReject,
|
|
||||||
):
|
|
||||||
hmac_builder.update(self.request.authenticator)
|
hmac_builder.update(self.request.authenticator)
|
||||||
else:
|
else:
|
||||||
hmac_builder.update(16 * b"\00")
|
hmac_builder.update(16 * b"\00")
|
||||||
@@ -202,7 +196,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
|
|||||||
*,
|
*,
|
||||||
code: Code = Code.AccessRequest,
|
code: Code = Code.AccessRequest,
|
||||||
request: Optional[Packet] = None,
|
request: Optional[Packet] = None,
|
||||||
**attributes
|
**attributes,
|
||||||
):
|
):
|
||||||
super().__init__(host, code, radius_id, request=request, **attributes)
|
super().__init__(host, code, radius_id, request=request, **attributes)
|
||||||
self.auth_type = auth_type
|
self.auth_type = auth_type
|
||||||
@@ -217,7 +211,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
|
|||||||
self.auth_type,
|
self.auth_type,
|
||||||
request=self,
|
request=self,
|
||||||
code=Code.AccessAccept,
|
code=Code.AccessAccept,
|
||||||
**attributes
|
**attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_reject(self, **attributes):
|
def create_reject(self, **attributes):
|
||||||
@@ -228,7 +222,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
|
|||||||
self.auth_type,
|
self.auth_type,
|
||||||
request=self,
|
request=self,
|
||||||
code=Code.AccessReject,
|
code=Code.AccessReject,
|
||||||
**attributes
|
**attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_challange(self, **attributes):
|
def create_challange(self, **attributes):
|
||||||
@@ -239,7 +233,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
|
|||||||
self.auth_type,
|
self.auth_type,
|
||||||
request=self,
|
request=self,
|
||||||
code=Code.AccessChallenge,
|
code=Code.AccessChallenge,
|
||||||
**attributes
|
**attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate_password(self, password: bytes) -> bool:
|
def validate_password(self, password: bytes) -> bool:
|
||||||
@@ -285,7 +279,7 @@ class AcctPacket(Packet): # pylint: disable=abstract-method
|
|||||||
*,
|
*,
|
||||||
code: Code = Code.AccountingRequest,
|
code: Code = Code.AccountingRequest,
|
||||||
request: Optional[Packet] = None,
|
request: Optional[Packet] = None,
|
||||||
**attributes
|
**attributes,
|
||||||
):
|
):
|
||||||
super().__init__(host, code, radius_id, request=request, **attributes)
|
super().__init__(host, code, radius_id, request=request, **attributes)
|
||||||
|
|
||||||
@@ -296,7 +290,7 @@ class AcctPacket(Packet): # pylint: disable=abstract-method
|
|||||||
self.identifier,
|
self.identifier,
|
||||||
code=Code.AccountingResponse,
|
code=Code.AccountingResponse,
|
||||||
request=self,
|
request=self,
|
||||||
**attributes
|
**attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
def increase_acct_delay_time(self, delay_time: float):
|
def increase_acct_delay_time(self, delay_time: float):
|
||||||
@@ -322,26 +316,18 @@ class CoAPacket(Packet): # pylint: disable=abstract-method
|
|||||||
*,
|
*,
|
||||||
code: Code = Code.CoARequest,
|
code: Code = Code.CoARequest,
|
||||||
request: Optional[Packet] = None,
|
request: Optional[Packet] = None,
|
||||||
**attributes
|
**attributes,
|
||||||
):
|
):
|
||||||
super().__init__(host, code, radius_id, request=request, **attributes)
|
super().__init__(host, code, radius_id, request=request, **attributes)
|
||||||
|
|
||||||
def create_ack(self, **attributes):
|
def create_ack(self, **attributes):
|
||||||
"""Create a RADIUS Packet of type CoA-Ack"""
|
"""Create a RADIUS Packet of type CoA-Ack"""
|
||||||
return CoAPacket(
|
return CoAPacket(
|
||||||
self.host,
|
self.host, self.identifier, code=Code.CoAACK, request=self, **attributes
|
||||||
self.identifier,
|
|
||||||
code=Code.CoAACK,
|
|
||||||
request=self,
|
|
||||||
**attributes
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_nack(self, **attributes):
|
def create_nack(self, **attributes):
|
||||||
"""Create a RADIUS Packet of type CoA-Nack"""
|
"""Create a RADIUS Packet of type CoA-Nack"""
|
||||||
return CoAPacket(
|
return CoAPacket(
|
||||||
self.host,
|
self.host, self.identifier, code=Code.CoANAK, request=self, **attributes
|
||||||
self.identifier,
|
|
||||||
code=Code.CoANAK,
|
|
||||||
request=self,
|
|
||||||
**attributes
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ def encode_ipv4_address(addr: Union[str, IPv4Address]) -> bytes:
|
|||||||
def encode_ipv4_prefix(network: Union[str, IPv4Network]) -> bytes:
|
def encode_ipv4_prefix(network: Union[str, IPv4Network]) -> bytes:
|
||||||
"""Encode a RADIUS value of type ipv4prefix"""
|
"""Encode a RADIUS value of type ipv4prefix"""
|
||||||
address = IPv4Network(network)
|
address = IPv4Network(network)
|
||||||
return (
|
return struct.pack("2B", 0, address.prefixlen) + address.network_address.packed
|
||||||
struct.pack("2B", 0, address.prefixlen) + address.network_address.packed
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def encode_ipv6_address(addr: Union[str, IPv6Address]) -> bytes:
|
def encode_ipv6_address(addr: Union[str, IPv6Address]) -> bytes:
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ class PacketError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
Header = namedtuple("Header", ["code", "radius_id", "length", "authenticator"])
|
Header = namedtuple("Header", ["code", "radius_id", "length", "authenticator"])
|
||||||
Attribute = namedtuple(
|
Attribute = namedtuple("Attribute", ["name", "pos", "type", "length", "tag", "value"])
|
||||||
"Attribute", ["name", "pos", "type", "length", "tag", "value"]
|
|
||||||
)
|
|
||||||
|
|
||||||
PreParsedAttributes = List[Tuple[Tuple[int, ...], bytes, int]]
|
PreParsedAttributes = List[Tuple[Tuple[int, ...], bytes, int]]
|
||||||
SpecialTlvDescription = Tuple[Tuple[int, ...], bytes, int]
|
SpecialTlvDescription = Tuple[Tuple[int, ...], bytes, int]
|
||||||
@@ -52,9 +50,7 @@ def decode_header(raw_packet: bytes) -> Header:
|
|||||||
return Header(*header)
|
return Header(*header)
|
||||||
|
|
||||||
|
|
||||||
def decode_attributes(
|
def decode_attributes(rad_dict: Dictionary, raw_packet: bytes) -> List[Attribute]:
|
||||||
rad_dict: Dictionary, raw_packet: bytes
|
|
||||||
) -> List[Attribute]:
|
|
||||||
"""Decode the Attributes in a RADIUS Packet.
|
"""Decode the Attributes in a RADIUS Packet.
|
||||||
|
|
||||||
This function skips the Header. The Header must be decoded and verified
|
This function skips the Header. The Header must be decoded and verified
|
||||||
@@ -139,9 +135,7 @@ def pre_decode_attributes( # pylint: disable=too-many-branches
|
|||||||
adef = rad_dict.attrindex.get(key)
|
adef = rad_dict.attrindex.get(key)
|
||||||
if adef is not None and adef.datatype == Datatype.tlv:
|
if adef is not None and adef.datatype == Datatype.tlv:
|
||||||
# TODO: deal with tagged tlvs
|
# TODO: deal with tagged tlvs
|
||||||
attributes.extend(
|
attributes.extend(decode_tlv(rad_dict, list(key), value, offset))
|
||||||
decode_tlv(rad_dict, list(key), value, offset)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
attributes.append((key, value, offset))
|
attributes.append((key, value, offset))
|
||||||
offset += length
|
offset += length
|
||||||
@@ -273,9 +267,7 @@ def calculate_authenticator(
|
|||||||
secret: bytes, authenticator: bytes, raw_packet: bytes
|
secret: bytes, authenticator: bytes, raw_packet: bytes
|
||||||
) -> bytes:
|
) -> bytes:
|
||||||
"""Calculate the Authenticator for the RADIUS Packet"""
|
"""Calculate the Authenticator for the RADIUS Packet"""
|
||||||
return MD5(
|
return MD5(raw_packet[0:4] + authenticator + raw_packet[20:] + secret).digest()
|
||||||
raw_packet[0:4] + authenticator + raw_packet[20:] + secret
|
|
||||||
).digest()
|
|
||||||
|
|
||||||
|
|
||||||
def validate_pap_password(
|
def validate_pap_password(
|
||||||
@@ -291,9 +283,7 @@ def validate_pap_password(
|
|||||||
return obfuscated_password == obf_pass
|
return obfuscated_password == obf_pass
|
||||||
|
|
||||||
|
|
||||||
def password_encode(
|
def password_encode(secret: bytes, authenticator: bytes, password: bytes) -> bytes:
|
||||||
secret: bytes, authenticator: bytes, password: bytes
|
|
||||||
) -> bytes:
|
|
||||||
"""Obfuscate the plaintext Password for RADIUS"""
|
"""Obfuscate the plaintext Password for RADIUS"""
|
||||||
buf = password + b"\x00" * (16 - (len(password) % 16))
|
buf = password + b"\x00" * (16 - (len(password) % 16))
|
||||||
last = authenticator
|
last = authenticator
|
||||||
@@ -348,22 +338,14 @@ def create_chap_password(
|
|||||||
|
|
||||||
|
|
||||||
def validate_chap_password(
|
def validate_chap_password(
|
||||||
chap_id: bytes,
|
chap_id: bytes, challenge: bytes, chap_password: bytes, plaintext_password: bytes,
|
||||||
challenge: bytes,
|
|
||||||
chap_password: bytes,
|
|
||||||
plaintext_password: bytes,
|
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Validate the CHAP password against the given plaintext password"""
|
"""Validate the CHAP password against the given plaintext password"""
|
||||||
return chap_password == create_chap_password(
|
return chap_password == create_chap_password(chap_id, challenge, plaintext_password)
|
||||||
chap_id, challenge, plaintext_password
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def salt_encrypt(
|
def salt_encrypt(
|
||||||
secret: bytes,
|
secret: bytes, authenticator: bytes, value: bytes, salt: Optional[int] = None,
|
||||||
authenticator: bytes,
|
|
||||||
value: bytes,
|
|
||||||
salt: Optional[int] = None,
|
|
||||||
) -> bytes:
|
) -> bytes:
|
||||||
"""Salt Encrypt the given value"""
|
"""Salt Encrypt the given value"""
|
||||||
if salt is None:
|
if salt is None:
|
||||||
|
|||||||
@@ -63,9 +63,7 @@ def test_valid_vendor_definitions(vendor):
|
|||||||
|
|
||||||
def test_closing_wrong_vendor():
|
def test_closing_wrong_vendor():
|
||||||
dictionary = StringIO(
|
dictionary = StringIO(
|
||||||
"VENDOR TEST-VENDOR 1234\n"
|
"VENDOR TEST-VENDOR 1234\n" "BEGIN-VENDOR TEST-VENDOR\n" "END-VENDOR WRONG-VENDOR"
|
||||||
"BEGIN-VENDOR TEST-VENDOR\n"
|
|
||||||
"END-VENDOR WRONG-VENDOR"
|
|
||||||
)
|
)
|
||||||
with pytest.raises(ParseError):
|
with pytest.raises(ParseError):
|
||||||
Dictionary("", dictionary)
|
Dictionary("", dictionary)
|
||||||
@@ -121,8 +119,7 @@ def test_valid_attribute_numbers(number):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"invalid_number",
|
"invalid_number", ["1000", "ABCD", "-1", "inf", "INF", "-INF", "2e4", "2.5e3"],
|
||||||
["1000", "ABCD", "-1", "inf", "INF", "-INF", "2e4", "2.5e3"],
|
|
||||||
)
|
)
|
||||||
def test_invalid_attribute_numbers(invalid_number):
|
def test_invalid_attribute_numbers(invalid_number):
|
||||||
dictionary = StringIO(f"ATTRIBUTE NAME {invalid_number} integer64")
|
dictionary = StringIO(f"ATTRIBUTE NAME {invalid_number} integer64")
|
||||||
@@ -160,8 +157,7 @@ def test_invalid_attr_type():
|
|||||||
@pytest.mark.parametrize("value", ["1", "0x1", "0o1"])
|
@pytest.mark.parametrize("value", ["1", "0x1", "0o1"])
|
||||||
def test_value_definition(value):
|
def test_value_definition(value):
|
||||||
dictionary = StringIO(
|
dictionary = StringIO(
|
||||||
"ATTRIBUTE TEST-ATTRIBUTE 1 byte\n"
|
"ATTRIBUTE TEST-ATTRIBUTE 1 byte\n" f"VALUE TEST-ATTRIBUTE TEST-VALUE {value}"
|
||||||
f"VALUE TEST-ATTRIBUTE TEST-VALUE {value}"
|
|
||||||
)
|
)
|
||||||
Dictionary("", dictionary)
|
Dictionary("", dictionary)
|
||||||
|
|
||||||
@@ -290,9 +286,7 @@ def test_valid_datatypes_in_vendor_space(datatype):
|
|||||||
Dictionary("", dictionary)
|
Dictionary("", dictionary)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize("datatype", ["concat", "extended", "long-extended", "evs"])
|
||||||
"datatype", ["concat", "extended", "long-extended", "evs"]
|
|
||||||
)
|
|
||||||
def test_invalid_datatypes_in_vendor_space(datatype):
|
def test_invalid_datatypes_in_vendor_space(datatype):
|
||||||
dictionary = StringIO(
|
dictionary = StringIO(
|
||||||
"VENDOR TEST 1234\n"
|
"VENDOR TEST 1234\n"
|
||||||
@@ -305,8 +299,7 @@ def test_invalid_datatypes_in_vendor_space(datatype):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"invalid_number",
|
"invalid_number", ["ABCD", "-1", "inf", "INF", "-INF", "0.1", "2e4", "2.5e3"],
|
||||||
["ABCD", "-1", "inf", "INF", "-INF", "0.1", "2e4", "2.5e3"],
|
|
||||||
)
|
)
|
||||||
def test_invalid_value_numbers(invalid_number):
|
def test_invalid_value_numbers(invalid_number):
|
||||||
dictionary = StringIO(
|
dictionary = StringIO(
|
||||||
@@ -340,9 +333,7 @@ def test_value_for_non_existing_attribute():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_value_for_wrong_datatype(datatype):
|
def test_value_for_wrong_datatype(datatype):
|
||||||
dictionary = StringIO(
|
dictionary = StringIO(f"ATTRIBUTE NAME 123 {datatype}\n" "VALUE NAME VNAME 256")
|
||||||
f"ATTRIBUTE NAME 123 {datatype}\n" "VALUE NAME VNAME 256"
|
|
||||||
)
|
|
||||||
with pytest.raises(ParseError):
|
with pytest.raises(ParseError):
|
||||||
Dictionary("", dictionary)
|
Dictionary("", dictionary)
|
||||||
|
|
||||||
@@ -398,9 +389,7 @@ def test_get_attributes_from_dictionaries(attribute):
|
|||||||
_ = dd[attribute]
|
_ = dd[attribute]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize("attribute", ["RFC-ATTRIBUTE1", 8, (26, 5556, 7), (26, 5555, 8)])
|
||||||
"attribute", ["RFC-ATTRIBUTE1", 8, (26, 5556, 7), (26, 5555, 8)]
|
|
||||||
)
|
|
||||||
def test_get_nonexisting_attributes_from_dictionaries(attribute):
|
def test_get_nonexisting_attributes_from_dictionaries(attribute):
|
||||||
dictionary = StringIO(
|
dictionary = StringIO(
|
||||||
"ATTRIBUTE RFC-ATTRIBUTE 7 integer\n"
|
"ATTRIBUTE RFC-ATTRIBUTE 7 integer\n"
|
||||||
|
|||||||
@@ -148,9 +148,7 @@ def flattened_product(l1, l2):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
VENDOR_TEST_ATTRIBUTES = flattened_product(
|
VENDOR_TEST_ATTRIBUTES = flattened_product(VENDOR_FORMAT_COMBINATIONS, TEST_ATTRIBUTES)
|
||||||
VENDOR_FORMAT_COMBINATIONS, TEST_ATTRIBUTES
|
|
||||||
)
|
|
||||||
VENDOR_TAGGED_ATTRIBUTES = flattened_product(
|
VENDOR_TAGGED_ATTRIBUTES = flattened_product(
|
||||||
VENDOR_FORMAT_COMBINATIONS, TAGGED_ATTRIBUTES
|
VENDOR_FORMAT_COMBINATIONS, TAGGED_ATTRIBUTES
|
||||||
)
|
)
|
||||||
@@ -206,13 +204,7 @@ def generate_vendor_attribute(vendor_id, tlen, llen, attr_bytes):
|
|||||||
|
|
||||||
attr_bytes = attr_bytes[2:]
|
attr_bytes = attr_bytes[2:]
|
||||||
packet = (
|
packet = (
|
||||||
bytes(20)
|
bytes(20) + b"\x1a" + vsa_length + vendor_id + attr_type + attr_len + attr_bytes
|
||||||
+ b"\x1a"
|
|
||||||
+ vsa_length
|
|
||||||
+ vendor_id
|
|
||||||
+ attr_type
|
|
||||||
+ attr_len
|
|
||||||
+ attr_bytes
|
|
||||||
)
|
)
|
||||||
return packet
|
return packet
|
||||||
|
|
||||||
@@ -268,9 +260,7 @@ def test_password(plaintext, obfuscated, authenticator):
|
|||||||
assert len(decoded) == len(plaintext)
|
assert len(decoded) == len(plaintext)
|
||||||
assert decoded == plaintext
|
assert decoded == plaintext
|
||||||
|
|
||||||
assert utils.validate_pap_password(
|
assert utils.validate_pap_password(SECRET, authenticator, encoded, plaintext)
|
||||||
SECRET, authenticator, encoded, plaintext
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|||||||
Reference in New Issue
Block a user