Skip to content

Commit

Permalink
Merge branch 'reworked-config'
Browse files Browse the repository at this point in the history
  • Loading branch information
jontyms committed Mar 19, 2024
2 parents 8f4953b + 32af788 commit a159728
Show file tree
Hide file tree
Showing 15 changed files with 350 additions and 185 deletions.
18 changes: 9 additions & 9 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
# Options for Onboard.
bws:
project_id: ""
enable: ""
jwt:
secret:
algorithm: "HS256"
lifetime: # (in seconds)
user: 9072000 # 15 weeks
sudo: 86400 # 1 day
lifetime_user: 9072000 # 15 weeks
lifetime_sudo: 86400 # 1 day

http:
domain: join.hackucf.org

infra:
wifi: ""
horizon: "https://horizon.hackucf.org"
ad:
application_credential_id:
application_credential_secret:
application_credential_id:
application_credential_secret:
tf_directory: "./"

discord:
Expand All @@ -31,9 +32,8 @@ stripe:
api_key: ""
webhook_secret: ""
price_id: ""
url:
success: "https://join.hackucf.org/final/"
failure: "https://join.hackucf.org/pay/"
url_success: "https://join.hackucf.org/final/"
url_failure: "https://join.hackucf.org/pay/"

aws:
dynamodb:
Expand Down
67 changes: 36 additions & 31 deletions index.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,22 @@
from util.authentication import Authentication
# Import error handling
from util.errors import Errors
from util.forms import Forms
# Import the page rendering library
from util.kennelish import Kennelish
# Import options
from util.options import Options
from util.settings import Settings

### TODO: TEMP
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "0"
###

