Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BANG-468: Force change to https #49

Merged
merged 4 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading