-
Notifications
You must be signed in to change notification settings - Fork 33
Implement OpenID Connect authentication #48
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Patrick Uiterwijk <[email protected]>
Signed-off-by: Patrick Uiterwijk <[email protected]>
Signed-off-by: Patrick Uiterwijk <[email protected]>
Signed-off-by: Patrick Uiterwijk <[email protected]>
Awesome work, thanks so much for the contribution! After a cursory review, this looks pretty good, but I'll give it a closer look soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. Could you also update the README documenting this new functionality and how to use it?
if current_user.is_authenticated: | ||
return | ||
|
||
from modern_paste import oidc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this import to the top of the file?
@@ -70,3 +73,45 @@ def auth_status(): | |||
'user_id': getattr(current_user, 'user_id', None), | |||
}, | |||
}), constants.api.SUCCESS_CODE | |||
|
|||
|
|||
def oidc_request_loader(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is not an API handler and doesn't belong in this file. Maybe create a new file app/util/oidc.py
and move this there?
# An OAuth2 Bearer Token was sent | ||
token = flask.request.headers['Authorization'].split(' ', 1)[1].strip() | ||
valid = oidc.validate_token(token, config.AUTH_OIDC_SCOPE) | ||
if valid is True: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if valid:
except UserDoesNotExistException: | ||
info = oidc.user_getinfo(['sub', 'name', 'email'], token) | ||
else: | ||
return flask.jsonify(constants.api.AUTH_FAILURE), constants.api.AUTH_FAILURE_CODE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function isn't an API handler, what is the meaning of returning an API response here?
@@ -39,7 +39,10 @@ def view_function(): | |||
""" | |||
@wraps(func) | |||
def decorated_view(*args, **kwargs): | |||
template, context = func(*args, **kwargs) | |||
response = func(*args, **kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change seems to be unrelated to this PR. What is the motivation? @view_function
is a deliberate abstraction requiring view functions to always return a tuple of (template name, context object)
and this logic overrides that purpose.
import models | ||
from views import * | ||
|
||
def setup_oidc(): | ||
from flask_oidc import OpenIDConnect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move these imports to the top of the file?
@@ -113,6 +117,7 @@ | |||
</div> | |||
</div> | |||
|
|||
{% if auth_method == 'local' %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent the following HTML block?
@@ -10,6 +10,20 @@ | |||
|
|||
|
|||
@app.context_processor | |||
def add_config(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is necessary; there is already an abstraction in place to provide the config to the template during server-side rendering in api.decorators.context_config()
return 'user/login.html', {} | ||
auth_method = config.AUTH_METHOD | ||
if auth_method == 'oidc': | ||
from modern_paste import oidc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this import to the top
@@ -0,0 +1 @@ | |||
{"web": {"redirect_uris": ["https://paste/oidc_callback"], "token_uri": "https://idp/openidc/Token", "auth_uri": "https://idp/openidc/Authorization", "client_id": "myclient", "client_secret": "thesecret", "userinfo_uri": "https://idp/openidc/UserInfo", "token_introspection_uri": "https://idp/openidc/TokenInfo", "issuer": "https://idp/openidc/"}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't seem like this secrets file should be versioned. Can you delete this file and instead document the shape of the secrets object in the README?
No description provided.