Browse Source

Allow OAuth hook to validate login: --oauth2-authorized-hook

tags/19.8.0
Henning Jacobs 3 months ago
parent
commit
fc3de8d474
3 changed files with 48 additions and 0 deletions
  1. +26
    -0
      examples/oauth2-validate-github-token/hooks.py
  2. +16
    -0
      kube_web/main.py
  3. +6
    -0
      kube_web/web.py

+ 26
- 0
examples/oauth2-validate-github-token/hooks.py View File

@@ -0,0 +1,26 @@
"""
Example hook to validate GitHub user login.

To be used with --oauth2-authorized-hook option
"""
import aiohttp
import logging


# list of authorized GitHub usernames
AUTHORIZED_USERS = frozenset(["hjacobs"])


async def oauth2_authorized(data: dict, session):
token = data["access_token"]
async with aiohttp.ClientSession() as session:
async with session.get(
"https://api.github.com/user", headers={"Authorization": f"token {token}"}
) as resp:
user_info = await resp.json()
login = user_info["login"]
logging.info(f"GitHub login is {login}")
if login not in AUTHORIZED_USERS:
# not authorized to access this app!
return False
return True

+ 16
- 0
kube_web/main.py View File

@@ -1,5 +1,7 @@
import asyncio
import aiohttp.web
import argparse
import importlib
import logging

from pathlib import Path
@@ -31,6 +33,15 @@ def key_value_pairs(value):
return data


def coroutine_function(value):
module_name, attr_path = value.rsplit(".", 1)
module = importlib.import_module(module_name)
function = getattr(module, attr_path)
if not asyncio.iscoroutinefunction(function):
raise ValueError(f"Not a coroutine (async) function: {value}")
return function


def main(argv=None):

parser = argparse.ArgumentParser(description=f"Kubernetes Web View v{__version__}")
@@ -116,6 +127,11 @@ def main(argv=None):
help="Comma-separated list of label columns per resource type; multiple entries separated by semicolon, e.g. 'pods=app,version;deployments=team'",
default={},
)
parser.add_argument(
"--oauth2-authorized-hook",
type=coroutine_function,
help="Optional hook (name of a coroutine like 'mymodule.myfunc') to process OAuth access token response (validate, log, ..)",
)

args = parser.parse_args(argv)


+ 6
- 0
kube_web/web.py View File

@@ -1045,6 +1045,12 @@ async def auth(request, handler):
expires_in = data.get("expires_in", ONE_WEEK)
expires = time.time() + expires_in
session = await get_session(request)
hook = request.app[CONFIG].oauth2_authorized_hook
if hook:
# the hook can store additional stuff in the session,
# deny access (raise exception), etc
if not await hook(data, session):
raise web.HTTPForbidden(text="Access Denied")
session["access_token"] = access_token
session["expires"] = expires
raise web.HTTPFound(location=original_url)

Loading…
Cancel
Save