Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ If you set this up, you will not need to manually enter an authentication code e

Now, when you run the scraper as explained [above](#Usage), it should authenticate itself automatically using this secret key.

###### Authenticate using Microsoft Authenticator

If you prefer to use Microsoft Authenticator for local development, you can set the `USE_MICROSOFT_AUTHENTICATOR` environment variable to `True`. This will allow the scraper to use Microsoft Authenticator for MFA.

1. Go to [connect.drexel.edu](connect.drexel.edu).
2. Click 'Help & Settings', then 'Change MFA settings'.
3. Log in to the Microsoft portal, then click 'Add sign-in method' on the 'Security info' tab.
4. Select 'Authenticator app' for the method, and click 'Add'.
5. Follow the instructions to set up Microsoft Authenticator.
6. Set your `USE_MICROSOFT_AUTHENTICATOR` environment variable to `True`.

Now, when you run the scraper as explained [above](#Usage), it should authenticate itself using Microsoft Authenticator.

#### All Colleges

To scrape all colleges instead of just the one specified in the `src/config.py`, run the following command:
Expand Down
3 changes: 3 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def get_environ(key: str, required: bool = True) -> str:
# This is not required if the user is using a separate authenticator app and will manually approve the login attempt
drexel_mfa_secret_key = get_environ("DREXEL_MFA_SECRET_KEY", False) or None

# New environment variable to toggle between Microsoft Authenticator and other authenticator apps
use_microsoft_authenticator = get_environ("USE_MICROSOFT_AUTHENTICATOR", False) or False

# URL's
tms_base_url = "https://termmasterschedule.drexel.edu"
tms_home_url = tms_base_url + "/webtms_du"
Expand Down
61 changes: 40 additions & 21 deletions src/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,47 @@ def login_with_drexel_connect(session: Session) -> Session:
page.wait_for_timeout(extra_timeout)
page.get_by_text("Sign in").click()

if config.drexel_mfa_secret_key is not None:
mfa_token = totp.get_token(config.drexel_mfa_secret_key)
if config.use_microsoft_authenticator:
page.wait_for_selector("input[name='otc']")
page.wait_for_timeout(extra_timeout)

mfa_input = page.query_selector("input[name='otc']")
assert isinstance(
mfa_input, ElementHandle
), "MFA input field on Microsoft Online not found"
mfa_input.fill(input("Please input your Microsoft Authenticator verification code: "))

page.wait_for_selector("input[type='submit']")
page.wait_for_timeout(extra_timeout)

submit_button = page.query_selector("input[type='submit']")
assert isinstance(
submit_button, ElementHandle
), "Submit button on Microsoft Online for MFA not found"
submit_button.click()
else:
mfa_token = input("Please input your MFA verification code: ")

page.wait_for_selector("input[name='otc']")
page.wait_for_timeout(extra_timeout)

mfa_input = page.query_selector("input[name='otc']")
assert isinstance(
mfa_input, ElementHandle
), "MFA input field on Microsoft Online not found"
mfa_input.fill(mfa_token)

page.wait_for_selector("input[type='submit']")
page.wait_for_timeout(extra_timeout)

submit_button = page.query_selector("input[type='submit']")
assert isinstance(
submit_button, ElementHandle
), "Submit button on Microsoft Online for MFA not found"
submit_button.click()
if config.drexel_mfa_secret_key is not None:
mfa_token = totp.get_token(config.drexel_mfa_secret_key)
else:
mfa_token = input("Please input your MFA verification code: ")

page.wait_for_selector("input[name='otc']")
page.wait_for_timeout(extra_timeout)

mfa_input = page.query_selector("input[name='otc']")
assert isinstance(
mfa_input, ElementHandle
), "MFA input field on Microsoft Online not found"
mfa_input.fill(mfa_token)

page.wait_for_selector("input[type='submit']")
page.wait_for_timeout(extra_timeout)

submit_button = page.query_selector("input[type='submit']")
assert isinstance(
submit_button, ElementHandle
), "Submit button on Microsoft Online for MFA not found"
submit_button.click()

page.wait_for_url("https://connect.drexel.edu/**")
page.wait_for_timeout(extra_timeout)
Expand Down
Loading