11from logging import getLogger , Logger
22
3- import json
4- import httpx
5-
63from fastapi import APIRouter , Request , Form
74from fastapi .responses import JSONResponse
85
96from core import slack , wikithoughts , cshcalendar
10- from config import WATCHED_CHANNELS
7+ import json
8+ import urllib
119
1210logger : Logger = getLogger (__name__ )
1311router : APIRouter = APIRouter ()
1412
15- ACCEPT_MESSAGE : str = "Posting right now :^)"
16- DENY_MESSAGE : str = "Okay :( maybe next time"
17-
1813
1914@router .get ("/calendar" )
2015async def get_calendar () -> JSONResponse :
@@ -63,44 +58,25 @@ async def slack_events(request: Request) -> JSONResponse:
6358 JSONResponse: A JSON response indicating the result of the event handling.
6459 """
6560
66- try :
67- logger .debug (f"Received Slack event: { await request .body ()} " )
61+ raw_body : bytes = await request .body ()
6862
69- body : dict = await request .json ()
63+ if not (slack .is_valid_slack_request (request , raw_body )):
64+ logger .warning (f"Received a Fake Slack Event!: { raw_body } " )
65+ return JSONResponse ({"error" : "Invalid signature" }, status_code = 403 )
7066
71- if request .headers .get ("content-type" ) == "application/json" :
72- if body .get ("type" ) == "url_verification" :
73- logger .info ("SLACK EVENT: Was a challenge!" )
74- return JSONResponse ({"challenge" : body .get ("challenge" )})
67+ body : dict = json .loads (raw_body )
7568
76- if not body :
77- logger .debug ("SLACK EVENT: Was a challenge, with no body" )
69+ # Challenge from Bot Authentication
70+ if request .headers .get ("content-type" ) == "application/json" :
71+ if body .get ("type" ) == "url_verification" :
72+ logger .info ("SLACK EVENT: Was a challenge!" )
7873 return JSONResponse ({"challenge" : body .get ("challenge" )})
7974
80- event : dict = body .get ("event" , {})
81- cleaned_text : str = slack .clean_text (event .get ("text" , "" ))
82-
83- if event .get ("subtype" , None ) is not None :
84- logger .info ("SLACK EVENT: Had no subtype, ignoring it" )
85- return JSONResponse ({"status" : "ignored" })
86-
87- if event .get ("channel" , None ) not in WATCHED_CHANNELS :
88- logger .info (
89- "SLACK EVENT: Message was not in a Watched Channel, ignoring it"
90- )
91- return JSONResponse ({"status" : "ignored" })
92-
93- logger .info ("SLACK EVENT: Requesting upload via dm!" )
94- await slack .request_upload_via_dm (event .get ("user" , "" ), cleaned_text )
95- except Exception as e :
96- logger .error (f"Error handling Slack event: { e } " )
97- return JSONResponse ({"status" : "error" , "message" : str (e )})
98-
99- return JSONResponse ({"status" : "success" })
75+ return JSONResponse (await slack .process_slack_events (body ))
10076
10177
10278@router .post ("/slack/message_actions" )
103- async def message_actions (payload : str = Form (...) ) -> JSONResponse :
79+ async def message_actions (request : Request ) -> JSONResponse :
10480 """
10581 Handles slack message action.
10682
@@ -111,48 +87,20 @@ async def message_actions(payload: str = Form(...)) -> JSONResponse:
11187 JSONResponse: A JSON response indicating the result of the action.
11288 """
11389
114- try :
115- form_json : dict = json .loads (payload )
116- response_url = form_json .get ("response_url" )
117-
118- if form_json .get ("type" ) != "block_actions" :
119- return JSONResponse ({}, status_code = 200 )
120-
121- if slack .convert_user_response_to_bool (form_json ):
122- logger .info (
123- "User approved the announcement, Adding it to the announcement list!"
124- )
125-
126- message_object : dict [str , dict ] = json .loads (
127- form_json .get ("actions" , [{}])[0 ].get ("value" , '{text:""}' )
128- ).get ("text" , None )
129-
130- user_id = form_json .get ("user" , {}).get ("id" )
131-
132- username : str = await slack .get_username (user_id = user_id )
133- username = username [:40 ]
134-
135- slack .add_announcement (message_object , username )
136-
137- if response_url :
138- async with httpx .AsyncClient () as client :
139- await client .post (
140- response_url ,
141- json = {"text" : ACCEPT_MESSAGE , "replace_original" : True },
142- )
143- else :
144- if response_url :
145- async with httpx .AsyncClient () as client :
146- await client .post (
147- response_url ,
148- json = {"text" : DENY_MESSAGE , "replace_original" : True },
149- )
90+ raw_body : bytes = await request .body ()
15091
151- except Exception as e :
152- logger .error (f"Error in message_actions: { e } " )
153- return JSONResponse ({"status" : "error" , "message" : str (e )}, status_code = 500 )
92+ if not (slack .is_valid_slack_request (request , raw_body )):
93+ logger .warning (f"Received a Fake Slack Message Action! { raw_body } " )
94+ return JSONResponse ({"error" : "Invalid signature" }, status_code = 403 )
95+
96+ form_data = urllib .parse .parse_qs (raw_body .decode ("utf-8" ))
97+ payload = form_data .get ("payload" , [None ])[0 ]
98+
99+ if payload is None :
100+ return JSONResponse ({"error" : "Missing payload" }, status_code = 400 )
154101
155- return JSONResponse ({"status" : "success" }, status_code = 200 )
102+ response_dict , status_code = await slack .process_slack_message_actions (payload )
103+ return JSONResponse (response_dict , status_code = status_code )
156104
157105
158106@router .get ("/wikithought" )
0 commit comments