-
Notifications
You must be signed in to change notification settings - Fork 365
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #701 from consideRatio/pr/cilogon-fnmatch-allowed-…
…domains [CILogon] allow fnmatch based expressions in `allowed_domains`, such as `*.jupyter.org`
- Loading branch information
Showing
2 changed files
with
30 additions
and
2 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
A JupyterHub authenticator class for use with CILogon as an identity provider. | ||
""" | ||
import os | ||
from fnmatch import fnmatch | ||
from urllib.parse import urlparse | ||
|
||
import jsonschema | ||
|
@@ -174,6 +175,11 @@ def _validate_scope(self, proposal): | |
address enables users to be allowed if their `username_claim` ends | ||
with `@` followed by a domain in this list. | ||
Use of wildcards `*` and a bit more is supported via Python's | ||
`fnmatch` function since version 16.2. Setting `allowed_domains` to | ||
`["jupyter.org", "*.jupyter.org"]` would for example allow users | ||
with `[email protected]` or `[email protected]` usernames. | ||
.. versionchanged:: 15.0 | ||
Changed format from a list to a dictionary. | ||
|
@@ -366,8 +372,17 @@ async def check_allowed(self, username, auth_model): | |
if idp_allowed_domains: | ||
unprocessed_username = self._user_info_to_unprocessed_username(user_info) | ||
user_domain = unprocessed_username.split("@", 1)[1].lower() | ||
if user_domain in idp_allowed_domains: | ||
return True | ||
|
||
for ad in idp_allowed_domains: | ||
# fnmatch allow us to use wildcards like * and ?, but | ||
# not the full regex. For simple domain matching this is | ||
# good enough. If we were to use regexes instead, people | ||
# will have to escape all their '.'s, and since that is | ||
# actually going to match 'any character' it is a | ||
# possible security hole. For details see | ||
# https://docs.python.org/3/library/fnmatch.html. | ||
if fnmatch(user_domain, ad): | ||
return True | ||
|
||
# users should be explicitly allowed via config, otherwise they aren't | ||
return False | ||
|
This file contains 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 |
---|---|---|
|
@@ -231,6 +231,19 @@ async def test_cilogon( | |
False, | ||
None, | ||
), | ||
( | ||
"A - allowed by allowed_domains via a wildcard", | ||
{ | ||
"username_derivation": { | ||
"username_claim": "email", | ||
}, | ||
"allowed_domains": ["allowed-domain.org", "*.allowed-domain.org"], | ||
}, | ||
{}, | ||
"[email protected]", | ||
True, | ||
None, | ||
), | ||
# test of allowed_users and admin_users together with | ||
# username_derivation actions to verify the final usernames is what | ||
# matters when describing allowed_users and admin_users | ||
|