-
Notifications
You must be signed in to change notification settings - Fork 11
Refactor MSL authentication checks #606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
MattyTheHacker
wants to merge
95
commits into
main
Choose a base branch
from
msl-auth
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+230
−179
Open
Changes from all commits
Commits
Show all changes
95 commits
Select commit
Hold shift + click to select a range
cc35a2b
Refactor membership checking
MattyTheHacker 0917ae5
Refactor and Reformat
MattyTheHacker 2270e9c
Fix import error
MattyTheHacker fdda120
Bit of a mess
MattyTheHacker 1ed9d9f
Formatting
MattyTheHacker 797f94d
Fix
MattyTheHacker 2ac933d
Reformat
MattyTheHacker 74e57a6
Revert accidental change
MattyTheHacker fc6c1aa
Revert
MattyTheHacker f324842
Add logging
MattyTheHacker 00a7121
Simplify logic
MattyTheHacker 363e315
Refactor auth token checking
MattyTheHacker 1c1722f
Remove unused variables
MattyTheHacker 5670cba
Merge main into msl-auth
automatic-pr-updater[bot] 26dcf70
Merge main into msl-auth
automatic-pr-updater[bot] ca9f7fb
Strip
MattyTheHacker 6c976d3
remove old import
MattyTheHacker c466e69
Merge main into msl-auth
automatic-pr-updater[bot] ec9b323
Merge main into msl-auth
automatic-pr-updater[bot] 3886f61
Merge main into msl-auth
automatic-pr-updater[bot] 104da07
Merge main into msl-auth
automatic-pr-updater[bot] 2aae19e
Merge branch 'main' into msl-auth
MattyTheHacker 44d8215
Fix mypy
MattyTheHacker 7a50739
Merge main into msl-auth
automatic-pr-updater[bot] 508120b
Merge main into msl-auth
automatic-pr-updater[bot] be46790
Merge main into msl-auth
automatic-pr-updater[bot] cdfbf13
Merge main into msl-auth
automatic-pr-updater[bot] 1f59415
Merge branch 'main' into msl-auth
MattyTheHacker 92aee59
Fix spacing
MattyTheHacker 5ae6b81
Merge main into msl-auth
automatic-pr-updater[bot] 23f9d49
Merge main into msl-auth
automatic-pr-updater[bot] f5cc302
Merge main into msl-auth
automatic-pr-updater[bot] d03f3b9
Merge main into msl-auth
automatic-pr-updater[bot] d7a56de
Merge main into msl-auth
automatic-pr-updater[bot] 4aef459
Merge main into msl-auth
automatic-pr-updater[bot] f5ad888
Merge main into msl-auth
automatic-pr-updater[bot] 381bd04
Merge main into msl-auth
automatic-pr-updater[bot] c3a8968
Merge main into msl-auth
automatic-pr-updater[bot] d546f1a
Merge main into msl-auth
automatic-pr-updater[bot] 6e2b490
Merge main into msl-auth
automatic-pr-updater[bot] b95929a
Merge main into msl-auth
automatic-pr-updater[bot] e2a25cf
Merge main into msl-auth
automatic-pr-updater[bot] 53a0fd3
Merge main into msl-auth
automatic-pr-updater[bot] 13cced0
Merge main into msl-auth
automatic-pr-updater[bot] 1dfd9be
Merge main into msl-auth
automatic-pr-updater[bot] 669155d
Merge main into msl-auth
automatic-pr-updater[bot] 82d4eb2
Merge main into msl-auth
automatic-pr-updater[bot] 11dc44a
Merge main into msl-auth
automatic-pr-updater[bot] 87f9336
Merge main into msl-auth
automatic-pr-updater[bot] 8fe9412
Merge main into msl-auth
automatic-pr-updater[bot] 83c28b5
Merge main into msl-auth
automatic-pr-updater[bot] 954b662
Merge main into msl-auth
automatic-pr-updater[bot] fbb6344
Merge main into msl-auth
automatic-pr-updater[bot] 5d91282
Merge main into msl-auth
automatic-pr-updater[bot] 6761788
Merge main into msl-auth
automatic-pr-updater[bot] c86723a
Merge main into msl-auth
automatic-pr-updater[bot] 61c41c6
Merge main into msl-auth
automatic-pr-updater[bot] 6622778
Merge main into msl-auth
automatic-pr-updater[bot] 84b61f4
Merge main into msl-auth
automatic-pr-updater[bot] 4b277a8
Merge main into msl-auth
automatic-pr-updater[bot] 80cd696
Merge main into msl-auth
automatic-pr-updater[bot] 58231d2
Merge main into msl-auth
automatic-pr-updater[bot] 128715a
Merge main into msl-auth
automatic-pr-updater[bot] 9fe0c67
Merge main into msl-auth
automatic-pr-updater[bot] 23cf0e5
Merge main into msl-auth
automatic-pr-updater[bot] 2b804c8
Merge main into msl-auth
automatic-pr-updater[bot] 8818213
Merge main into msl-auth
automatic-pr-updater[bot] 873ef8a
Merge main into msl-auth
automatic-pr-updater[bot] 1cbedd6
Merge main into msl-auth
automatic-pr-updater[bot] 71d1a80
Merge main into msl-auth
automatic-pr-updater[bot] 573e4e9
Merge main into msl-auth
automatic-pr-updater[bot] 28eef27
Merge main into msl-auth
automatic-pr-updater[bot] 8dc8784
Merge main into msl-auth
automatic-pr-updater[bot] 5daec9b
Merge main into msl-auth
automatic-pr-updater[bot] b14250f
Merge main into msl-auth
automatic-pr-updater[bot] f076cf6
Merge main into msl-auth
automatic-pr-updater[bot] 4104931
Merge main into msl-auth
automatic-pr-updater[bot] bca1e21
Merge main into msl-auth
automatic-pr-updater[bot] fc10377
Merge main into msl-auth
automatic-pr-updater[bot] 0c13f5b
Merge main into msl-auth
automatic-pr-updater[bot] 66ba9fe
Merge main into msl-auth
automatic-pr-updater[bot] d73d6ba
Merge main into msl-auth
automatic-pr-updater[bot] 6b25f51
Merge main into msl-auth
automatic-pr-updater[bot] 5f60e4c
Merge main into msl-auth
automatic-pr-updater[bot] fef078e
Merge main into msl-auth
automatic-pr-updater[bot] de2980b
Merge main into msl-auth
automatic-pr-updater[bot] 137323d
Merge branch 'main' into msl-auth
MattyTheHacker 7861d21
Lots of fixes
MattyTheHacker e46f875
Fix error
MattyTheHacker e75f7cd
Fixes
MattyTheHacker 9606d61
Fixes
MattyTheHacker 299be3e
[autofix.ci] apply automated fixes
autofix-ci[bot] ee70d0a
Merge main into msl-auth
automatic-pr-updater[bot] 9f06943
Merge main into msl-auth
automatic-pr-updater[bot] b29f684
Merge main into msl-auth
automatic-pr-updater[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| """Module for authorisation checks.""" | ||
|
|
||
| import logging | ||
| from enum import Enum | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| import bs4 | ||
|
|
||
| from .core import ORGANISATION_ADMIN_URL, su_platform_client | ||
|
|
||
| if TYPE_CHECKING: | ||
| from collections.abc import Iterable, Sequence | ||
| from logging import Logger | ||
| from typing import Final | ||
|
|
||
|
|
||
| __all__: "Sequence[str]" = ( | ||
| "SUPlatformAccessCookieStatus", | ||
| "get_su_platform_access_cookie_status", | ||
| "get_su_platform_organisations", | ||
| ) | ||
|
|
||
|
|
||
| logger: "Final[Logger]" = logging.getLogger("TeX-Bot") | ||
|
|
||
|
|
||
| SU_PLATFORM_PROFILE_URL: "Final[str]" = "https://guildofstudents.com/profile" | ||
|
|
||
|
|
||
| class SUPlatformAccessCookieStatus(Enum): | ||
| """Enum class defining the status of the SU Platform Access Cookie.""" | ||
|
|
||
| INVALID = ( | ||
| logging.WARNING, | ||
| ( | ||
| "The SU platform access cookie is not associated with any MSL user, " | ||
| "meaning it is invalid or expired." | ||
| ), | ||
| ) | ||
| VALID = ( | ||
| logging.WARNING, | ||
| ( | ||
| "The SU platform access cookie is associated with a valid MSL user, " | ||
| "but is not an admin to any MSL organisations." | ||
| ), | ||
| ) | ||
| AUTHORISED = ( | ||
| logging.INFO, | ||
| ( | ||
| "The SU platform access cookie is associated with a valid MSL user and " | ||
| "has access to at least one MSL organisation." | ||
| ), | ||
| ) | ||
|
|
||
|
|
||
| async def get_su_platform_access_cookie_status() -> SUPlatformAccessCookieStatus: | ||
| """Retrieve the current validity status of the SU platform access cookie.""" | ||
| response_object: bs4.BeautifulSoup = bs4.BeautifulSoup( | ||
| await su_platform_client.fetch_url_content(SU_PLATFORM_PROFILE_URL), "html.parser" | ||
| ) | ||
| page_title: bs4.Tag | bs4.NavigableString | None = response_object.find("title") | ||
| if not page_title or "Login" in str(page_title): | ||
| logger.debug("Token is invalid or expired.") | ||
| return SUPlatformAccessCookieStatus.INVALID | ||
|
|
||
| response_html: str = await su_platform_client.fetch_url_content(ORGANISATION_ADMIN_URL) | ||
|
|
||
| if "admin tools" in response_html.lower(): | ||
| return SUPlatformAccessCookieStatus.AUTHORISED | ||
|
|
||
| if "you do not have any permissions for this organisation" in response_html.lower(): | ||
| return SUPlatformAccessCookieStatus.VALID | ||
|
|
||
| logger.warning( | ||
| "Unexpected response when checking SU platform access cookie authorisation." | ||
| ) | ||
| return SUPlatformAccessCookieStatus.INVALID | ||
|
MattyTheHacker marked this conversation as resolved.
|
||
|
|
||
|
|
||
| async def get_su_platform_organisations() -> "Iterable[str]": | ||
| """Retrieve the MSL organisations the current SU platform cookie has access to.""" | ||
| response_object: bs4.BeautifulSoup = bs4.BeautifulSoup( | ||
| await su_platform_client.fetch_url_content(SU_PLATFORM_PROFILE_URL), "html.parser" | ||
| ) | ||
|
|
||
| page_title: bs4.Tag | bs4.NavigableString | None = response_object.find("title") | ||
|
|
||
| if not page_title: | ||
| logger.warning( | ||
| "Profile page returned no content when checking " | ||
| "SU platform access cookie's authorisation." | ||
| ) | ||
| return () | ||
|
|
||
| if "Login" in str(page_title): | ||
| logger.warning( | ||
| "Authentication redirected to login page. " | ||
| "SU platform access cookie is invalid or expired." | ||
| ) | ||
| return () | ||
|
|
||
| profile_section_html: bs4.Tag | bs4.NavigableString | None = response_object.find( | ||
| "div", {"id": "profile_main"} | ||
| ) | ||
|
|
||
| if profile_section_html is None: | ||
| logger.warning( | ||
| "Couldn't find the profile section of the user " | ||
| "when scraping the SU platform's website HTML." | ||
| ) | ||
| logger.debug("Retrieved HTML: %s", response_object.text) | ||
| return () | ||
|
|
||
| user_name: bs4.Tag | bs4.NavigableString | int | None = profile_section_html.find("h1") | ||
|
|
||
| if not isinstance(user_name, bs4.Tag): | ||
| logger.warning("Found user profile on the SU platform but couldn't find their name.") | ||
| logger.debug("Retrieved HTML: %s", response_object.text) | ||
| return () | ||
|
|
||
| parsed_html: bs4.Tag | bs4.NavigableString | None = response_object.find( | ||
| "ul", {"id": "ulOrgs"} | ||
| ) | ||
|
|
||
| if parsed_html is None or isinstance(parsed_html, bs4.NavigableString): | ||
| NO_ADMIN_TABLE_MESSAGE: Final[str] = ( | ||
| f"Failed to retrieve the admin table for user: {user_name.string}. " | ||
| "Please check you have used the correct SU platform access token!" | ||
| ) | ||
| logger.warning(NO_ADMIN_TABLE_MESSAGE) | ||
| return () | ||
|
|
||
| organisations: Iterable[str] = [ | ||
| list_item.get_text(strip=True) for list_item in parsed_html.find_all("li") | ||
| ] | ||
|
|
||
| logger.debug( | ||
| "SU platform access cookie has admin authorisation to: %s as user %s", | ||
| organisations, | ||
| user_name.text, | ||
| ) | ||
|
|
||
| return organisations | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.