Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ dist/
.coverage
htmlcov/
coverage.xml
lcov.info
lcov.info
.idea/
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,45 @@ def protected():
pass
```

If you're using the **Flask Application Factory**, set up using `init_app()` like:

```python
# __init__.py

oauth2 = OAuth2Decorator()


def create_app(config_class=Config):
application = Flask(__name__)
application.config.from_object(config_class)

# ... register blueprints etc

with application.app_context():
oauth2.init_app(application) # <-- call init_app()
return application
```

```python
# some-blueprint-file.py

from api import oauth2 # <-- from __init__.py

bp = Blueprint('users', __name__, url_prefix=Config.ROOT_URL+ '/api/v1')


@oauth2.requires_token()
@bp.route('/users', methods=['GET'])
def index():
"""
Get all users
"""
users = User.query.all()
return users_schema.dump(users)

```


# License

MIT License
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='flask-oauth2-validation',
version='0.1.3',
version='0.1.4',
author='Henrik Sachse',
author_email='henrik@0x7d7b.net',
description=(
Expand Down
19 changes: 12 additions & 7 deletions src/flask_oauth2_validation/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class OAuth2Decorator():

"""

def __init__(self, app: Flask):
def __init__(self, app: Flask | None = None):
""" Reads the app configuration and requests
the Authorization Server Metadata as well as the
authorization servers public keys.
Expand All @@ -68,12 +68,6 @@ def __init__(self, app: Flask):

self._logger = logging.getLogger(__name__)

app.config.setdefault('OAUTH2_ISSUER', None)
app.config.setdefault('OAUTH2_AUDIENCE', None)
app.config.setdefault('OAUTH2_JWKS_UPDATE_INTERVAL', None)
app.config.setdefault('OAUTH2_CLIENT_ID', None)
app.config.setdefault('OAUTH2_CLIENT_SECRET', None)

# Holds the current requests token in case
# the verification steps where all successful.
self.token = None
Expand All @@ -97,6 +91,17 @@ def __init__(self, app: Flask):
# that's why we cache its response, here.
self._cached_metadata = None

if app is not None:
self.init_app(app)

def init_app(self, app: Flask):

app.config.setdefault('OAUTH2_ISSUER', None)
app.config.setdefault('OAUTH2_AUDIENCE', None)
app.config.setdefault('OAUTH2_JWKS_UPDATE_INTERVAL', None)
app.config.setdefault('OAUTH2_CLIENT_ID', None)
app.config.setdefault('OAUTH2_CLIENT_SECRET', None)

# The only mandatory value is the issuer URI.
# In case it is the only value we expect it to offer
# Authorization Server Metadata support (RFC-8414).
Expand Down
8 changes: 8 additions & 0 deletions tests/functional/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,11 @@ def test_introspection_setup_without_secret(test_app):
with pytest.raises(TypeError) as err:
OAuth2Decorator(test_app)
assert str(err.value) == 'OAUTH2_CLIENT_SECRET config property required'


def test_set_up_using_flask_application_factory(test_app):
test_app.config['OAUTH2_ISSUER'] = 'https://issuer.local/oauth2'
oauth2 = OAuth2Decorator()
oauth2.init_app(test_app)
assert oauth2._issuer == 'https://issuer.local/oauth2'
assert oauth2._jwks_uri == 'https://issuer.local/oauth2/keys'