-
Notifications
You must be signed in to change notification settings - Fork 248
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
[auth] Validate usernames upfront #14808
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,7 +128,7 @@ async def check_valid_new_user(tx: Transaction, username, login_id, is_developer | |
raise MultipleUserTypes(username) | ||
if not is_service_account and not login_id: | ||
raise EmptyLoginID(username) | ||
if not username or not all(c for c in username if c.isalnum()): | ||
if not username or not (username.isalnum() and username.islower()): | ||
raise InvalidUsername(username) | ||
|
||
existing_users = await users_with_username_or_login_id(tx, username, login_id) | ||
|
@@ -151,6 +151,18 @@ async def check_valid_new_user(tx: Transaction, username, login_id, is_developer | |
return None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we seem to only allow alphanumeric usernames. Do you know if that's true, or is this not being executed for some reason? Either way, it would be nice to define username validity in one place. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, interesting, I somehow missed this. The original error report was caused by uppercase characters, which I guess is why it got past this check originally. Usernames which don't conform to RFC1123 was where I started seeing downstream problems with user creation, but since "(lowercase) alphanumeric" is a subset of RFC1123, I'm inclined to make that our new rule, instead of expanding the options up to include all of RFC1123. And I like the idea of moving that check into this function, instead of adding a new validation. I'll do that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact, RFC1123 would be a fine validation for the credentials_secret_name that we allow as a development environment option, and is currently unvalidated until it potentially blows up the user creation process downstream. So I'll repurpose the original change into a token name validator, and make username validation stricter and happening here |
||
|
||
|
||
def validate_credentials_secret_name_input(secret_name: Optional[str]): | ||
if secret_name is None: | ||
return | ||
|
||
regex = re.compile(r'^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very nice catch! |
||
if not regex.match(secret_name): | ||
raise AuthUserError( | ||
f'invalid credentials_secret_name {secret_name}. Must match RFC1123 (lowercase alphanumeric plus "." and "-", start and end with alphanumeric)', | ||
'error', | ||
) | ||
|
||
|
||
async def insert_new_user( | ||
db: Database, | ||
username: str, | ||
|
@@ -183,6 +195,7 @@ async def _insert(tx): | |
), | ||
) | ||
|
||
validate_credentials_secret_name_input(hail_credentials_secret_name) | ||
await _insert() | ||
return True | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I missing an important reason why this was being done character by character previously?