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

Fix for docker github workflow #251

Draft
wants to merge 7 commits into
base: dev
Choose a base branch
from
Draft
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
27 changes: 24 additions & 3 deletions .github/workflows/docker-build.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build Docker Image
name: Build Docker Image Test

on:
push:
Expand All @@ -7,6 +7,7 @@ on:
pull_request:
branches:
- main
- dev

jobs:
build:
Expand All @@ -22,5 +23,25 @@ jobs:
- name: Build Docker image
run: docker build . --target prod -t onboardlite

- name: Verify Docker image
run: docker run -e ONBOARD_ENV=dev --rm onboardlite echo "Docker image built successfully!"
- name: Run Docker container
run: docker run -d -p 8000:8000 --name onboardlite_container onboardlite

- name: sleep 10 seconds
run: sleep 10

- name: Wait for container to be ready
run: |
for i in {1..30}; do
if curl -s -v http://localhost:8000/; then
exit 0
fi
sleep 1
done
docker logs onboardlite_container
exit 1

- name: Verify homepage
run: curl -f -v http://localhost:8000/

- name: Stop and remove Docker container
run: docker stop onboardlite_container && docker rm onboardlite_container
15 changes: 15 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2024 Collegiate Cyber Defense Club
import logging
import os
import uuid
from typing import Optional
from urllib.parse import urlparse
Expand All @@ -25,6 +26,12 @@

# Import routes
from app.routes import admin, api, infra, stripe, wallet

# This check is a little hacky and needs to be documented in the dev environment set up
# If it's run under docker, the -e flag should set the env variable, but if its local you have to set it yourself
# Use 'export ENV=development' to set the env variable
if os.getenv("ENV") == "development":
from app.routes import dev_auth
from app.util.approve import Approve

# Import middleware
Expand Down Expand Up @@ -94,6 +101,14 @@ def global_context(request: Request):
app.include_router(wallet.router)
app.include_router(infra.router)

# This check is a little hacky and needs to be documented in the dev environment set up
# If it's run under docker, the -e flag should set the env variable, but if its local you have to set it yourself
# Use 'export ENV=development' to set the env variable
if os.getenv("ENV") == "development":
logger.warning("loading dev endpoints")
app.include_router(dev_auth.router)


# TODO figure out wtf this is used for
# Create the OpenStack SDK config.
# with open("clouds.yaml", "w", encoding="utf-8") as f:
Expand Down
130 changes: 130 additions & 0 deletions app/routes/dev_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import logging
import uuid

from fastapi import APIRouter, Depends, Form, Request, status
from fastapi.responses import HTMLResponse, RedirectResponse
from sqlmodel import Session, select

from app.models.user import (
DiscordModel,
EthicsFormModel, # Import the EthicsFormModel
UserModel,
)
from app.util.authentication import Authentication
from app.util.database import get_session
from app.util.errors import Errors
from app.util.settings import Settings

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/dev", tags=["API"], responses=Errors.basic_http())

# Hard-coded users
hardcoded_users = [
{"id": uuid.UUID("00000000-0000-0000-0000-000000000001"), "discord_id": "000000000001", "first_name": "Admin User", "sudo": True, "did_pay_dues": True, "ethics_form": {"signtime": 1}},
{"id": uuid.UUID("00000000-0000-0000-0000-000000000002"), "discord_id": "000000000002", "first_name": "Dues Paying Member", "sudo": False, "did_pay_dues": True, "ethics_form": {"signtime": 1}},
{
"id": uuid.UUID("00000000-0000-0000-0000-000000000003"),
"discord_id": "000000000003",
"first_name": "Ethics Form Filled Out, No Payment",
"sudo": False,
"did_pay_dues": False,
"ethics_form": {"signtime": 1},
},
{
"id": uuid.UUID("00000000-0000-0000-0000-000000000004"),
"discord_id": "000000000004",
"first_name": "No Activity Beyond Account Creation 1",
"sudo": False,
"did_pay_dues": False,
"ethics_form": {"signtime": 0},
},
{
"id": uuid.UUID("00000000-0000-0000-0000-000000000005"),
"discord_id": "000000000005",
"first_name": "No Activity Beyond Account Creation 2",
"sudo": False,
"did_pay_dues": False,
"ethics_form": {"signtime": 0},
},
]


def create_hardcoded_users(session: Session):
for user_data in hardcoded_users:
statement = select(UserModel).where(UserModel.id == user_data["id"])
result = session.exec(statement).one_or_none()
if not result:
ethics_form = EthicsFormModel(signtime=user_data["ethics_form"]["signtime"])
user = UserModel(
id=user_data["id"], discord_id=user_data["discord_id"], name=user_data["first_name"], sudo=user_data["sudo"], did_pay_dues=user_data["did_pay_dues"], ethics_form=ethics_form
)
discord_user = DiscordModel(username=f"devuser-{user_data['first_name']}", email=f"devuser-{user_data['id']}@mail.com", user_id=user_data["id"], user=user)
session.add(user)
session.add(discord_user)
session.commit()
session.refresh(user)
session.refresh(discord_user)


@router.get("/user/", response_class=HTMLResponse)
async def create_dev_user(request: Request, session: Session = Depends(get_session), sudo: bool = False):
if request.client.host not in ["127.0.0.1", "localhost"]:
return Errors.generate(
request,
403,
"Forbidden",
essay="This endpoint is only available on localhost.",
)

create_hardcoded_users(session)

return """
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/hackucf.css">
</head>
<body>
<form action="/dev/select_user/" method="post">
<label for="user">Select User:</label>
<select name="user_id" id="user">
<option value="00000000-0000-0000-0000-000000000001">Admin User</option>
<option value="00000000-0000-0000-0000-000000000002">Dues Paying Member</option>
<option value="00000000-0000-0000-0000-000000000003">Ethics Form Filled Out, No Payment</option>
<option value="00000000-0000-0000-0000-000000000004">No Activity Beyond Account Creation 1</option>
<option value="00000000-0000-0000-0000-000000000005">No Activity Beyond Account Creation 2</option>
</select>
<input type="submit" value="Login">
</form>
</body>
</html>
"""


@router.post("/select_user/")
async def select_user(request: Request, user_id: str = Form(...), session: Session = Depends(get_session)):
statement = select(UserModel).where(UserModel.id == uuid.UUID(user_id))
user = session.exec(statement).one_or_none()

if not user:
return Errors.generate(
request,
404,
"User not found",
essay="The selected user does not exist.",
)

# Create JWT token for the user
bearer = Authentication.create_jwt(user)
rr = RedirectResponse("/profile", status_code=status.HTTP_302_FOUND)
max_age = Settings().jwt.lifetime_sudo if user.sudo else Settings().jwt.lifetime_user
rr.set_cookie(
key="token",
value=bearer,
httponly=True,
samesite="lax",
secure=False,
max_age=max_age,
)
Comment on lines +121 to +128

Check warning

Code scanning / CodeQL

Failure to use secure cookies Medium

Cookie is added without the Secure attribute properly set.

return rr
Loading