Implement initial flow (#2)
This commit is contained in:
committed by
GitHub
parent
1c8c7ed14a
commit
8ba494c49c
49
custom_components/auth_oidc/endpoints/callback.py
Normal file
49
custom_components/auth_oidc/endpoints/callback.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from aiohttp import web
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
import logging
|
||||
from ..oidc_client import OIDCClient
|
||||
from ..provider import OpenIDAuthProvider
|
||||
|
||||
PATH = "/auth/oidc/callback"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
class OIDCCallbackView(HomeAssistantView):
|
||||
"""OIDC Plugin Callback View."""
|
||||
|
||||
requires_auth = False
|
||||
url = PATH
|
||||
name = "auth:oidc:callback"
|
||||
|
||||
def __init__(
|
||||
self, oidc_client: OIDCClient, oidc_provider: OpenIDAuthProvider
|
||||
) -> None:
|
||||
self.oidc_client = oidc_client
|
||||
self.oidc_provider = oidc_provider
|
||||
|
||||
async def get(self, request: web.Request) -> web.Response:
|
||||
"""Receive response."""
|
||||
|
||||
_LOGGER.debug("Callback view accessed")
|
||||
|
||||
params = request.rel_url.query
|
||||
code = params.get("code")
|
||||
state = params.get("state")
|
||||
base_uri = str(request.url).split('/auth', 2)[0]
|
||||
|
||||
if not (code and state):
|
||||
return web.Response(
|
||||
headers={"content-type": "text/html"},
|
||||
text="<h1>Error</h1><p>Missing code or state parameter</p>",
|
||||
)
|
||||
|
||||
user_details = await self.oidc_client.complete_token_flow(base_uri, code, state)
|
||||
if user_details is None:
|
||||
return web.Response(
|
||||
headers={"content-type": "text/html"},
|
||||
text="<h1>Error</h1><p>Failed to get user details, see console.</p>",
|
||||
)
|
||||
|
||||
code = await self.oidc_provider.save_user_info(user_details)
|
||||
|
||||
return web.HTTPFound(base_uri + "/auth/oidc/finish?code=" + code)
|
||||
24
custom_components/auth_oidc/endpoints/finish.py
Normal file
24
custom_components/auth_oidc/endpoints/finish.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from aiohttp import web
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
import logging
|
||||
|
||||
PATH = "/auth/oidc/finish"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
class OIDCFinishView(HomeAssistantView):
|
||||
"""OIDC Plugin Finish View."""
|
||||
|
||||
requires_auth = False
|
||||
url = PATH
|
||||
name = "auth:oidc:finish"
|
||||
|
||||
async def get(self, request: web.Request) -> web.Response:
|
||||
"""Receive response."""
|
||||
|
||||
code = request.query.get("code", "FAIL")
|
||||
|
||||
return web.Response(
|
||||
headers={"content-type": "text/html"},
|
||||
text=f"<h1>Done!</h1><p>Your code is: <b>{code}</b></p><p>Please return to the Home Assistant login screen (or your mobile app) and fill in this code into the single login field. It should be visible if you select 'Login with OpenID Connect (SSO)'.</p>",
|
||||
)
|
||||
46
custom_components/auth_oidc/endpoints/redirect.py
Normal file
46
custom_components/auth_oidc/endpoints/redirect.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from aiohttp import web
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
import logging
|
||||
|
||||
from ..oidc_client import OIDCClient
|
||||
|
||||
PATH = "/auth/oidc/redirect"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
class OIDCRedirectView(HomeAssistantView):
|
||||
"""OIDC Plugin Redirect View."""
|
||||
|
||||
requires_auth = False
|
||||
url = PATH
|
||||
name = "auth:oidc:redirect"
|
||||
|
||||
def __init__(
|
||||
self, oidc_client: OIDCClient
|
||||
) -> None:
|
||||
self.oidc_client = oidc_client
|
||||
|
||||
async def get(self, request: web.Request) -> web.Response:
|
||||
"""Receive response."""
|
||||
|
||||
_LOGGER.debug("Redirect view accessed")
|
||||
|
||||
base_uri = str(request.url).split('/auth', 2)[0]
|
||||
_LOGGER.debug("Base URI: %s", base_uri)
|
||||
|
||||
auth_url = await self.oidc_client.get_authorization_url(base_uri)
|
||||
_LOGGER.debug("Auth URL: %s", auth_url)
|
||||
|
||||
if auth_url:
|
||||
return web.HTTPFound(auth_url)
|
||||
else:
|
||||
return web.Response(
|
||||
headers={"content-type": "text/html"},
|
||||
text="<h1>Plugin is misconfigured, discovery could not be obtained</h1>",
|
||||
)
|
||||
|
||||
async def post(self, request: web.Request) -> web.Response:
|
||||
"""POST"""
|
||||
|
||||
_LOGGER.debug("Redirect POST view accessed")
|
||||
return await self.get(request)
|
||||
24
custom_components/auth_oidc/endpoints/welcome.py
Normal file
24
custom_components/auth_oidc/endpoints/welcome.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from aiohttp import web
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
import logging
|
||||
|
||||
PATH = "/auth/oidc/welcome"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
class OIDCWelcomeView(HomeAssistantView):
|
||||
"""OIDC Plugin Welcome View."""
|
||||
|
||||
requires_auth = False
|
||||
url = PATH
|
||||
name = "auth:oidc:welcome"
|
||||
|
||||
async def get(self, request: web.Request) -> web.Response:
|
||||
"""Receive response."""
|
||||
|
||||
_LOGGER.debug("Welcome view accessed")
|
||||
|
||||
return web.Response(
|
||||
headers={"content-type": "text/html"},
|
||||
text="<h1>OIDC Login (beta)</h1><p><a href='/auth/oidc/redirect'>Login with OIDC</a></p>",
|
||||
)
|
||||
Reference in New Issue
Block a user