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