diff --git a/README.md b/README.md index 2170ee0..be9e945 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/src/config.py b/src/config.py index c1abb63..c89cb87 100644 --- a/src/config.py +++ b/src/config.py @@ -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" diff --git a/src/login.py b/src/login.py index 4dade21..f9b5b9a 100644 --- a/src/login.py +++ b/src/login.py @@ -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)