55import config
66import totp
77
8+
89def login_with_drexel_connect (session : Session ) -> Session :
910 response = session .get (config .drexel_connect_base_url )
1011 soup = BeautifulSoup (response .text , "html.parser" )
1112
1213 csrf_token = extract_csrf_token (soup )
1314 form_action_path = extract_form_action_path (soup )
14-
15+
1516 login_payload = {
1617 "j_username" : config .drexel_username ,
1718 "j_password" : config .drexel_password ,
1819 "csrf_token" : csrf_token ,
19- "_eventId_proceed" : ""
20+ "_eventId_proceed" : "" ,
2021 }
2122
2223 # this should send the credentials and send the MFA request
23- response = session .post (config .drexel_connect_base_url + form_action_path , data = login_payload )
24+ response = session .post (
25+ config .drexel_connect_base_url + form_action_path , data = login_payload
26+ )
2427
2528 soup = BeautifulSoup (response .text , "html.parser" )
2629 data = parse_initial_mfa_page (soup )
2730
28- response = session .post (config .drexel_connect_base_url + data ["url" ], data = data ["form-data" ])
31+ response = session .post (
32+ config .drexel_connect_base_url + data ["url" ], data = data ["form-data" ]
33+ )
2934 json_response = response .json ()
3035
3136 data = {
3237 json_response ["csrfN" ]: json_response ["csrfV" ],
3338 "_eventId" : json_response ["actValue" ],
3439 }
3540
36- response = session .post (config .drexel_connect_base_url + json_response ["flowExURL" ], data = data )
41+ response = session .post (
42+ config .drexel_connect_base_url + json_response ["flowExURL" ], data = data
43+ )
3744 soup = BeautifulSoup (response .text , "html.parser" )
3845
3946 parsed_data = parse_final_mfa_page (soup )
40-
47+
4148 totp_code = totp .get_token (config .drexel_mfa_secret_key )
4249
4350 data = {
4451 "csrf_token" : parsed_data ["csrf_token" ],
4552 "_eventId" : "proceed" ,
46- "j_mfaToken" : totp_code
53+ "j_mfaToken" : totp_code ,
4754 }
4855
49- response = session .post (config .drexel_connect_base_url + parsed_data ["url" ], data = data )
56+ response = session .post (
57+ config .drexel_connect_base_url + parsed_data ["url" ], data = data
58+ )
5059
5160 return session
5261
62+
5363def extract_csrf_token (soup : BeautifulSoup ) -> str :
54- csrf_token_input_tag = soup .find ("input" , {"name" : "csrf_token" })
64+ csrf_token_input_tag = soup .find ("input" , {"name" : "csrf_token" })
5565
5666 if not isinstance (csrf_token_input_tag , Tag ):
5767 raise Exception ("Could not find CSRF token." )
58-
68+
5969 csrf_token = csrf_token_input_tag ["value" ]
6070
6171 if not isinstance (csrf_token , str ):
62- raise Exception (f"CSRF token was not a string. Found: { csrf_token } of type: { type (csrf_token )} " )
72+ raise Exception (
73+ f"CSRF token was not a string. Found: { csrf_token } of type: { type (csrf_token )} "
74+ )
6375
6476 return csrf_token
6577
78+
6679def extract_form_action_path (soup : BeautifulSoup ) -> str :
6780 # the form is a child of a div with id "login-box"
6881 login_box_div = soup .find ("div" , {"id" : "login-box" })
@@ -78,10 +91,13 @@ def extract_form_action_path(soup: BeautifulSoup) -> str:
7891 form_action_path = login_form ["action" ]
7992
8093 if not isinstance (form_action_path , str ):
81- raise Exception (f"Form action path was not a string. Found: { form_action_path } of type: { type (form_action_path )} " )
94+ raise Exception (
95+ f"Form action path was not a string. Found: { form_action_path } of type: { type (form_action_path )} "
96+ )
8297
8398 return form_action_path
8499
100+
85101def parse_initial_mfa_page (soup : BeautifulSoup ) -> dict [str , str ]:
86102 data = {}
87103
@@ -94,29 +110,35 @@ def parse_initial_mfa_page(soup: BeautifulSoup) -> dict[str, str]:
94110 script_content = script_tag .string
95111
96112 if not isinstance (script_content , str ):
97- raise Exception (f"Script content was not a string. Found: { script_content } of type: { type (script_content )} " )
113+ raise Exception (
114+ f"Script content was not a string. Found: { script_content } of type: { type (script_content )} "
115+ )
98116
99- url_match = re .search (r"url:\s*['\"](/idp/profile/cas/login\?execution=[^'\"]+)['\"]" , script_content )
117+ url_match = re .search (
118+ r"url:\s*['\"](/idp/profile/cas/login\?execution=[^'\"]+)['\"]" , script_content
119+ )
100120 if not url_match :
101121 raise Exception ("Could not find MFA URL." )
102122
103- event_id_match = event_id_match = re .search (r"data:\s*'_eventId=([^'&]+)&csrf_token" , script_content )
123+ event_id_match = event_id_match = re .search (
124+ r"data:\s*'_eventId=([^'&]+)&csrf_token" , script_content
125+ )
104126 if not event_id_match :
105127 raise Exception ("Could not find MFA event ID." )
106128
107129 csrf_token_match = re .search (r"csrf_token=([^'&]+)" , script_content )
108130 if not csrf_token_match :
109131 raise Exception ("Could not find MFA CSRF token." )
110-
132+
111133 data ["url" ] = url_match .group (1 )
112134 data ["form-data" ] = {
113135 "_eventId" : event_id_match .group (1 ),
114- "csrf_token" : csrf_token_match .group (1 )
136+ "csrf_token" : csrf_token_match .group (1 ),
115137 }
116138
117-
118139 return data
119140
141+
120142def parse_final_mfa_page (soup : BeautifulSoup ) -> dict [str , str ]:
121143 data : dict [str , str ] = {}
122144
@@ -125,23 +147,25 @@ def parse_final_mfa_page(soup: BeautifulSoup) -> dict[str, str]:
125147
126148 if not isinstance (form , Tag ):
127149 raise Exception ("Could not find OTP form." )
128-
150+
129151 url = form ["action" ]
130152
131153 if not isinstance (url , str ):
132154 raise Exception (f"Action was not a string. Found: { url } of type: { type (url )} " )
133-
155+
134156 csrf_token_input = form .find ("input" , {"name" : "csrf_token" })
135157
136158 if not isinstance (csrf_token_input , Tag ):
137159 raise Exception ("Could not find CSRF token input." )
138-
160+
139161 csrf_token = csrf_token_input ["value" ]
140162
141163 if not isinstance (csrf_token , str ):
142- raise Exception (f"CSRF token was not a string. Found: { csrf_token } of type: { type (csrf_token )} " )
164+ raise Exception (
165+ f"CSRF token was not a string. Found: { csrf_token } of type: { type (csrf_token )} "
166+ )
143167
144168 data ["url" ] = url
145169 data ["csrf_token" ] = csrf_token
146170
147- return data
171+ return data
0 commit comments