aboutsummaryrefslogtreecommitdiffstats
path: root/cloud_mdir_sync/oauth.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloud_mdir_sync/oauth.py')
-rw-r--r--cloud_mdir_sync/oauth.py26
1 files changed, 17 insertions, 9 deletions
diff --git a/cloud_mdir_sync/oauth.py b/cloud_mdir_sync/oauth.py
index 449d16c..163dcba 100644
--- a/cloud_mdir_sync/oauth.py
+++ b/cloud_mdir_sync/oauth.py
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
import asyncio
+import os
import aiohttp
import aiohttp.web
@@ -9,35 +10,36 @@ class WebServer(object):
"""A small web server is used to manage oauth requests. The user should point a browser
window at localhost. The program will generate redirects for the browser to point at
OAUTH servers when interactive authentication is required."""
- url = "http://localhost:8080/"
+ url = "http://127.0.0.1:8080/"
runner = None
def __init__(self):
self.auth_redirs = {}
self.web_app = aiohttp.web.Application()
self.web_app.router.add_get("/", self._start)
- self.web_app.router.add_get("/oauth2/msal", self._oauth2_msal)
+ self.web_app.router.add_get("/oauth2/msal", self._oauth2_redirect)
+ self.web_app.router.add_get("/oauth2/gmail", self._oauth2_redirect)
async def go(self):
self.runner = aiohttp.web.AppRunner(self.web_app)
await self.runner.setup()
- site = aiohttp.web.TCPSite(self.runner, 'localhost', 8080)
+ site = aiohttp.web.TCPSite(self.runner, '127.0.0.1', 8080)
await site.start()
async def close(self):
if self.runner:
await self.runner.cleanup()
- async def auth_redir(self, url, state):
+ async def auth_redir(self, url: str, state: str, redir_url: str):
"""Call as part of an OAUTH flow to hand the URL off to interactive browser
based authentication. The flow will resume when the OAUTH server
redirects back to the localhost server. The final query paremeters
will be returned by this function"""
queue = asyncio.Queue()
- self.auth_redirs[state] = (url, queue)
+ self.auth_redirs[state] = (url, queue, redir_url)
return await queue.get()
- def _start(self, request):
+ def _start(self, request: aiohttp.web.Request):
"""Feed redirects to the web browser until all authing is done. FIXME: Some
fancy java script should be used to fetch new interactive auth
requests"""
@@ -45,11 +47,17 @@ class WebServer(object):
raise aiohttp.web.HTTPFound(I[0])
return aiohttp.web.Response(text="Authentication done")
- def _oauth2_msal(self, request):
+ def _oauth2_redirect(self, request: aiohttp.web.Request):
"""Use for the Azure AD authentication response redirection"""
- state = request.query["state"]
+ state = request.query.get("state", None)
+ if state is None:
+ raise aiohttp.web.HTTPBadRequest(text="No state parameter")
try:
- queue = self.auth_redirs[state][1]
+ _, queue, redir_url = self.auth_redirs[state]
+ # RFC8252 8.10
+ if redir_url != self.url[:-1] + request.path:
+ raise aiohttp.web.HTTPBadRequest(
+ text="Invalid redirection path")
del self.auth_redirs[state]
queue.put_nowait(request.query)
except KeyError: