move migration, bugfixes, ....
This commit is contained in:
parent
5401e2594d
commit
18863bee7f
25 changed files with 255 additions and 33 deletions
|
@ -5,6 +5,7 @@ from flask import jsonify
|
|||
from flask.typing import ResponseReturnValue
|
||||
from flask_login import current_user, logout_user
|
||||
from oauthlib.oauth2.rfc6749.errors import TokenExpiredError
|
||||
from authlib.integrations.base_client.errors import InvalidTokenError
|
||||
from ory_hydra_client.api.admin import list_o_auth_2_clients, get_o_auth_2_client, update_o_auth_2_client, create_o_auth_2_client
|
||||
from ory_hydra_client.models import OAuth2Client, GenericError
|
||||
from typing import Optional
|
||||
|
@ -28,7 +29,7 @@ def before_request() -> Optional[ResponseReturnValue]:
|
|||
return redirect_login()
|
||||
if 'groups' not in data or 'admin' not in data['groups']:
|
||||
return 'Not an admin', 403
|
||||
except MissingTokenError:
|
||||
except (MissingTokenError, InvalidTokenError):
|
||||
return redirect_login()
|
||||
return None
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ from flask.typing import ResponseReturnValue
|
|||
|
||||
from flask import Blueprint, render_template, request, url_for
|
||||
import logging
|
||||
import httpx
|
||||
|
||||
from ..model import User
|
||||
from ..auth_providers import LdapAuthProvider
|
||||
|
@ -18,20 +19,43 @@ from ory_hydra_client.models import GenericError
|
|||
|
||||
api_views = Blueprint('api', __name__, url_prefix='/api')
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@api_views.route('/users', methods=['GET'])
|
||||
def user_list() -> ResponseReturnValue:
|
||||
if 'authorization' not in request.headers:
|
||||
return '', 403
|
||||
token = request.headers['authorization'].replace('Bearer ', '')
|
||||
token_info = introspect_o_auth_2_token.sync(_client=hydra_service.hydra_client)
|
||||
# if 'authorization' not in request.headers:
|
||||
# return '', 403
|
||||
# token = request.headers['authorization'].replace('Bearer ', '')
|
||||
# token_info = introspect_o_auth_2_token.sync(_client=hydra_service.hydra_client)
|
||||
|
||||
if token_info is None or isinstance(token_info, GenericError):
|
||||
return 'internal errror', 500
|
||||
# if token_info is None or isinstance(token_info, GenericError):
|
||||
# return 'internal errror', 500
|
||||
|
||||
if not isinstance(token_info.scope, str) or 'lc_i_userlist' not in token_info.scope.split(' '):
|
||||
return '', 403
|
||||
# if not isinstance(token_info.scope, str) or 'lc_i_userlist' not in token_info.scope.split(' '):
|
||||
# return '', 403
|
||||
|
||||
return jsonify([
|
||||
{'username': str(user.username), 'email': str(user.email)}
|
||||
for user in User.query_().all()])
|
||||
|
||||
@api_views.route('/introspect', methods=['POST'])
|
||||
def introspect() -> ResponseReturnValue:
|
||||
token = request.form['token']
|
||||
logger.error(f'debug token: {token}')
|
||||
resp = httpx.post("https://hydra.cloud.tux.ac/oauth2/introspect", data={'token':token})
|
||||
#if token_info is None or isinstance(token_info, GenericError):
|
||||
if resp.status_code != 200:
|
||||
return jsonify({}), 500
|
||||
token_info = resp.json()
|
||||
#token_info = introspect_o_auth_2_token.sync(_client=hydra_service, token=token)
|
||||
logger.error(f'debug hydra: {token_info}')
|
||||
|
||||
if not token_info['active']:
|
||||
return jsonify({'active': False})
|
||||
token_info['email'] = token_info['ext']['email']
|
||||
|
||||
logger.error(f'debug: {token_info}')
|
||||
|
||||
return jsonify(token_info)
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ async def consent() -> ResponseReturnValue:
|
|||
token_data = {
|
||||
'name': str(user.username),
|
||||
'preferred_username': str(user.username),
|
||||
'username': str(user.username),
|
||||
'email': str(user.email),
|
||||
'email_verified': True,
|
||||
'groups': [group.name for group in user.groups]
|
||||
|
|
|
@ -175,7 +175,7 @@ def webauthn_list_route() -> ResponseReturnValue:
|
|||
"""list registered credentials for current user"""
|
||||
|
||||
creds = WebauthnCredential.query.all()
|
||||
return render_template('webauthn_list.html', creds=creds, button_form=ButtonForm())
|
||||
return render_template('frontend/webauthn_list.html', creds=creds, button_form=ButtonForm())
|
||||
|
||||
|
||||
@frontend_views.route('/webauthn/delete/<webauthn_id>', methods=['POST'])
|
||||
|
@ -207,19 +207,15 @@ def random_string(length=32) -> str:
|
|||
def webauthn_pkcco_route() -> ResponseReturnValue:
|
||||
"""get publicKeyCredentialCreationOptions"""
|
||||
|
||||
form = ButtonForm()
|
||||
if form.validate_on_submit():
|
||||
user = User.query.get(current_user.id)
|
||||
user_handle = random_string()
|
||||
exclude_credentials = webauthn_credentials(user)
|
||||
pkcco, state = webauthn.register_begin(
|
||||
{'id': user_handle.encode('utf-8'), 'name': user.username, 'displayName': user.username},
|
||||
exclude_credentials)
|
||||
session['webauthn_register_user_handle'] = user_handle
|
||||
session['webauthn_register_state'] = state
|
||||
return Response(b64encode(cbor.encode(pkcco)).decode('utf-8'), mimetype='text/plain')
|
||||
|
||||
return '', HTTPStatus.BAD_REQUEST
|
||||
user = User.query.get(current_user.id)
|
||||
user_handle = random_string()
|
||||
exclude_credentials = webauthn_credentials(user)
|
||||
pkcco, state = webauthn.register_begin(
|
||||
{'id': user_handle.encode('utf-8'), 'name': user.username, 'displayName': user.username},
|
||||
exclude_credentials)
|
||||
session['webauthn_register_user_handle'] = user_handle
|
||||
session['webauthn_register_state'] = state
|
||||
return Response(b64encode(cbor.encode(pkcco)).decode('utf-8'), mimetype='text/plain')
|
||||
|
||||
|
||||
@frontend_views.route('/webauthn/register', methods=['GET', 'POST'])
|
||||
|
@ -248,7 +244,7 @@ def webauthn_register_route() -> ResponseReturnValue:
|
|||
current_app.logger.exception(e)
|
||||
flash('Error during registration.', 'error')
|
||||
|
||||
return render_template('webauthn_register.html', form=form)
|
||||
return render_template('frontend/webauthn_register.html', form=form)
|
||||
|
||||
|
||||
@frontend_views.route('/password_change')
|
||||
|
|
|
@ -9,7 +9,7 @@ from typing import Optional
|
|||
from ..model import User, SecurityUser
|
||||
|
||||
def fetch_token(name: str) -> Optional[dict]:
|
||||
token = session['token']
|
||||
token = session.get('token', None)
|
||||
if isinstance(token, dict):
|
||||
return token
|
||||
return None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue