more oauth2 fixes
This commit is contained in:
parent
65ceb2abbd
commit
14d219eef7
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue