more oauth2 fixes

master
TuxCoder 2023-03-18 12:00:40 +01:00
parent 65ceb2abbd
commit 14d219eef7
7 changed files with 45 additions and 17 deletions

View File

@ -6,8 +6,8 @@ from typing import Optional
class HydraService: class HydraService:
def __init__(self): def __init__(self):
self._hydra_client = None # type: Optional[Client] self._hydra_client: Optional[Client] = None
self._oauth_client = None # type: Optional[Client] self._oauth_client: Optional[Client] = None
@property @property
def hydra_client(self) -> Client: def hydra_client(self) -> Client:

View File

@ -9,9 +9,6 @@ from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from flask import current_app from flask import current_app
from lenticular_cloud.model import User from lenticular_cloud.model import User
from ldap3_orm import AttrDef, EntryBase as _EntryBase, ObjectDef, EntryType
from ldap3_orm import Reader
from ldap3 import Connection, Server, ALL
import logging import logging
@ -23,6 +20,10 @@ depends_on = None
def upgrade(): def upgrade():
from ldap3_orm import AttrDef, EntryBase as _EntryBase, ObjectDef, EntryType
from ldap3_orm import Reader
from ldap3 import Connection, Server, ALL
app = current_app app = current_app
server = Server(app.config['LDAP_URL'], get_info=ALL) server = Server(app.config['LDAP_URL'], get_info=ALL)
ldap_conn = Connection(server, app.config['LDAP_BIND_DN'], app.config['LDAP_BIND_PW'], auto_bind=True) # TODO auto_bind read docu ldap_conn = Connection(server, app.config['LDAP_BIND_DN'], app.config['LDAP_BIND_PW'], auto_bind=True) # TODO auto_bind read docu

View File

@ -11,7 +11,7 @@ import logging
import crypt import crypt
import secrets import secrets
import string import string
from flask_sqlalchemy import SQLAlchemy, orm from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate from flask_migrate import Migrate
from datetime import datetime from datetime import datetime
import uuid import uuid

View File

@ -3,16 +3,15 @@ from flask_babel import Babel
from flask_login import current_user from flask_login import current_user
from typing import Optional from typing import Optional
from lenticular_cloud.model import db, User from lenticular_cloud.model import db, User
from importlib.metadata import version
LANGUAGES = { LANGUAGES = {
'en': 'English', 'en': 'English',
'de': 'Deutsch' 'de': 'Deutsch'
} }
babel = Babel()
@babel.localeselector
def get_locale() -> str: def get_locale() -> str:
# if a user is logged in, use the locale from the user settings # if a user is logged in, use the locale from the user settings
user = current_user # type: Optional[User] user = current_user # type: Optional[User]
@ -34,13 +33,31 @@ def get_locale() -> str:
# example. The best match wins. # example. The best match wins.
return request.accept_languages.best_match(['de']) return request.accept_languages.best_match(['de'])
@babel.timezoneselector
def get_timezone() -> Optional[str]: def get_timezone() -> Optional[str]:
# user = getattr(g, 'user', None) # user = getattr(g, 'user', None)
# if user is not None: # if user is not None:
# return user.timezone # return user.timezone
return None return None
flask_babel_version = version('flask_babel')
kwargs = {}
if flask_babel_version >= "3.0.0":
kwargs = {
'locale_selector': get_locale,
#'timezone_selector': get_timezone,
}
babel = Babel(**kwargs)
if flask_babel_version < "3.0.0":
@babel.localeselector
def _get_locale() -> str:
return get_locale()
@babel.timezoneselector
def _get_timezone() -> Optional[str]:
return get_timezone()
def init_babel(app: Flask) -> None: def init_babel(app: Flask) -> None:
babel.init_app(app) babel.init_app(app)

View File

