Skip to content

Commit

Permalink
Basic Auth Service
Browse files Browse the repository at this point in the history
  • Loading branch information
VVoruganti committed Mar 25, 2024
1 parent 257ae8a commit a3e9e56
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 17 deletions.
2 changes: 1 addition & 1 deletion api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ realtime = "^1.0.2"
psycopg = {extras = ["binary"], version = "^3.1.18"}
langchain = "^0.1.12"
langchain-openai = "^0.0.8"
httpx = "^0.27.0"

[tool.ruff.lint]
# from https://docs.astral.sh/ruff/linter/#rule-selection example
Expand Down
42 changes: 30 additions & 12 deletions api/src/main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import json
import logging
import os
import re
import uuid
from contextlib import asynccontextmanager
from typing import Optional, Sequence

import httpx
import sentry_sdk
from fastapi import (
APIRouter,
Expand Down Expand Up @@ -220,33 +222,49 @@ async def lifespan(app: FastAPI):
add_pagination(app)

USE_AUTH_SERVICE = os.getenv("USE_AUTH_SERVICE", "False").lower() == "true"
AUTH_SERVICE_URL = os.getenv("AUTH_SERVICE_URL", "http://localhost:8001")


# TODO make the API Token Validation Optional
class BearerTokenMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
authorization: Optional[str] = request.headers.get("Authorization")
if authorization:
scheme, _, token = authorization.partition(" ")
if scheme.lower() == "bearer":
if token == "default":
if scheme.lower() == "bearer" and token:
id_pattern = r"\/apps\/([^\/]+)"
name_pattern = r"\/apps\/name\/([^\/]+)|\/apps\/get_or_create\/([^\/]+)"
match_id = re.search(id_pattern, request.url.path)
match_name = re.search(name_pattern, request.url.path)
payload = {"token": token}
if match_name:
payload["name"] = match_name.group(1)
elif match_id:
payload["app_id"] = match_id.group(1)

res = httpx.get(
f"{AUTH_SERVICE_URL}/validate",
params=payload,
)
data = res.json()
if (
data["app_id"] or data["name"]
): # Anything that checks app_id if True is valid
return await call_next(request)
if data["token"]:
check_pattern = r"^\/apps$|^\/apps\/get_or_create"
match = re.search(check_pattern, request.url.path)
if match:
return await call_next(request)

return Response(content="Invalid token.", status_code=400)
# Here you can add your token validation logic
# For example, checking token validity, expiration, etc.
# If the token is valid, you let the request pass through:
else:
# If the scheme is not Bearer, you might want to either
# 1. Reject the request
# 2. Ignore and proceed with the next middleware or the request
# This example demonstrates rejecting the request:
return Response(
content="Invalid authentication scheme.", status_code=400
)

# If no Authorization header is present, you can choose to reject the request or let it pass
# This example demonstrates rejecting the request:
exclude_paths = ["/docs", "/redoc", "/openapi.json"]
if request.url.path in exclude_paths:
return await call_next(request)
return Response(content="Authorization header missing.", status_code=401)


Expand Down
33 changes: 29 additions & 4 deletions api/src/routers/apps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import os
import uuid
from typing import Optional

import httpx
from fastapi import APIRouter, HTTPException, Request
from sqlalchemy.ext.asyncio import AsyncSession

Expand Down Expand Up @@ -57,8 +60,30 @@ async def create_app(request: Request, app: schemas.AppCreate, db=db):
schemas.App: Created App object
"""

return await crud.create_app(db, app=app)
USE_AUTH_SERVICE = os.getenv("USE_AUTH_SERVICE", "False").lower() == "true"
if USE_AUTH_SERVICE:
AUTH_SERVICE_URL = os.getenv("AUTH_SERVICE_URL", "http://localhost:8001")
authorization: Optional[str] = request.headers.get("Authorization")
if authorization:
scheme, _, token = authorization.partition(" ")
if token is not None:
honcho_app = await crud.create_app(db, app=app)
if token == "default":
return honcho_app
res = httpx.put(
f"{AUTH_SERVICE_URL}/organizations",
json={
"id": str(honcho_app.id),
"name": honcho_app.name,
"token": token,
},
)
data = res.json()
if data:
return honcho_app
else:
honcho_app = await crud.create_app(db, app=app)
return honcho_app


@router.get("/get_or_create/{name}", response_model=schemas.App)
Expand All @@ -73,9 +98,9 @@ async def get_or_create_app(request: Request, name: str, db=db):
"""
print("name", name)
app = await crud.get_app_by_name(db, name=name)
app = await crud.get_app_by_name(db=db, name=name)
if app is None:
app = await crud.create_app(db, app=schemas.AppCreate(name=name))
app = await create_app(request=request, db=db, app=schemas.AppCreate(name=name))
return app


Expand Down

0 comments on commit a3e9e56

Please sign in to comment.