logging.basicConfig(level=logging.DEBUG,

logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger(__name__)

options = Options.fetch()

# Initiate FastAPI.
app = FastAPI()
Expand All @@ -60,9 +61,9 @@
f"""clouds:
hackucf_infra:
auth:
auth_url: {options.get('infra', {}).get('horizon', '')}:5000
application_credential_id: {options.get('infra', {}).get('ad', {}).get('application_credential_id', '')}
application_credential_secret: {options.get('infra', {}).get('ad', {}).get('application_credential_secret', '')}
auth_url: {Settings().infra.horizon}:5000
application_credential_id: {Settings().infra.application_credential_id}
application_credential_secret: {Settings().infra.application_credential_secret.get_secret_value()}
region_name: "hack-ucf-0"
interface: "public"
identity_api_version: 3
Expand All @@ -86,8 +87,8 @@ async def index(request: Request, token: Optional[str] = Cookie(None)):
try:
user_jwt = jwt.decode(
token,
options.get("jwt").get("secret"),
algorithms=options.get("jwt").get("algorithm"),
Settings().jwt.secret.get_secret_value(),
algorithms=Settings().jwt.algorithm,
)
is_full_member: bool = user_jwt.get("is_full_member", False)
is_admin: bool = user_jwt.get("sudo", False)
Expand Down Expand Up @@ -119,15 +120,13 @@ async def index(request: Request, token: Optional[str] = Cookie(None)):
async def oauth_transformer(redir: str = "/join/2"):
# Open redirect check
hostname = urlparse(redir).netloc
if hostname != "" and hostname != options.get("http", {}).get(
"domain", "my.hackucf.org"
):
if hostname != "" and hostname != Settings().http.domain:
redir = "/join/2"

oauth = OAuth2Session(
options.get("discord").get("client_id"),
redirect_uri=options.get("discord").get("redirect_base") + "_redir",
scope=options.get("discord").get("scope"),
Settings().discord.client_id,
redirect_uri=Settings().discord.redirect_base + "_redir",
scope=Settings().discord.scope,
)
authorization_url, state = oauth.authorization_url(
"https://discord.com/api/oauth2/authorize"
Expand Down Expand Up @@ -156,17 +155,15 @@ async def oauth_transformer_new(
):
# AWS dependencies
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)

# Open redirect check
if redir == "_redir":
redir = redir_endpoint

hostname = urlparse(redir).netloc

if hostname != "" and hostname != options.get("http", {}).get(
"domain", "my.hackucf.org"
):
if hostname != "" and hostname != Settings().http.domain:
redir = "/join/2"

if code is None:
Expand All @@ -179,15 +176,15 @@ async def oauth_transformer_new(

# Get data from Discord
oauth = OAuth2Session(
options.get("discord").get("client_id"),
redirect_uri=options.get("discord").get("redirect_base") + "_redir",
scope=options.get("discord")["scope"],
Settings().discord.client_id,
redirect_uri=Settings().discord.redirect_base + "_redir",
scope=Settings().discord.scope,
)

token = oauth.fetch_token(
"https://discord.com/api/oauth2/token",
client_id=options.get("discord").get("client_id"),
client_secret=options.get("discord").get("secret"),
client_id=Settings().discord.client_id,
client_secret=Settings().discord.secret.get_secret_value(),
# authorization_response=code
code=code,
)
Expand Down Expand Up @@ -235,20 +232,20 @@ async def oauth_transformer_new(
# Make user join the Hack@UCF Discord, if it's their first rodeo.
discord_id = str(discordData["id"])
headers = {
"Authorization": f"Bot {options.get('discord', {}).get('bot_token')}",
"Authorization": f"Bot {Settings().discord.bot_token.get_secret_value()}",
"Content-Type": "application/json",
"X-Audit-Log-Reason": "Hack@UCF OnboardLite Bot",
}
put_join_guild = {"access_token": token["access_token"]}
requests.put(
f"https://discordapp.com/api/guilds/{options.get('discord', {}).get('guild_id')}/members/{discord_id}",
f"https://discordapp.com/api/guilds/{Settings().discord.guild_id}/members/{discord_id}",
headers=headers,
data=json.dumps(put_join_guild),
)

data = {
"id": member_id,
"discord_id": int(discordData["id"]),
"discord_id": discordData["id"],
"discord": {
"email": discordData["email"],
"mfa": discordData["mfa_enabled"],
Expand Down Expand Up @@ -290,8 +287,8 @@ async def oauth_transformer_new(
}
bearer = jwt.encode(
jwtData,
options.get("jwt").get("secret"),
algorithm=options.get("jwt").get("algorithm"),
Settings().jwt.secret.get_secret_value(),
algorithm=Settings().jwt.algorithm,
)
rr = RedirectResponse(redir, status_code=status.HTTP_302_FOUND)
rr.set_cookie(key="token", value=bearer)
Expand Down Expand Up @@ -329,7 +326,7 @@ async def profile(
):
# Get data from DynamoDB
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)

user_data = table.get_item(Key={"id": user_jwt.get("id")}).get("Item", None)

Expand All @@ -356,12 +353,20 @@ async def forms(
):
# AWS dependencies
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)

if num == "1":
return RedirectResponse("/join/", status_code=status.HTTP_302_FOUND)
try:
data = Forms.get_form_body(num)
except Exception:
return Errors.generate(
request,
404,
"Form not found",
essay="This form does not exist.",
)

data = Options.get_form_body(num)

# Get data from DynamoDB
user_data = table.get_item(Key={"id": user_jwt.get("id")}).get("Item", None)
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ pre-commit==3.6.2
pyasn1==0.5.1
pyasn1-modules==0.3.0
pycparser==2.21
pydantic==1.10.10
pyOpenSSL==23.2.0
pydantic==2.6.4
pydantic_settings==2.2.1
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-jose==3.3.0
Expand Down
30 changes: 14 additions & 16 deletions routes/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
from util.discord import Discord
from util.email import Email
from util.errors import Errors
from util.options import Options

options = Options.fetch()
from util.settings import Settings

templates = Jinja2Templates(directory="templates")

Expand All @@ -30,8 +28,8 @@ async def admin(request: Request, token: Optional[str] = Cookie(None)):
"""
payload = jwt.decode(
token,
options.get("jwt").get("secret"),
algorithms=options.get("jwt").get("algorithm"),
Settings().jwt.secret.get_secret_value(),
algorithms=Settings().jwt.algorithm,
)
return templates.TemplateResponse(
"admin_searcher.html",
Expand Down Expand Up @@ -66,7 +64,7 @@ async def get_infra(

# Get user data
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)

user_data = table.get_item(Key={"id": member_id}).get("Item", None)

Expand All @@ -75,16 +73,16 @@ async def get_infra(
We are happy to grant you Hack@UCF Private Cloud access!
These credentials can be used to the Hack@UCF Private Cloud. This can be accessed at {options.get('infra', {}).get('horizon')} while on the CyberLab WiFi.
These credentials can be used to the Hack@UCF Private Cloud. This can be accessed at {Settings().infra.horizon} while on the CyberLab WiFi.
```
Username: {creds.get('username', 'Not Set')}
Password: {creds.get('password', f"Please visit https://{options.get('http', {}).get('domain')}/profile and under Danger Zone, reset your Infra creds.")}
Password: {creds.get('password', f"Please visit https://{Settings().http.domain}/profile and under Danger Zone, reset your Infra creds.")}
```
By using the Hack@UCF Infrastructure, you agree to the following EULA located at https://help.hackucf.org/misc/eula
The password for the `Cyberlab` WiFi is currently `{options.get('infra', {}).get('wifi')}`, but this is subject to change (and we'll let you know when that happens).
The password for the `Cyberlab` WiFi is currently `{Settings().infra.wifi}`, but this is subject to change (and we'll let you know when that happens).
Happy Hacking,
- Hack@UCF Bot
Expand Down Expand Up @@ -112,7 +110,7 @@ async def get_refresh(
Approve.approve_member(member_id)

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
data = table.get_item(Key={"id": member_id}).get("Item", None)

if not data:
Expand All @@ -135,7 +133,7 @@ async def admin_get_single(
return {"data": {}, "error": "Missing ?member_id"}

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
data = table.get_item(Key={"id": member_id}).get("Item", None)

if not data:
Expand All @@ -159,7 +157,7 @@ async def admin_get_snowflake(
return {"data": {}, "error": "Missing ?discord_id"}

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
data = table.scan(FilterExpression=Attr("discord_id").eq(str(discord_id))).get(
"Items"
)
Expand Down Expand Up @@ -193,7 +191,7 @@ async def admin_post_discord_message(
return {"data": {}, "error": "Missing ?member_id"}

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
data = table.get_item(Key={"id": member_id}).get("Item", None)

if not data:
Expand Down Expand Up @@ -222,7 +220,7 @@ async def admin_edit(
member_id = input_data.id

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
old_data = table.get_item(Key={"id": member_id}).get("Item", None)

if not old_data:
Expand Down Expand Up @@ -252,7 +250,7 @@ async def admin_list(request: Request, token: Optional[str] = Cookie(None)):
API endpoint that dumps all users as JSON.
"""
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
data = table.scan().get("Items", None)
return {"data": data}

Expand All @@ -264,7 +262,7 @@ async def admin_list_csv(request: Request, token: Optional[str] = Cookie(None)):
API endpoint that dumps all users as CSV.
"""
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(options.get("aws").get("dynamodb").get("table"))
table = dynamodb.Table(Settings().aws.table)
data = table.scan().get("Items", None)

output = "Membership ID, First Name, Last Name, NID, Is Returning, Gender, Major, Class Standing, Shirt Size, Discord Username, Experience, Cyber Interests, Event Interest, Is C3 Interest, Comments, Ethics Form Timestamp, Minecraft, Infra Email\n"
Expand Down
Loading

0 comments on commit a159728

Please sign in to comment.