Skip to content

Commit 7900c08

Browse files
committed
bootstrap
1 parent 0f43e5e commit 7900c08

File tree

13 files changed

+653
-0
lines changed

13 files changed

+653
-0
lines changed

.github/workflows/flake8.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: flake8
2+
3+
on:
4+
[ push, pull_request ]
5+
6+
jobs:
7+
flake8_py3:
8+
runs-on: ubuntu-22.04
9+
steps:
10+
- uses: actions/checkout@master
11+
- uses: actions/setup-python@v5
12+
name: setup Python
13+
with:
14+
python-version: '3.10'
15+
- name: Checkout pygeoapi-auth
16+
uses: actions/checkout@master
17+
- name: Install flake8
18+
run: pip3 install flake8
19+
- name: Run flake8
20+
uses: suo/flake8-github-action@releases/v1
21+
with:
22+
checkName: 'flake8_py3'
23+
env:
24+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
recursive-include pygeoapi_auth
2+
include README.md
3+
include requirements.txt

README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# pygeoapi-auth
2+
3+
Python module to manage pygeoapi authorization
4+
5+
## Installation
6+
7+
pygeoapi-auth is best installed and used within a Python virtualenv.
8+
9+
### Requirements
10+
11+
* Python 3 and above
12+
* Python [virtualenv](https://virtualenv.pypa.io) package
13+
14+
### Dependencies
15+
16+
Dependencies are listed in [requirements.txt](requirements.txt). Dependencies
17+
are automatically installed during pygeoapi-auth's installation.
18+
19+
### Installing the Package
20+
21+
```bash
22+
python3 -m venv my-env
23+
cd my-env
24+
. bin/activate
25+
git clone https://github.com/cartologic/pygeoapi-auth.git
26+
cd pygeoapi-auth
27+
python3 setup.py install
28+
```
29+
30+
## Running
31+
32+
### From the command line
33+
34+
```bash
35+
# show all subcommands
36+
pygeoapi-auth
37+
38+
# inject authorization into OpenAPI using Authelia
39+
pygeoapi-auth openapi inject-auth local-openapi.yml authelia authelia-conf.yml
40+
41+
# inject authorization into OpenAPI using Authelia with an API prefix
42+
pygeoapi-auth openapi inject-auth local-openapi.yml authelia authelia-conf.yml --api-prefix api
43+
44+
# inject authorization into OpenAPI using Authelia with an API prefix, writing to file
45+
pygeoapi-auth openapi inject-auth local-openapi.yml authelia authelia-conf.yml --api-prefix api --output-file openapi-auth.yml
46+
47+
# if installed in the pygeoapi deployment environment, run as a plugin!
48+
pygeoapi plugins openapi inject-auth local-openapi.yml authelia authelia-conf.yml --api-prefix api --output-file openapi-auth.yml
49+
```
50+
51+
### Using the API from Python
52+
53+
TODO
54+
55+
## Development
56+
57+
### Setting up a Development Environment
58+
59+
Same as installing a package. Use a virtualenv. Also install developer
60+
requirements:
61+
62+
```bash
63+
pip3 install -r requirements-dev.txt
64+
```
65+
66+
### Running Tests
67+
68+
```bash
69+
# via setuptools
70+
python3 setup.py test
71+
# manually
72+
cd tests
73+
python3 run_tests.py
74+
```
75+
76+
## Releasing
77+
78+
```bash
79+
# update version
80+
vi pygeoapi_auth/__init__.py
81+
git commit -m 'update release version' pygeoapi_auth/__init__.py
82+
# push changes
83+
git push origin master
84+
git tag -a x.y.z -m 'tagging release x.y.z'
85+
# push tag
86+
git push --tags
87+
rm -fr build dist *.egg-info
88+
python3 setup.py sdist bdist_wheel --universal
89+
twine upload dist/*
90+
```
91+
92+
### Code Conventions
93+
94+
* [PEP8](https://www.python.org/dev/peps/pep-0008)
95+
96+
### Bugs and Issues
97+
98+
All bugs, enhancements and issues are managed on [GitHub](https://github.com/geopython/pygeoapi-auth/issues).
99+
100+
## Contact
101+
102+
* [Tom Kralidis](https://github.com/tomkralidis)
103+
* [Youssef Harby](https://github.com/Youssef-Harby)

pygeoapi_auth/__init__.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
###################################################################
2+
#
3+
# Authors: Tom Kralidis <[email protected]>
4+
#
5+
# Copyright (c) 2024 Tom Kralidis
6+
#
7+
# Permission is hereby granted, free of charge, to any person
8+
# obtaining a copy of this software and associated documentation
9+
# files (the "Software"), to deal in the Software without
10+
# restriction, including without limitation the rights to use,
11+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
# copies of the Software, and to permit persons to whom the
13+
# Software is furnished to do so, subject to the following
14+
# conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be
17+
# included in all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+
# OTHER DEALINGS IN THE SOFTWARE.
27+
#
28+
###################################################################
29+
30+
import click
31+
32+
from pygeoapi_auth.openapi import openapi
33+
34+
__version__ = '0.0.1'
35+
36+
37+
@click.group()
38+
@click.version_option(version=__version__)
39+
def cli():
40+
pass
41+
42+
43+
cli.add_command(openapi)

pygeoapi_auth/auth/__init__.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
###################################################################
2+
#
3+
# Authors: Tom Kralidis <[email protected]>
4+
#
5+
# Copyright (c) 2024 Tom Kralidis
6+
#
7+
# Permission is hereby granted, free of charge, to any person
8+
# obtaining a copy of this software and associated documentation
9+
# files (the "Software"), to deal in the Software without
10+
# restriction, including without limitation the rights to use,
11+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
# copies of the Software, and to permit persons to whom the
13+
# Software is furnished to do so, subject to the following
14+
# conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be
17+
# included in all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+
# OTHER DEALINGS IN THE SOFTWARE.
27+
#
28+
###################################################################
29+
30+
from abc import ABC, abstractmethod
31+
import importlib
32+
import logging
33+
from typing import IO
34+
35+
import yaml
36+
37+
LOGGER = logging.getLogger(__name__)
38+
39+
40+
class AuthProvider(ABC):
41+
def __init__(self, config: IO = None):
42+
"""Initializer"""
43+
44+
self.config = yaml.safe_load(config)
45+
self.resources = self.get_resources()
46+
47+
@abstractmethod
48+
def get_resources(self):
49+
raise NotImplementedError()
50+
51+
@abstractmethod
52+
def is_resource_protected(
53+
self, path: str, api_prefix: str = None) -> bool:
54+
55+
raise NotImplementedError()
56+
57+
58+
def load_auth_provider(factory: str, config_file: str) -> AuthProvider:
59+
"""
60+
Load auth provider plugin
61+
62+
:param factory: `str` of dotted path of Python module/class
63+
:param configuration: `str` of configuration of auth provider
64+
65+
:returns: AuthProvider object
66+
"""
67+
68+
modulename = f'{__package__}.{factory}'
69+
classname = AUTH_PROVIDERS[factory]
70+
71+
LOGGER.debug(f'module name: {modulename}')
72+
LOGGER.debug(f'class name: {classname}')
73+
74+
module = importlib.import_module(modulename)
75+
76+
return getattr(module, classname)(config_file)
77+
78+
79+
AUTH_PROVIDERS = {
80+
'authelia': 'AutheliaAuthProvider'
81+
}

pygeoapi_auth/auth/authelia.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
###################################################################
2+
#
3+
# Authors: Tom Kralidis <[email protected]>
4+
#
5+
# Copyright (c) 2024 Tom Kralidis
6+
#
7+
# Permission is hereby granted, free of charge, to any person
8+
# obtaining a copy of this software and associated documentation
9+
# files (the "Software"), to deal in the Software without
10+
# restriction, including without limitation the rights to use,
11+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
# copies of the Software, and to permit persons to whom the
13+
# Software is furnished to do so, subject to the following
14+
# conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be
17+
# included in all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+
# OTHER DEALINGS IN THE SOFTWARE.
27+
#
28+
###################################################################
29+
30+
import logging
31+
import re
32+
33+
from pygeoapi_auth.auth import AuthProvider
34+
35+
LOGGER = logging.getLogger(__name__)
36+
37+
38+
class AutheliaAuthProvider(AuthProvider):
39+
def get_resources(self):
40+
print(self.config)
41+
return [item for sublist in self.config['access_control']['rules']
42+
for item in sublist['resources']]
43+
44+
def is_resource_protected(self, path: str, api_prefix: str = None) -> bool:
45+
for resource in self.resources:
46+
LOGGER.debug(f'Testing {path} against {resource}')
47+
if api_prefix is not None:
48+
path2 = f'/{api_prefix}{path}'
49+
else:
50+
path2 = path
51+
52+
LOGGER.debug(f'Generated path: {path2}')
53+
54+
if re.search(resource, path2):
55+
LOGGER.debug(f'{path2} matches {resource}')
56+
return True
57+
58+
return False

pygeoapi_auth/cli_options.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
###################################################################
2+
#
3+
# Authors: Tom Kralidis <[email protected]>
4+
#
5+
# Copyright (c) 2024 Tom Kralidis
6+
#
7+
# Permission is hereby granted, free of charge, to any person
8+
# obtaining a copy of this software and associated documentation
9+
# files (the "Software"), to deal in the Software without
10+
# restriction, including without limitation the rights to use,
11+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
# copies of the Software, and to permit persons to whom the
13+
# Software is furnished to do so, subject to the following
14+
# conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be
17+
# included in all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+
# OTHER DEALINGS IN THE SOFTWARE.
27+
#
28+
###################################################################
29+
30+
import logging
31+
import sys
32+
33+
import click
34+
35+
36+
def OPTION_VERBOSITY(f):
37+
logging_options = ['ERROR', 'WARNING', 'INFO', 'DEBUG']
38+
39+
def callback(ctx, param, value):
40+
if value is not None:
41+
logging.basicConfig(stream=sys.stdout,
42+
level=getattr(logging, value))
43+
return True
44+
45+
return click.option('--verbosity', '-v',
46+
type=click.Choice(logging_options),
47+
help='Verbosity',
48+
callback=callback)(f)
49+
50+
51+
def cli_callbacks(f):
52+
f = OPTION_VERBOSITY(f)
53+
return f

0 commit comments

Comments
 (0)