From 8ee4c74da8bfe5e3531391be8ced73b54016e020 Mon Sep 17 00:00:00 2001 From: Peyton Duncan Date: Thu, 11 Jul 2024 16:19:32 -0500 Subject: [PATCH 1/5] New requirements, program runs --- Makefile | 21 +++++++++++++++++++++ app/main.py | 22 +++++++++++----------- app/models/info.py | 2 +- app/routes/admin.py | 16 ++++++++-------- app/routes/api.py | 14 +++++++------- app/routes/infra.py | 21 ++++++++++----------- app/routes/stripe.py | 12 ++++++------ app/routes/wallet.py | 10 +++++----- app/util/approve.py | 12 ++++++------ app/util/authentication.py | 6 +++--- app/util/database.py | 2 +- app/util/discord.py | 2 +- app/util/email.py | 2 +- app/util/settings.py | 37 ++++++++++++++++++++++++++----------- config.yml | 12 +++++++----- requirements-dev.in | 5 +++++ requirements-in.txt | 0 requirements.in | 7 +++++++ 18 files changed, 126 insertions(+), 77 deletions(-) create mode 100644 Makefile create mode 100644 requirements-dev.in create mode 100644 requirements-in.txt create mode 100644 requirements.in diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b0cd23a --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +.PHONYS: run deps dev + +venv: + virtualenv venv + +requirements-dev.txt: + pip-compile requirements-dev.in > requirements-dev.txt + +requirements.txt: + pip-compile requirements.in > requirements.txt + +dev-deps: requirements-dev.txt + pip install -r requirements-dev.txt + +deps: requirements.txt + pip install -r requirements.txt + +dev: venv requirements-dev.txt requirements.txt deps dev-deps + +run: + python3 app/main.py \ No newline at end of file diff --git a/app/main.py b/app/main.py index aa25fea..fea67ef 100644 --- a/app/main.py +++ b/app/main.py @@ -17,28 +17,28 @@ from sqlmodel import Session, select # Import data types -from app.models.user import DiscordModel, EthicsFormModel, UserModel, user_to_dict +from models.user import DiscordModel, EthicsFormModel, UserModel, user_to_dict # Import routes -from app.routes import admin, api, infra, stripe, wallet -from app.util.approve import Approve +from routes import admin, api, infra, stripe, wallet +from util.approve import Approve # Import middleware -from app.util.authentication import Authentication -from app.util.database import get_session, init_db -from app.util.discord import Discord +from util.authentication import Authentication +from util.database import get_session, init_db +from util.discord import Discord # Import error handling -from app.util.errors import Errors -from app.util.forms import Forms +from util.errors import Errors +from util.forms import Forms # Import the page rendering library -from app.util.kennelish import Kennelish +from util.kennelish import Kennelish # Import options -from app.util.settings import Settings +from util.settings import Settings -if Settings().telemetry.enable: +if Settings().telemetry and Settings().telemetry.enable: import sentry_sdk ### TODO: TEMP # os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "0" diff --git a/app/models/info.py b/app/models/info.py index 2651246..984fafb 100644 --- a/app/models/info.py +++ b/app/models/info.py @@ -3,7 +3,7 @@ from pydantic import BaseModel # Import data types -from app.models.user import PublicContact +from models.user import PublicContact class InfoModel(BaseModel): diff --git a/app/routes/admin.py b/app/routes/admin.py index 90a9afe..14f4f6c 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -7,19 +7,19 @@ from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from app.models.user import ( +from models.user import ( UserModel, UserModelMutable, user_to_dict, user_update_instance, ) -from app.util.approve import Approve -from app.util.authentication import Authentication -from app.util.database import get_session -from app.util.discord import Discord -from app.util.email import Email -from app.util.errors import Errors -from app.util.settings import Settings +from util.approve import Approve +from util.authentication import Authentication +from util.database import get_session +from util.discord import Discord +from util.email import Email +from util.errors import Errors +from util.settings import Settings logger = logging.getLogger(__name__) diff --git a/app/routes/api.py b/app/routes/api.py index 489a986..742f998 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -6,13 +6,13 @@ from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from app.models.info import InfoModel -from app.models.user import PublicContact, UserModel, user_to_dict, user_update_instance -from app.util.authentication import Authentication -from app.util.database import get_session -from app.util.errors import Errors -from app.util.forms import Forms, apply_fuzzy_parsing, transform_dict -from app.util.kennelish import Transformer +from models.info import InfoModel +from models.user import PublicContact, UserModel, user_to_dict, user_update_instance +from util.authentication import Authentication +from util.database import get_session +from util.errors import Errors +from util.forms import Forms, apply_fuzzy_parsing, transform_dict +from util.kennelish import Transformer logger = logging.getLogger(__name__) diff --git a/app/routes/infra.py b/app/routes/infra.py index 11276aa..3622861 100644 --- a/app/routes/infra.py +++ b/app/routes/infra.py @@ -4,18 +4,17 @@ from fastapi import APIRouter, Cookie, Depends, Request from fastapi.responses import FileResponse from fastapi.templating import Jinja2Templates +from models.info import InfoModel +from models.user import PublicContact, UserModel from sqlmodel import Session, select - -from app.models.info import InfoModel -from app.models.user import PublicContact, UserModel -from app.util.approve import Approve -from app.util.authentication import Authentication -from app.util.database import get_session -from app.util.discord import Discord -from app.util.email import Email -from app.util.errors import Errors -from app.util.limiter import RateLimiter -from app.util.settings import Settings +from util.approve import Approve +from util.authentication import Authentication +from util.database import get_session +from util.discord import Discord +from util.email import Email +from util.errors import Errors +from util.limiter import RateLimiter +from util.settings import Settings logger = logging.getLogger(__name__) diff --git a/app/routes/stripe.py b/app/routes/stripe.py index a99e72e..a1789cc 100644 --- a/app/routes/stripe.py +++ b/app/routes/stripe.py @@ -8,12 +8,12 @@ from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from app.models.user import UserModel, user_to_dict -from app.util.approve import Approve -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 +from models.user import UserModel, user_to_dict +from util.approve import Approve +from util.authentication import Authentication +from util.database import get_session +from util.errors import Errors +from util.settings import Settings templates = Jinja2Templates(directory="app/templates") diff --git a/app/routes/wallet.py b/app/routes/wallet.py index 4856b66..453d7a3 100644 --- a/app/routes/wallet.py +++ b/app/routes/wallet.py @@ -9,11 +9,11 @@ from sqlalchemy.orm import selectinload from sqlmodel import select -from app.models.info import InfoModel -from app.models.user import PublicContact, UserModel, user_to_dict -from app.util.authentication import Authentication -from app.util.database import get_session -from app.util.errors import Errors +from models.info import InfoModel +from models.user import PublicContact, UserModel, user_to_dict +from util.authentication import Authentication +from util.database import get_session +from util.errors import Errors router = APIRouter( prefix="/wallet", tags=["API", "MobileWallet"], responses=Errors.basic_http() diff --git a/app/util/approve.py b/app/util/approve.py index d4137c9..bad20ac 100644 --- a/app/util/approve.py +++ b/app/util/approve.py @@ -5,12 +5,12 @@ from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from app.models.user import UserModel -from app.util.database import engine -from app.util.discord import Discord -from app.util.email import Email -from app.util.horsepass import HorsePass -from app.util.settings import Settings +from models.user import UserModel +from util.database import engine +from util.discord import Discord +from util.email import Email +from util.horsepass import HorsePass +from util.settings import Settings logger = logging.getLogger() diff --git a/app/util/authentication.py b/app/util/authentication.py index 0f5c0f8..a8f5cd3 100644 --- a/app/util/authentication.py +++ b/app/util/authentication.py @@ -6,11 +6,11 @@ from fastapi.responses import RedirectResponse from jose import jwt -from app.models.user import UserModel +from models.user import UserModel # Import options and errors -from app.util.errors import Errors -from app.util.settings import Settings +from util.errors import Errors +from util.settings import Settings class Authentication: diff --git a/app/util/database.py b/app/util/database.py index 2b141a0..bdbed4e 100644 --- a/app/util/database.py +++ b/app/util/database.py @@ -4,7 +4,7 @@ from sqlmodel import Session, SQLModel, create_engine from sqlmodel.pool import StaticPool -from app.util.settings import Settings +from util.settings import Settings DATABASE_URL = Settings().database.url # TODO remove echo=True diff --git a/app/util/discord.py b/app/util/discord.py index 6d34759..9b3590e 100644 --- a/app/util/discord.py +++ b/app/util/discord.py @@ -2,7 +2,7 @@ import requests -from app.util.settings import Settings +from util.settings import Settings headers = { "Authorization": f"Bot {Settings().discord.bot_token.get_secret_value()}", diff --git a/app/util/email.py b/app/util/email.py index 03d001b..8e034aa 100644 --- a/app/util/email.py +++ b/app/util/email.py @@ -4,7 +4,7 @@ import commonmark -from app.util.settings import Settings +from util.settings import Settings email = Settings().email.email password = Settings().email.password.get_secret_value() diff --git a/app/util/settings.py b/app/util/settings.py index ba60e8c..f7ad706 100644 --- a/app/util/settings.py +++ b/app/util/settings.py @@ -30,6 +30,7 @@ def BitwardenConfig(settings: dict): ).stdout except Exception as e: logger.exception(e) + raise e bitwarden_settings = parse_json_to_dict(bitwarden_raw) bitwarden_mapping = { @@ -67,8 +68,8 @@ def BitwardenConfig(settings: dict): settings = dict() # Reads config from ../config/options.yml -here = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(here, "../../config/options.yml")) as f: +# here = os.path.abspath(os.path.dirname(__file__)) +with open("config.yml") as f: settings.update(yaml.load(f, Loader=yaml.FullLoader)) @@ -108,7 +109,10 @@ class DiscordConfig(BaseModel): enable: Optional[bool] = True -discord_config = DiscordConfig(**settings["discord"]) +if settings.get('discord'): + discord_config = DiscordConfig(**settings["discord"]) +else: + logger.warn("Missing discord config") class StripeConfig(BaseModel): @@ -196,7 +200,11 @@ class KeycloakConfig(BaseModel): relam: str -keycloak_config = KeycloakConfig(**settings["keycloak"]) +if settings.get('keycloak'): + keycloak_config = KeycloakConfig(**settings["keycloak"]) +else: + keycloak_config = None + logger.warn("Missing Keycloak Config") class TelemetryConfig(BaseModel): @@ -212,7 +220,11 @@ class DatabaseConfig(BaseModel): url: str -database_config = DatabaseConfig(**settings["database"]) +if settings.get('database'): + database_config = DatabaseConfig(**settings["database"]) +else: + database_config = None + logger.warn("Missing database config") class RedisConfig(BaseModel): @@ -220,8 +232,11 @@ class RedisConfig(BaseModel): port: int db: int - -redis_config = RedisConfig(**settings["redis"]) +if settings.get('redis'): + redis_config = RedisConfig(**settings["redis"]) +else: + redis_config = None + logger.warn("Missing redis config") class HttpConfig(BaseModel): @@ -245,9 +260,9 @@ class Settings(BaseSettings, metaclass=SingletonBaseSettingsMeta): stripe: StripeConfig = stripe_config email: EmailConfig = email_config jwt: JwtConfig = jwt_config - database: DatabaseConfig = database_config + database: DatabaseConfig = database_config or DatabaseConfig(url="sqlite:///:memory:") infra: InfraConfig = infra_config - redis: RedisConfig = redis_config + redis: RedisConfig = redis_config or RedisConfig(host="localhost", db=0, port=6379) http: HttpConfig = http_config - keycloak: KeycloakConfig = keycloak_config - telemetry: TelemetryConfig = telemetry_config + keycloak: Optional[KeycloakConfig] = keycloak_config + telemetry: Optional[TelemetryConfig] = telemetry_config diff --git a/config.yml b/config.yml index 44c5ec4..83c35b1 100644 --- a/config.yml +++ b/config.yml @@ -1,6 +1,6 @@ bws: project_id: "your_project_id" - enable: "true" + enable: False jwt: secret: "your_jwt_secret_key_here" # Ensure this is at least 32 characters long @@ -16,13 +16,13 @@ infra: horizon: "https://horizon.hackucf.org" discord: - client_id: "your_discord_client_id_here" + client_id: 0 secret: "your_discord_secret_here" redirect_base: "https://join.hackucf.org/api/oauth/?redir=" scope: "email identify guilds.join" bot_token: "your_discord_bot_token_here" - guild_id: "your_guild_id_here" - member_role: "your_member_role_id_here" + guild_id: 0 + member_role: 0 enable: true stripe: @@ -41,4 +41,6 @@ email: telemetry: url: "your_telemetry_url_here" - enable: true \ No newline at end of file + enable: false + +keycloak: diff --git a/requirements-dev.in b/requirements-dev.in new file mode 100644 index 0000000..b481047 --- /dev/null +++ b/requirements-dev.in @@ -0,0 +1,5 @@ +httpx +pre-commit +pytest +semgrep +pip-tools \ No newline at end of file diff --git a/requirements-in.txt b/requirements-in.txt new file mode 100644 index 0000000..e69de29 diff --git a/requirements.in b/requirements.in new file mode 100644 index 0000000..c9befdf --- /dev/null +++ b/requirements.in @@ -0,0 +1,7 @@ +requests +python-keycloak +alembic +pydantic +fastapi +stripe +sentry_sdk \ No newline at end of file From 3e04801154dadf8757b264bcf98eb329992bd2f5 Mon Sep 17 00:00:00 2001 From: Peyton Duncan Date: Thu, 11 Jul 2024 16:21:33 -0500 Subject: [PATCH 2/5] Updated dev docs for local getting started --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 066ba41..143f68c 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ This is to be replaced by Influx in the future, a more fleshed-out approach with ## Getting Started (local) ```py # Requires >= Python3.8 -python3 -m pip install -r requirements.txt -python3 index.py +make dev ``` ## Deploying From e37c9316294d02fb63e3e0311d8d2806838a24ad Mon Sep 17 00:00:00 2001 From: Peyton Duncan Date: Thu, 11 Jul 2024 15:00:43 -0700 Subject: [PATCH 3/5] Linting fixes --- Makefile | 2 +- app/main.py | 6 +++--- app/models/info.py | 3 +-- app/routes/admin.py | 5 ++--- app/routes/api.py | 5 ++--- app/routes/stripe.py | 3 +-- app/routes/wallet.py | 5 ++--- app/util/approve.py | 3 +-- app/util/authentication.py | 1 - app/util/database.py | 1 - app/util/discord.py | 1 - app/util/email.py | 1 - app/util/settings.py | 13 ++++++++----- 13 files changed, 21 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index b0cd23a..32b2121 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ requirements-dev.txt: requirements.txt: pip-compile requirements.in > requirements.txt - + dev-deps: requirements-dev.txt pip install -r requirements-dev.txt diff --git a/app/main.py b/app/main.py index fea67ef..df0f221 100644 --- a/app/main.py +++ b/app/main.py @@ -12,15 +12,15 @@ from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from jose import jwt -from requests_oauthlib import OAuth2Session -from sqlalchemy.orm import selectinload -from sqlmodel import Session, select # Import data types from models.user import DiscordModel, EthicsFormModel, UserModel, user_to_dict +from requests_oauthlib import OAuth2Session # Import routes from routes import admin, api, infra, stripe, wallet +from sqlalchemy.orm import selectinload +from sqlmodel import Session, select from util.approve import Approve # Import middleware diff --git a/app/models/info.py b/app/models/info.py index 984fafb..4859b40 100644 --- a/app/models/info.py +++ b/app/models/info.py @@ -1,9 +1,8 @@ from typing import List, Optional -from pydantic import BaseModel - # Import data types from models.user import PublicContact +from pydantic import BaseModel class InfoModel(BaseModel): diff --git a/app/routes/admin.py b/app/routes/admin.py index 14f4f6c..10d631e 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -4,15 +4,14 @@ from fastapi import APIRouter, Body, Cookie, Depends, Request, Response from fastapi.templating import Jinja2Templates from jose import jwt -from sqlalchemy.orm import selectinload -from sqlmodel import Session, select - from models.user import ( UserModel, UserModelMutable, user_to_dict, user_update_instance, ) +from sqlalchemy.orm import selectinload +from sqlmodel import Session, select from util.approve import Approve from util.authentication import Authentication from util.database import get_session diff --git a/app/routes/api.py b/app/routes/api.py index 742f998..92065e8 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -3,11 +3,10 @@ from typing import Optional from fastapi import APIRouter, Cookie, Depends, HTTPException, Request -from sqlalchemy.orm import selectinload -from sqlmodel import Session, select - from models.info import InfoModel from models.user import PublicContact, UserModel, user_to_dict, user_update_instance +from sqlalchemy.orm import selectinload +from sqlmodel import Session, select from util.authentication import Authentication from util.database import get_session from util.errors import Errors diff --git a/app/routes/stripe.py b/app/routes/stripe.py index a1789cc..f2d8c11 100644 --- a/app/routes/stripe.py +++ b/app/routes/stripe.py @@ -5,10 +5,9 @@ from fastapi import APIRouter, Cookie, Depends, HTTPException, Request from fastapi.responses import RedirectResponse from fastapi.templating import Jinja2Templates +from models.user import UserModel, user_to_dict from sqlalchemy.orm import selectinload from sqlmodel import Session, select - -from models.user import UserModel, user_to_dict from util.approve import Approve from util.authentication import Authentication from util.database import get_session diff --git a/app/routes/wallet.py b/app/routes/wallet.py index 453d7a3..677938a 100644 --- a/app/routes/wallet.py +++ b/app/routes/wallet.py @@ -6,11 +6,10 @@ import requests from airpress import PKPass from fastapi import APIRouter, Cookie, Depends, Request, Response -from sqlalchemy.orm import selectinload -from sqlmodel import select - from models.info import InfoModel from models.user import PublicContact, UserModel, user_to_dict +from sqlalchemy.orm import selectinload +from sqlmodel import select from util.authentication import Authentication from util.database import get_session from util.errors import Errors diff --git a/app/util/approve.py b/app/util/approve.py index bad20ac..2b97458 100644 --- a/app/util/approve.py +++ b/app/util/approve.py @@ -2,10 +2,9 @@ import os from keycloak import KeycloakAdmin +from models.user import UserModel from sqlalchemy.orm import selectinload from sqlmodel import Session, select - -from models.user import UserModel from util.database import engine from util.discord import Discord from util.email import Email diff --git a/app/util/authentication.py b/app/util/authentication.py index a8f5cd3..85b3cbf 100644 --- a/app/util/authentication.py +++ b/app/util/authentication.py @@ -5,7 +5,6 @@ from fastapi import Request, status from fastapi.responses import RedirectResponse from jose import jwt - from models.user import UserModel # Import options and errors diff --git a/app/util/database.py b/app/util/database.py index bdbed4e..f45cef6 100644 --- a/app/util/database.py +++ b/app/util/database.py @@ -3,7 +3,6 @@ from alembic.runtime import migration from sqlmodel import Session, SQLModel, create_engine from sqlmodel.pool import StaticPool - from util.settings import Settings DATABASE_URL = Settings().database.url diff --git a/app/util/discord.py b/app/util/discord.py index 9b3590e..d747057 100644 --- a/app/util/discord.py +++ b/app/util/discord.py @@ -1,7 +1,6 @@ import json import requests - from util.settings import Settings headers = { diff --git a/app/util/email.py b/app/util/email.py index 8e034aa..9f209d4 100644 --- a/app/util/email.py +++ b/app/util/email.py @@ -3,7 +3,6 @@ from email.mime.text import MIMEText import commonmark - from util.settings import Settings email = Settings().email.email diff --git a/app/util/settings.py b/app/util/settings.py index f7ad706..ff15f69 100644 --- a/app/util/settings.py +++ b/app/util/settings.py @@ -109,7 +109,7 @@ class DiscordConfig(BaseModel): enable: Optional[bool] = True -if settings.get('discord'): +if settings.get("discord"): discord_config = DiscordConfig(**settings["discord"]) else: logger.warn("Missing discord config") @@ -200,7 +200,7 @@ class KeycloakConfig(BaseModel): relam: str -if settings.get('keycloak'): +if settings.get("keycloak"): keycloak_config = KeycloakConfig(**settings["keycloak"]) else: keycloak_config = None @@ -220,7 +220,7 @@ class DatabaseConfig(BaseModel): url: str -if settings.get('database'): +if settings.get("database"): database_config = DatabaseConfig(**settings["database"]) else: database_config = None @@ -232,7 +232,8 @@ class RedisConfig(BaseModel): port: int db: int -if settings.get('redis'): + +if settings.get("redis"): redis_config = RedisConfig(**settings["redis"]) else: redis_config = None @@ -260,7 +261,9 @@ class Settings(BaseSettings, metaclass=SingletonBaseSettingsMeta): stripe: StripeConfig = stripe_config email: EmailConfig = email_config jwt: JwtConfig = jwt_config - database: DatabaseConfig = database_config or DatabaseConfig(url="sqlite:///:memory:") + database: DatabaseConfig = database_config or DatabaseConfig( + url="sqlite:///:memory:" + ) infra: InfraConfig = infra_config redis: RedisConfig = redis_config or RedisConfig(host="localhost", db=0, port=6379) http: HttpConfig = http_config From a76078d66f024f7e0002ac139df139e6421d562a Mon Sep 17 00:00:00 2001 From: Peyton Duncan Date: Fri, 12 Jul 2024 10:31:33 -0700 Subject: [PATCH 4/5] Fixed imports, test erroring due to expecting random side effects --- app/__init__.py | 0 app/main.py | 20 ++++++++++---------- app/models/info.py | 2 +- app/routes/admin.py | 16 ++++++++-------- app/routes/api.py | 14 +++++++------- app/routes/infra.py | 34 ++++++++++++++++++++-------------- app/routes/stripe.py | 12 ++++++------ app/routes/wallet.py | 10 +++++----- app/util/approve.py | 12 ++++++------ app/util/authentication.py | 6 +++--- app/util/database.py | 2 +- app/util/discord.py | 2 +- app/util/email.py | 2 +- 13 files changed, 69 insertions(+), 63 deletions(-) delete mode 100644 app/__init__.py diff --git a/app/__init__.py b/app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/main.py b/app/main.py index df0f221..fdd76f8 100644 --- a/app/main.py +++ b/app/main.py @@ -14,29 +14,29 @@ from jose import jwt # Import data types -from models.user import DiscordModel, EthicsFormModel, UserModel, user_to_dict +from .models.user import DiscordModel, EthicsFormModel, UserModel, user_to_dict from requests_oauthlib import OAuth2Session # Import routes -from routes import admin, api, infra, stripe, wallet +from .routes import admin, api, infra, stripe, wallet from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from util.approve import Approve +from .util.approve import Approve # Import middleware -from util.authentication import Authentication -from util.database import get_session, init_db -from util.discord import Discord +from .util.authentication import Authentication +from .util.database import get_session, init_db +from .util.discord import Discord # Import error handling -from util.errors import Errors -from util.forms import Forms +from .util.errors import Errors +from .util.forms import Forms # Import the page rendering library -from util.kennelish import Kennelish +from .util.kennelish import Kennelish # Import options -from util.settings import Settings +from .util.settings import Settings if Settings().telemetry and Settings().telemetry.enable: import sentry_sdk diff --git a/app/models/info.py b/app/models/info.py index 4859b40..4773eca 100644 --- a/app/models/info.py +++ b/app/models/info.py @@ -1,7 +1,7 @@ from typing import List, Optional # Import data types -from models.user import PublicContact +from ..models.user import PublicContact from pydantic import BaseModel diff --git a/app/routes/admin.py b/app/routes/admin.py index 10d631e..f3f2c1d 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -4,7 +4,7 @@ from fastapi import APIRouter, Body, Cookie, Depends, Request, Response from fastapi.templating import Jinja2Templates from jose import jwt -from models.user import ( +from ..models.user import ( UserModel, UserModelMutable, user_to_dict, @@ -12,13 +12,13 @@ ) from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from util.approve import Approve -from util.authentication import Authentication -from util.database import get_session -from util.discord import Discord -from util.email import Email -from util.errors import Errors -from util.settings import Settings +from ..util.approve import Approve +from ..util.authentication import Authentication +from ..util.database import get_session +from ..util.discord import Discord +from ..util.email import Email +from ..util.errors import Errors +from ..util.settings import Settings logger = logging.getLogger(__name__) diff --git a/app/routes/api.py b/app/routes/api.py index 92065e8..3666026 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -3,15 +3,15 @@ from typing import Optional from fastapi import APIRouter, Cookie, Depends, HTTPException, Request -from models.info import InfoModel -from models.user import PublicContact, UserModel, user_to_dict, user_update_instance +from ..models.info import InfoModel +from ..models.user import PublicContact, UserModel, user_to_dict, user_update_instance from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from util.authentication import Authentication -from util.database import get_session -from util.errors import Errors -from util.forms import Forms, apply_fuzzy_parsing, transform_dict -from util.kennelish import Transformer +from ..util.authentication import Authentication +from ..util.database import get_session +from ..util.errors import Errors +from ..util.forms import Forms, apply_fuzzy_parsing, transform_dict +from ..util.kennelish import Transformer logger = logging.getLogger(__name__) diff --git a/app/routes/infra.py b/app/routes/infra.py index 3622861..a870116 100644 --- a/app/routes/infra.py +++ b/app/routes/infra.py @@ -1,20 +1,22 @@ import logging from typing import Optional -from fastapi import APIRouter, Cookie, Depends, Request +from fastapi import APIRouter, Cookie, Depends, Request, HTTPException from fastapi.responses import FileResponse from fastapi.templating import Jinja2Templates -from models.info import InfoModel -from models.user import PublicContact, UserModel +from pathlib import Path from sqlmodel import Session, select -from util.approve import Approve -from util.authentication import Authentication -from util.database import get_session -from util.discord import Discord -from util.email import Email -from util.errors import Errors -from util.limiter import RateLimiter -from util.settings import Settings + +from ..models.info import InfoModel +from ..models.user import PublicContact, UserModel +from ..util.approve import Approve +from ..util.authentication import Authentication +from ..util.database import get_session +from ..util.discord import Discord +from ..util.email import Email +from ..util.errors import Errors +from ..util.limiter import RateLimiter +from ..util.settings import Settings logger = logging.getLogger(__name__) @@ -54,6 +56,10 @@ async def download_file( """ # Replace 'path/to/your/file.txt' with the actual path to your file file_path = "../HackUCF.ovpn" - return FileResponse( - file_path, filename="HackUCF.ovpn", media_type="application/octet-stream" - ) + if not Path(file_path).exists(): + ## Return 500 ISE + raise HTTPException(status_code=500, detail="HackUCF OpenVPN Config not Found") + else: + return FileResponse( + file_path, filename="HackUCF.ovpn", media_type="application/octet-stream" + ) diff --git a/app/routes/stripe.py b/app/routes/stripe.py index f2d8c11..f6ce6fc 100644 --- a/app/routes/stripe.py +++ b/app/routes/stripe.py @@ -5,14 +5,14 @@ from fastapi import APIRouter, Cookie, Depends, HTTPException, Request from fastapi.responses import RedirectResponse from fastapi.templating import Jinja2Templates -from models.user import UserModel, user_to_dict +from ..models.user import UserModel, user_to_dict from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from util.approve import Approve -from util.authentication import Authentication -from util.database import get_session -from util.errors import Errors -from util.settings import Settings +from ..util.approve import Approve +from ..util.authentication import Authentication +from ..util.database import get_session +from ..util.errors import Errors +from ..util.settings import Settings templates = Jinja2Templates(directory="app/templates") diff --git a/app/routes/wallet.py b/app/routes/wallet.py index 677938a..f447281 100644 --- a/app/routes/wallet.py +++ b/app/routes/wallet.py @@ -6,13 +6,13 @@ import requests from airpress import PKPass from fastapi import APIRouter, Cookie, Depends, Request, Response -from models.info import InfoModel -from models.user import PublicContact, UserModel, user_to_dict +from ..models.info import InfoModel +from ..models.user import PublicContact, UserModel, user_to_dict from sqlalchemy.orm import selectinload from sqlmodel import select -from util.authentication import Authentication -from util.database import get_session -from util.errors import Errors +from ..util.authentication import Authentication +from ..util.database import get_session +from ..util.errors import Errors router = APIRouter( prefix="/wallet", tags=["API", "MobileWallet"], responses=Errors.basic_http() diff --git a/app/util/approve.py b/app/util/approve.py index 2b97458..257b319 100644 --- a/app/util/approve.py +++ b/app/util/approve.py @@ -2,14 +2,14 @@ import os from keycloak import KeycloakAdmin -from models.user import UserModel +from ..models.user import UserModel from sqlalchemy.orm import selectinload from sqlmodel import Session, select -from util.database import engine -from util.discord import Discord -from util.email import Email -from util.horsepass import HorsePass -from util.settings import Settings +from .database import engine +from .discord import Discord +from .email import Email +from .horsepass import HorsePass +from .settings import Settings logger = logging.getLogger() diff --git a/app/util/authentication.py b/app/util/authentication.py index 85b3cbf..6408911 100644 --- a/app/util/authentication.py +++ b/app/util/authentication.py @@ -5,11 +5,11 @@ from fastapi import Request, status from fastapi.responses import RedirectResponse from jose import jwt -from models.user import UserModel +from ..models.user import UserModel # Import options and errors -from util.errors import Errors -from util.settings import Settings +from .errors import Errors +from .settings import Settings class Authentication: diff --git a/app/util/database.py b/app/util/database.py index f45cef6..f69e856 100644 --- a/app/util/database.py +++ b/app/util/database.py @@ -3,7 +3,7 @@ from alembic.runtime import migration from sqlmodel import Session, SQLModel, create_engine from sqlmodel.pool import StaticPool -from util.settings import Settings +from .settings import Settings DATABASE_URL = Settings().database.url # TODO remove echo=True diff --git a/app/util/discord.py b/app/util/discord.py index d747057..625807b 100644 --- a/app/util/discord.py +++ b/app/util/discord.py @@ -1,7 +1,7 @@ import json import requests -from util.settings import Settings +from .settings import Settings headers = { "Authorization": f"Bot {Settings().discord.bot_token.get_secret_value()}", diff --git a/app/util/email.py b/app/util/email.py index 9f209d4..c0d7093 100644 --- a/app/util/email.py +++ b/app/util/email.py @@ -3,7 +3,7 @@ from email.mime.text import MIMEText import commonmark -from util.settings import Settings +from .settings import Settings email = Settings().email.email password = Settings().email.password.get_secret_value() From 6fab30a19005c7d51846c445fe939e3433e243ef Mon Sep 17 00:00:00 2001 From: Peyton Duncan Date: Fri, 12 Jul 2024 10:39:28 -0700 Subject: [PATCH 5/5] Test Err Fixed --- app/routes/infra.py | 3 ++- tests/test_user.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/routes/infra.py b/app/routes/infra.py index a870116..cb6d485 100644 --- a/app/routes/infra.py +++ b/app/routes/infra.py @@ -43,6 +43,7 @@ async def get_root(): ], ) +ERR_VPN_CONFIG_NOT_FOUND = HTTPException(status_code=500, detail="HackUCF OpenVPN Config Not Found") @router.get("/openvpn") @Authentication.member @@ -58,7 +59,7 @@ async def download_file( file_path = "../HackUCF.ovpn" if not Path(file_path).exists(): ## Return 500 ISE - raise HTTPException(status_code=500, detail="HackUCF OpenVPN Config not Found") + raise ERR_VPN_CONFIG_NOT_FOUND else: return FileResponse( file_path, filename="HackUCF.ovpn", media_type="application/octet-stream" diff --git a/tests/test_user.py b/tests/test_user.py index cfb3f27..c1b24af 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -5,6 +5,7 @@ from sqlmodel import Session from app.models.user import UserModel +from app.routes.infra import ERR_VPN_CONFIG_NOT_FOUND # jwt: str @@ -17,8 +18,9 @@ def test_profile(mock_approve, client: TestClient, jwt: str): def test_openvpn(client: TestClient, jwt: str): - response = client.get("/infra/openvpn/", cookies={"token": jwt}) - assert response.status_code == 200 + response = client.get("/infra/openvpn", cookies={"token": jwt}) + assert response.status_code == 500 + assert response.json().get('detail') == ERR_VPN_CONFIG_NOT_FOUND.detail def test_db(client: TestClient, session: Session, jwt: str):