Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication callback #12

Merged
merged 7 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
DEPLOYMENT=development
PADDLES_URL=http://localhost:8080
PULPITO_URL=http://localhost:8081

# Github Related Stuff
GH_CLIENT_ID=
GH_CLIENT_SECRET=
GH_AUTHORIZATION_BASE_URL='https://github.com/login/oauth/authorize'
GH_TOKEN_URL='https://github.com/login/oauth/access_token'
GH_FETCH_MEMBERSHIP_URL='https://api.github.com/user/memberships/orgs/ceph'

#Session Related Stuff
## SESSION_SECRET_KEY is used to encrypt session data
## and it's prod value should be kept secret.
SESSION_SECRET_KEY=my-secret-key
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@ A REST API to execute [teuthology commands](https://docs.ceph.com/projects/teuth
#### Option 1: (teuthology docker setup)

1. Clone [teuthology](https://github.com/ceph/teuthology) and [teuthology-api](https://github.com/VallariAg/teuthology-api).
2. Add the following to [teuthology's docker-compose](https://github.com/ceph/teuthology/blob/main/docs/docker-compose/docker-compose.yml) services.
2. Rename `.env.dev` file to `.env`.
3. Configure secrets:

3.1. Create a Github OAuth Application by following [these](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) instructions. Set "Homepage URL" as `http://localhost:8082/` and "Authorization callback URL" as `http://localhost:8082/login/callback/`.

3.2. Ensure [ceph](https://github.com/ceph) belongs in your public list of organizations[[ref](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/about-organization-membership)]. By default your membership is set private, change that to public by following [these](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/publicizing-or-hiding-organization-membership) steps.

3.3. Save `CLIENT_ID` and `CLIENT_SECRET` from your Github OAuth App to your local `.env` file as `GH_CLIENT_ID` and `GH_CLIENT_SECRET`.

4. Add the following to [teuthology's docker-compose](https://github.com/ceph/teuthology/blob/main/docs/docker-compose/docker-compose.yml) services.
```
teuthology_api:
build:
Expand All @@ -21,7 +30,7 @@ A REST API to execute [teuthology commands](https://docs.ceph.com/projects/teuth
- teuthology
- paddles
```
3. Follow teuthology development setup instructions from [here](https://github.com/ceph/teuthology/tree/main/docs/docker-compose).
5. Follow teuthology development setup instructions from [here](https://github.com/ceph/teuthology/tree/main/docs/docker-compose).

## Documentation

Expand Down
4 changes: 3 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

DEPLOYMENT = os.getenv("DEPLOYMENT")
SESSION_SECRET_KEY = os.getenv("SESSION_SECRET_KEY")
PULPITO_URL = os.getenv("PULPITO_URL")
PADDLES_URL = os.getenv("PADDLES_URL")

log = logging.getLogger(__name__)
app = FastAPI()
Expand All @@ -26,7 +28,7 @@ def read_root(request: Request):
if DEPLOYMENT == "development":
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_origins=[PULPITO_URL, PADDLES_URL],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
Expand Down
16 changes: 14 additions & 2 deletions src/routes/login.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import os
from fastapi import APIRouter, HTTPException, Request
from starlette.responses import RedirectResponse
from fastapi.responses import RedirectResponse
from dotenv import load_dotenv
import httpx

Expand All @@ -12,6 +12,7 @@
GH_AUTHORIZATION_BASE_URL = os.getenv("GH_AUTHORIZATION_BASE_URL")
GH_TOKEN_URL = os.getenv("GH_TOKEN_URL")
GH_FETCH_MEMBERSHIP_URL = os.getenv("GH_FETCH_MEMBERSHIP_URL")
PULPITO_URL = os.getenv("PULPITO_URL")

log = logging.getLogger(__name__)
router = APIRouter(
Expand All @@ -27,6 +28,8 @@ async def github_login():
GET route for /login, (If first time) will redirect to github login page
where you should authorize the app to gain access.
"""
if not GH_AUTHORIZATION_BASE_URL or not GH_CLIENT_ID:
return HTTPException(status_code=500, detail="Environment secrets are missing.")
scope = "read:org"
return RedirectResponse(
f"{GH_AUTHORIZATION_BASE_URL}?client_id={GH_CLIENT_ID}&scope={scope}",
Expand Down Expand Up @@ -82,4 +85,13 @@ async def handle_callback(code: str, request: Request):
"access_token": token,
}
request.session["user"] = data
return RedirectResponse(url="/")
cookie_data = {
"username": data["username"],
"avatar_url": response_org_dic.get("user", {}).get("avatar_url"),
}
cookie = "; ".join(
[f"{str(key)}={str(value)}" for key, value in cookie_data.items()]
)
response = RedirectResponse(PULPITO_URL)
response.set_cookie(key="GH_USER", value=cookie)
return response
7 changes: 5 additions & 2 deletions src/routes/logout.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import logging
import logging, os
from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import RedirectResponse

PULPITO_URL = os.getenv("PULPITO_URL")
log = logging.getLogger(__name__)

router = APIRouter(
prefix="/logout",
tags=["logout"],
Expand All @@ -17,7 +20,7 @@ def logout(request: Request):
user = request.session.get("user")
if user:
request.session.pop("user", None)
return {"logout": "success"}
return RedirectResponse(PULPITO_URL)
log.warning("No session found, probably already logged out.")
raise HTTPException(
status_code=204, detail="No session found, probably already logged out."
Expand Down
Loading