Skip to content

Commit

Permalink
feat(admin): initial attempts to utilize proxy authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
imnotjames committed Apr 4, 2024
1 parent 0042a49 commit 0d96f66
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
14 changes: 12 additions & 2 deletions admin/src/portr_admin/apis/security.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import Annotated
from fastapi import Cookie, Depends, Header
from fastapi import Depends, Header, Request

from portr_admin.models.auth import Session
from portr_admin.models.user import Role, TeamUser, User
from portr_admin.services.user import get_or_create_user
from portr_admin.utils.exception import PermissionDenied


Expand All @@ -11,8 +12,17 @@ class NotAuthenticated(Exception):


async def get_current_user(
portr_session: Annotated[str | None, Cookie()] = None,
request: Request
) -> User:
# TODO: use header from config
# TODO: only use header from config if matching host
proxy_auth_email = request.headers.get("Remote-Email")

if proxy_auth_email:
return await get_or_create_user(proxy_auth_email)

portr_session = request.cookies.get("portr_session")

if portr_session is None:
raise NotAuthenticated

Expand Down
13 changes: 5 additions & 8 deletions admin/src/portr_admin/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ async def lifespan(app: FastAPI):

@app.get("/")
async def render_index_template(
request: Request,
portr_session: Annotated[str | None, Cookie()] = None,
request: Request
):
try:
user: User = await get_current_user(portr_session)
user: User = await get_current_user(request)
except NotAuthenticated:
return templates.TemplateResponse(
request=request,
Expand All @@ -67,11 +66,10 @@ async def render_index_template(
@app.get("/new-team")
@app.get("/instance-settings")
async def render_index_template_for_setup_route(
request: Request,
portr_session: Annotated[str | None, Cookie()] = None,
request: Request
):
try:
user = await get_current_user(portr_session)
user = await get_current_user(request)
if not user.is_superuser:
return RedirectResponse(url="/")
except NotAuthenticated:
Expand All @@ -98,10 +96,9 @@ async def render_index_template_for_setup_route(
async def render_index_template_for_team_routes(
request: Request,
team: str,
portr_session: Annotated[str | None, Cookie()] = None,
):
try:
user: User = await get_current_user(portr_session)
user: User = await get_current_user(request)
except NotAuthenticated:
next_url = request.url.path + "?" + request.url.query
next_url_encoded = urllib.parse.urlencode({"next": next_url})
Expand Down
35 changes: 25 additions & 10 deletions admin/src/portr_admin/services/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@ class EmailFetchError(ServiceError):
pass


async def get_or_create_user(email: str):
is_first_user = not (await User.filter().exists())

if is_first_user:
# If this is the first user we can create them
await User.create(
email=email,
is_superuser=True,
)

user = await User.get_or_none(email=email)

if not user:
raise UserNotFoundError("User does not exist yet")

is_user_on_team = await TeamUser.filter(user__email=email).exists()

if not user.is_superuser and not is_user_on_team:
# This user MUST be part of a team to authenticate UNLESS they're a superuser
raise UserNotFoundError("User not part of any team")

return user


@transactions.atomic()
async def get_or_create_user_from_github(code: str):
client = GithubOauth(
Expand All @@ -35,16 +59,7 @@ async def get_or_create_user_from_github(code: str):
if not github_user["email"]:
raise EmailFetchError("No verified email found")

is_superuser = await User.filter().count() == 0

if not is_superuser:
if not await TeamUser.filter(user__email=github_user["email"]).exists():
raise UserNotFoundError("User not part of any team")

user, _ = await User.get_or_create(
email=github_user["email"],
defaults={"is_superuser": is_superuser},
)
user = await get_or_create_user(github_user["email"])

github_user_obj, created = await GithubUser.get_or_create(
user=user,
Expand Down

0 comments on commit 0d96f66

Please sign in to comment.