Skip to content

Add ability to login with email address#85

Open
twdbben wants to merge 3 commits into
data-govt-nz:masterfrom
TNRIS:login-with-email
Open

Add ability to login with email address#85
twdbben wants to merge 3 commits into
data-govt-nz:masterfrom
TNRIS:login-with-email

Conversation

@twdbben
Copy link
Copy Markdown
Contributor

@twdbben twdbben commented Mar 19, 2025

CKAN 2.10 added the ability to login with email address in addition to username.

In this PR I have added this capability to ckanext-security.

I may need to do something about the way this interacts with throttling. As it is currently implemented, a separate security_throttle_key is tracked for a user's email and user_name. So, for instance, an attacker could theoretically attempt ckanext.security.login_max_count logins every ckanext.security.lock_timeout seconds on an email address and a user_name separately, technically doubling the threat exposure.

I know this isn't optimal, but I also don't know how big of an issue I consider it. It would be better if only one security_throttle_key was tracked but that is beyond the scope of what I have time to implement here and now.

Interested to hear if you think this fix is worth merging as it is or if (a) I have introduced non-throttling related security problems with what I have proposed so far or (b) I should first work to also consolidate the security_throttle_keys into one per user as part of this PR.

Thanks, hope this is useful.

Comment thread ckanext/security/authenticator.py Outdated
return
LoginThrottle(User.by_name(user_name), user_name).reset()
user = User.by_name(user_name)
if not user:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same logic as in get_user_throttle, perhaps extract a helper.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, thanks.

I've taken care of this by creating a new helper function security_get_user(user_name).

Note that in addition to reset_address_throttle(user_name) and get_user_throttle(user_name) in authenticator.py, login() in utils.py also uses the new helper.

Comment thread ckanext/security/plugin/__init__.py Outdated
return {
'check_ckan_version': tk.check_ckan_version,
'security_enable_totp': security_enable_totp,
'security_get_user': security_get_user,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this have a more descriptive name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, what would you suggest?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps something more descriptive of its purpose, eg get_user_by_name_or_email

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the function name from security_get_user to security_get_user_by_name_or_email.

Changed function name security_get_user to
security_get_user_by_name_or_email
@ThrawnCA
Copy link
Copy Markdown
Contributor

ThrawnCA commented Jul 1, 2025

What happens if someone sets their email address to be someone else's username?

@twdbben
Copy link
Copy Markdown
Contributor Author

twdbben commented Jul 8, 2025

What happens if someone sets their email address to be someone else's username?

Good question. Based on some investigation I have found the following to be true.

CKAN core name_validator does not allow @ symbol.

https://github.com/ckan/ckan/blob/36f72e64487e74a0f23b34d0496b82e67dfb9841/ckan/logic/validators.py#L399-L401

CKAN core email_validator requires a valid email address (i.e. includes an @ symbol)

https://github.com/ckan/ckan/blob/36f72e64487e74a0f23b34d0496b82e67dfb9841/ckan/logic/validators.py#L1045-L1051

So, unless I'm overlooking something, this means a username cannot be set to an email address, and an email address cannot be set to a username.

@ThrawnCA
Copy link
Copy Markdown
Contributor

ThrawnCA commented Jul 9, 2025

So, unless I'm overlooking something, this means a username cannot be set to an email address, and an email address cannot be set to a username.

That sounds good. Can you add a unit test to catch any future changes that might alter this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants