move migration, bugfixes, ....

This commit is contained in:
TuxCoder 2022-04-08 21:29:23 +02:00
parent 5401e2594d
commit 18863bee7f
25 changed files with 255 additions and 33 deletions

View file

@ -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

View file

@ -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)

View file

@ -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]

View file

@ -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')

View file

@ -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