@ -8,8 +8,10 @@ from oauthlib.oauth2.rfc6749.errors import TokenExpiredError
from authlib.integrations.base_client.errors import InvalidTokenError from authlib.integrations.base_client.errors import InvalidTokenError
from ory_hydra_client.api.o_auth_2 import list_o_auth_2_clients, get_o_auth_2_client, set_o_auth_2_client, create_o_auth_2_client from ory_hydra_client.api.o_auth_2 import list_o_auth_2_clients, get_o_auth_2_client, set_o_auth_2_client, create_o_auth_2_client
from ory_hydra_client.models import OAuth20Client, GenericError from ory_hydra_client.models import OAuth20Client, GenericError
from typing import Optional from typing import Optional, List
from collections.abc import Iterable from collections.abc import Iterable
from http import HTTPStatus
import httpx
import logging import logging
from ..model import db, User from ..model import db, User
@ -77,7 +79,12 @@ def registration_accept(registration_id) -> ResponseReturnValue:
@admin_views.route('/clients') @admin_views.route('/clients')
async def clients() -> ResponseReturnValue: async def clients() -> ResponseReturnValue:
clients = await list_o_auth_2_clients.asyncio_detailed(_client=hydra_service.hydra_client) response = await list_o_auth_2_clients.asyncio_detailed(_client=hydra_service.hydra_client)
clients = response.parsed
if clients is None:
logger.error(f"could not fetch client list response {response}")
return 'internal error', 500
logger.error(f'{clients}')
return render_template('admin/clients.html.j2', clients=clients) return render_template('admin/clients.html.j2', clients=clients)
@admin_views.route('/client/<client_id>', methods=['GET', 'POST']) @admin_views.route('/client/<client_id>', methods=['GET', 'POST'])

View File

@ -92,11 +92,12 @@ def init_login_manager(app: Flask) -> None:
name="custom", name="custom",
client_id=app.config['OAUTH_ID'], client_id=app.config['OAUTH_ID'],
client_secret=app.config['OAUTH_SECRET'], client_secret=app.config['OAUTH_SECRET'],
server_metadata_url=f'{base_url}/.well-known/openid-configuration',
access_token_url=f"{base_url}/oauth2/token", access_token_url=f"{base_url}/oauth2/token",
authorize_url=f"{base_url}/oauth2/auth", authorize_url=f"{base_url}/oauth2/auth",
api_base_url=base_url, api_base_url=base_url,
client_kwargs={'scope': ' '.join(['openid', 'profile', 'manage'])} client_kwargs={'scope': ' '.join(['openid', 'profile', 'manage'])},
) )
oauth2.init_app(app) oauth2.init_app(app)
login_manager.init_app(app) login_manager.init_app(app)

View File

@ -8,6 +8,7 @@ from ...types import Response, UNSET
from ... import errors from ... import errors
from ...types import UNSET, Unset from ...types import UNSET, Unset
from ...models import OAuth20Client
from typing import Optional from typing import Optional
from typing import Union from typing import Union
@ -63,16 +64,17 @@ def _get_kwargs(
} }
def _parse_response(*, client: Client, response: httpx.Response) -> Optional[Any]: def _parse_response(*, client: Client, response: httpx.Response) -> Optional[List[OAuth20Client]]:
if response.status_code == HTTPStatus.OK: if response.status_code == HTTPStatus.OK:
return None response_200 = list([ OAuth20Client.from_dict(data) for data in response.json() ])
return response_200
if client.raise_on_unexpected_status: if client.raise_on_unexpected_status:
raise errors.UnexpectedStatus(f"Unexpected status code: {response.status_code}") raise errors.UnexpectedStatus(f"Unexpected status code: {response.status_code}")
else: else:
return None return None
def _build_response(*, client: Client, response: httpx.Response) -> Response[Any]: def _build_response(*, client: Client, response: httpx.Response) -> Response[List[OAuth20Client]]:
return Response( return Response(
status_code=HTTPStatus(response.status_code), status_code=HTTPStatus(response.status_code),
content=response.content, content=response.content,
@ -89,7 +91,7 @@ def sync_detailed(
client_name: Union[Unset, None, str] = UNSET, client_name: Union[Unset, None, str] = UNSET,
owner: Union[Unset, None, str] = UNSET, owner: Union[Unset, None, str] = UNSET,
) -> Response[Any]: ) -> Response[List[OAuth20Client]]:
"""List OAuth 2.0 Clients """List OAuth 2.0 Clients
This endpoint lists all clients in the database, and never returns client secrets. This endpoint lists all clients in the database, and never returns client secrets.
@ -135,7 +137,7 @@ async def asyncio_detailed(
client_name: Union[Unset, None, str] = UNSET, client_name: Union[Unset, None, str] = UNSET,
owner: Union[Unset, None, str] = UNSET, owner: Union[Unset, None, str] = UNSET,
) -> Response[Any]: ) -> Response[List[OAuth20Client]]:
"""List OAuth 2.0 Clients """List OAuth 2.0 Clients
This endpoint lists all clients in the database, and never returns client secrets. This endpoint lists all clients in the database, and never returns client secrets.