mirror of
https://github.com/MichaByte/OnBoard-Live.git
synced 2025-12-06 17:13:40 -05:00
fix security issue and run black
This commit is contained in:
parent
3d08445e0f
commit
75882ddccb
1 changed files with 74 additions and 7 deletions
|
|
@ -3,10 +3,12 @@ import hmac
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
from datetime import datetime
|
||||||
from random import choice
|
from random import choice
|
||||||
from secrets import token_hex
|
from secrets import token_hex
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
|
import cv2
|
||||||
import httpx
|
import httpx
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
|
|
@ -19,6 +21,7 @@ from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
from prisma import Prisma
|
from prisma import Prisma
|
||||||
from slack_bolt.adapter.fastapi.async_handler import AsyncSlackRequestHandler
|
from slack_bolt.adapter.fastapi.async_handler import AsyncSlackRequestHandler
|
||||||
from slack_bolt.async_app import AsyncAck, AsyncApp
|
from slack_bolt.async_app import AsyncAck, AsyncApp
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
load_dotenv(dotenv_path="./.env")
|
load_dotenv(dotenv_path="./.env")
|
||||||
|
|
||||||
|
|
@ -30,6 +33,15 @@ scheduler = AsyncIOScheduler()
|
||||||
FERNET = Fernet(os.environ["FERNET_KEY"])
|
FERNET = Fernet(os.environ["FERNET_KEY"])
|
||||||
|
|
||||||
|
|
||||||
|
def get_recording_duration(timestamp, stream_key):
|
||||||
|
vid = cv2.VideoCapture(
|
||||||
|
f"/home/onboard/recordings/{stream_key}/{datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%fZ').strftime('%Y-%m-%d_%H-%M-%S-%f')}.mp4"
|
||||||
|
)
|
||||||
|
return int(
|
||||||
|
(vid.get(cv2.CAP_PROP_FRAME_COUNT) / vid.get(cv2.CAP_PROP_FPS)) / 60
|
||||||
|
) # seconds to minutes
|
||||||
|
|
||||||
|
|
||||||
def verify_gh_signature(payload_body, secret_token, signature_header):
|
def verify_gh_signature(payload_body, secret_token, signature_header):
|
||||||
"""Verify that the payload was sent from GitHub by validating SHA256.
|
"""Verify that the payload was sent from GitHub by validating SHA256.
|
||||||
|
|
||||||
|
|
@ -54,7 +66,14 @@ def verify_gh_signature(payload_body, secret_token, signature_header):
|
||||||
|
|
||||||
async def get_recording_list(stream_key: str) -> List[str]:
|
async def get_recording_list(stream_key: str) -> List[str]:
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
return [recording["start"] for recording in (await client.get(f"http://localhost:9997/v3/recordings/get/{stream_key}")).json()["segments"]]
|
return [
|
||||||
|
recording["start"]
|
||||||
|
for recording in (
|
||||||
|
await client.get(
|
||||||
|
f"http://localhost:9997/v3/recordings/get/{stream_key}"
|
||||||
|
)
|
||||||
|
).json()["segments"]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
async def update_active():
|
async def update_active():
|
||||||
|
|
@ -167,7 +186,19 @@ bolt_handler = AsyncSlackRequestHandler(bolt)
|
||||||
@api.get("/auth/github/login")
|
@api.get("/auth/github/login")
|
||||||
async def github_redirect(request: Request):
|
async def github_redirect(request: Request):
|
||||||
return RedirectResponse(
|
return RedirectResponse(
|
||||||
f"https://github.com/login/oauth/authorize?client_id={os.environ['GH_CLIENT_ID']}&redirect_uri=https://live.onboard.hackclub.com/auth/github/callback&scopes=read:user&state={request.query_params['state']}"
|
str(
|
||||||
|
URL.build(
|
||||||
|
scheme="https",
|
||||||
|
host="github.com",
|
||||||
|
path="/login/oauth/authorize",
|
||||||
|
query={
|
||||||
|
"client_id": os.environ["GH_CLIENT_ID"],
|
||||||
|
"redirect_uri": "https://live.onboard.hackclub.com/auth/github/callback",
|
||||||
|
"scopes": "read:user",
|
||||||
|
"state": request.query_params["state"],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -177,7 +208,9 @@ async def github_callback(request: Request):
|
||||||
state: str = request.query_params["state"]
|
state: str = request.query_params["state"]
|
||||||
user_id, pr_id = FERNET.decrypt(bytes.fromhex(state)).decode().split("+")
|
user_id, pr_id = FERNET.decrypt(bytes.fromhex(state)).decode().split("+")
|
||||||
db_user = await db.user.find_first_or_raise(where={"slack_id": user_id})
|
db_user = await db.user.find_first_or_raise(where={"slack_id": user_id})
|
||||||
user_stream_key = (await db.stream.find_first_or_raise(where={"user_id": db_user.id})).key
|
user_stream_key = (
|
||||||
|
await db.stream.find_first_or_raise(where={"user_id": db_user.id})
|
||||||
|
).key
|
||||||
db_pr = await db.pullrequest.find_first_or_raise(where={"github_id": int(pr_id)})
|
db_pr = await db.pullrequest.find_first_or_raise(where={"github_id": int(pr_id)})
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
token = (
|
token = (
|
||||||
|
|
@ -228,23 +261,57 @@ async def github_callback(request: Request):
|
||||||
"type": "section",
|
"type": "section",
|
||||||
"text": {
|
"text": {
|
||||||
"type": "mrkdwn",
|
"type": "mrkdwn",
|
||||||
"text": "This is a section block with checkboxes.",
|
"text": f"Here are all your sessions. Select the ones associated with OnBoard pull request #{pr_id}:",
|
||||||
},
|
},
|
||||||
"accessory": {
|
"accessory": {
|
||||||
"type": "checkboxes",
|
"type": "checkboxes",
|
||||||
"options": [
|
"options": [
|
||||||
json.loads("""{{"text": {{ "type": "mrkdwn", "text": "Your session on {pretty_time}"}}, "description": {{"type": "mrkdwn", "text": "You streamed for {length}"}}, "value": "checkbox-{filename}"}}""".format(pretty_time=recording, length=1, filename=recording)) for recording in stream_recs
|
json.loads(
|
||||||
|
"""{{"text": {{ "type": "mrkdwn", "text": "Your session on {pretty_time}"}}, "description": {{"type": "mrkdwn", "text": "You streamed for {length} {minute_or_minutes}"}}, "value": "checkbox-{filename}"}}""".format(
|
||||||
|
pretty_time=recording,
|
||||||
|
length=get_recording_duration(
|
||||||
|
recording, user_stream_key
|
||||||
|
),
|
||||||
|
minute_or_minutes=(
|
||||||
|
"minute"
|
||||||
|
if get_recording_duration(
|
||||||
|
recording, user_stream_key
|
||||||
|
)
|
||||||
|
== 1
|
||||||
|
else "minutes"
|
||||||
|
),
|
||||||
|
filename=recording,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for recording in stream_recs
|
||||||
],
|
],
|
||||||
"action_id": "checkboxes",
|
"action_id": "checkboxes",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "actions",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"text": {
|
||||||
|
"type": "plain_text",
|
||||||
|
"emoji": True,
|
||||||
|
"text": "Submit",
|
||||||
|
},
|
||||||
|
"style": "primary",
|
||||||
|
"value": "submit_sessions",
|
||||||
|
"action_id": "submit_sessions",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
return HTMLResponse(
|
return HTMLResponse(
|
||||||
"<h1>Success! Your PR has been linked to your account. Check your Slack DMs for the next steps!</h1>"
|
"<h1>Success! Your PR has been linked to your Slack account. Check your Slack DMs for the next steps!</h1>"
|
||||||
)
|
)
|
||||||
return HTMLResponse(
|
return HTMLResponse(
|
||||||
f"<h1>Looks like something went wrong! DM @mra on slack.</h1><p>This info might be of use to them: {FERNET.encrypt(bytes(str(db_pr.gh_user_id) + " " + str(gh_user) + " " + user_id + " " + pr_id + " " + state, encoding='utf-8'))}</p>", status_code=403
|
f"<h1>Looks like something went wrong! DM @mra on slack.</h1><p>This info might be of use to them: {FERNET.encrypt(bytes(str(db_pr.gh_user_id) + " " + str(gh_user) + " " + user_id + " " + pr_id + " " + state, encoding='utf-8'))}</p>",
|
||||||
|
status_code=403,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue