Skip to content

Commit

Permalink
Merge pull request #49 from best-doctor/bang-468-add-keycloak-oauth
Browse files Browse the repository at this point in the history
BANG-468: Force change to https
  • Loading branch information
Arondit authored Aug 29, 2024
2 parents 9279c00 + 28fac35 commit 010ea1f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
30 changes: 30 additions & 0 deletions auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import aiohttp_jinja2
from aiohttp.abc import StreamResponse
from aiohttp.web import HTTPFound, View, Response
from aiohttp.web_exceptions import HTTPTemporaryRedirect
from aiohttp.web_request import Request
from aiohttp_security import forget, remember
from dynaconf import settings
from marshmallow.exceptions import ValidationError
from multidict import MultiDictProxy
from yarl import URL

from auth.auth import check_credentials, get_login_context
from auth.schemes import LoginPostRequestSchema
Expand All @@ -16,6 +19,33 @@
from typing import Optional, Dict


def redirect_uri(request: Request) -> str:
oauth_subbapp = request.app._subapps[0]
url = str(request.url.with_path(str(oauth_subbapp.router['callback'].url_for())))
if settings.OAUTH.force_https:
return url.replace('http', 'https')
return url


class OauthViewForceHttps(View):
"""Modified version of aiohttp_oauth2.client.views.AuthView to replace http by https"""

async def get(self) -> Response:
params = {
'client_id': self.request.app['CLIENT_ID'],
'redirect_uri': redirect_uri(self.request),
'response_type': 'code',
**self.request.app['AUTH_EXTRAS'],
}

if self.request.app['SCOPES']:
params['scope'] = ' '.join(self.request.app['SCOPES'])

location = str(URL(self.request.app['AUTHORIZE_URL']).with_query(params))

return HTTPTemporaryRedirect(location=location)


class LoginView(View):
@aiohttp_jinja2.template('users/login.html')
async def get(self, error: Optional[str] = None) -> Dict[str, Union[str | bool]]:
Expand Down
22 changes: 20 additions & 2 deletions its_on/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import asyncio
import pathlib

from aiohttp import web
from aiohttp import web, ClientSession
from aiohttp_oauth2 import oauth2_app
from aiohttp_security import setup as setup_security
from aiohttp_security import SessionIdentityPolicy
Expand All @@ -21,7 +21,7 @@
from its_on.cache import setup_cache
from its_on.db_utils import init_pg, close_pg
from its_on.middlewares import setup_middlewares
from its_on.routes import setup_routes
from its_on.routes import setup_routes, setup_oauth_route

BASE_DIR = pathlib.Path(__file__).parent.parent

Expand All @@ -37,13 +37,31 @@ async def make_redis_pool() -> aioredis.ConnectionsPool:
return await aioredis.create_redis_pool(redis_address, timeout=1)


async def client_session(app: web.Application): # type:ignore
async with ClientSession() as session:
app['session'] = session
yield


def init_app(
loop: asyncio.AbstractEventLoop,
redis_pool: Optional[aioredis.ConnectionsPool] = None,
) -> web.Application:
app = web.Application(loop=loop)

if settings.OAUTH.IS_USED:
client_id = settings.OAUTH.CLIENT_ID
authorize_url = settings.OAUTH.AUTHORIZE_URL
scopes = None
auth_extras = None
app.update( # pylint: disable=no-member
CLIENT_ID=client_id,
AUTHORIZE_URL=authorize_url,
SCOPES=scopes,
AUTH_EXTRAS=auth_extras or {},
)
app.cleanup_ctx.append(client_session)
setup_oauth_route(app)
app.add_subapp(
'/oauth/',
oauth2_app(
Expand Down
6 changes: 5 additions & 1 deletion its_on/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from aiohttp_cors import CorsConfig
from dynaconf import settings

from auth.views import LoginView, LogoutView
from auth.views import LoginView, LogoutView, OauthViewForceHttps
from its_on.views import SwitchFullListView, SwitchListView, SwitchSvgBadgeView
from its_on.admin.views.switches import (
SwitchAddAdminView,
Expand All @@ -20,6 +20,10 @@
from pathlib import Path


def setup_oauth_route(app: Application) -> None:
app.router.add_view('/oauth/auth', OauthViewForceHttps)


def setup_routes(app: Application, base_dir: Path, cors_config: CorsConfig) -> None:
app.router.add_view('/zbs/login', LoginView, name='login_view')
app.router.add_view('/zbs/logout', LogoutView)
Expand Down
3 changes: 2 additions & 1 deletion settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ default:
database:
dsn: postgresql://bestdoctor:bestdoctor@localhost:5432/its_on
oauth:
is_used: false
is_used: true
only_oauth: false
client_id: '@none'
client_secret: '@none'
authorize_url: '@none'
token_url: '@none'
force_https: true
sign_in_title: 'Sign in with "Bestdoctor ID"'
enable_db_logging: false
cache_url: redis://127.0.0.1:6379/1
Expand Down

0 comments on commit 010ea1f

Please sign in to comment.