You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.6 KiB
91 lines
2.6 KiB
## |
|
## lib/auth.py |
|
## Provides functions for Calnet authentication over |
|
## Selenium, including cookies export. |
|
## |
|
## Copyright (c) 2022 Kevin Mo |
|
## |
|
|
|
import pickle |
|
from selenium.webdriver.common.by import By |
|
from selenium.webdriver.support.ui import WebDriverWait |
|
from selenium.webdriver.support import expected_conditions as EC |
|
|
|
COOKIES_NAME = "cookies.pkl" |
|
|
|
def save_cookies(driver): |
|
""" |
|
Save cookies given a Selenium driver. |
|
""" |
|
pickle.dump(driver.get_cookies(), open(COOKIES_NAME, "wb")) |
|
return True |
|
|
|
def load_cookies(driver): |
|
""" |
|
Load cookies given a Selenium driver. |
|
""" |
|
try: |
|
cookies = pickle.load(open(COOKIES_NAME, "rb")) |
|
for cookie in cookies: |
|
driver.add_cookie(cookie) |
|
except IOError: |
|
pass |
|
|
|
return driver |
|
|
|
def check_calnet_auth(driver): |
|
""" |
|
Returns whether CalNet authentication is ready. |
|
""" |
|
return "auth.berkeley.edu" in driver.current_url |
|
|
|
def perform_calnet_auth(driver, cid, pwd): |
|
""" |
|
Perform authentication with CalNet, given |
|
that driver is at auth.berkeley.edu. |
|
""" |
|
print("Performing Calnet authentication") |
|
print("Current URL:", driver.current_url) |
|
|
|
if not check_calnet_auth(driver): |
|
raise Exception("Cannot perform authentication at current state.") |
|
|
|
# Target user input and then submit |
|
cid_box = driver.find_element_by_id("username") |
|
pwd_box = driver.find_element_by_id("password") |
|
submit_box = driver.find_element_by_id("submit") |
|
|
|
cid_box.send_keys(cid) |
|
pwd_box.send_keys(pwd) |
|
submit_box.click() |
|
|
|
# Handle incorrect login attempt |
|
if "auth.berkeley.edu" in driver.current_url: |
|
print("Incorrect login attempt detected.") |
|
raise Exception("Incorrect CalNet credentials") |
|
|
|
# Check the presence of Duo 2FA |
|
try: |
|
if "duosecurity.com" not in driver.current_url: |
|
return True |
|
|
|
print() |
|
print("IMPORTANT: Complete the 2FA process on the automated browser.") |
|
print("Complete the process through push notification, security key, etc.") |
|
print() |
|
|
|
# Stall for success or trust box |
|
wait = WebDriverWait(driver, 30) |
|
trust_box = wait.until(EC.element_to_be_clickable((By.ID, "trust-browser-button"))) |
|
print("Detected trust browser button, clicking...") |
|
trust_box.click() |
|
|
|
wait = WebDriverWait(driver, 10) |
|
if not wait.until(EC.url_contains("duosecurity.com")): |
|
raise Exception("2FA did not complete successfully") |
|
else: |
|
print("Detected redirect, authentication is a success!") |
|
except: |
|
print("Timed out or could not locate Duo 2FA prompt.") |
|
|
|
|