Skip to content

Cargo owner username disambiguation - #14213

Open
moskirathe wants to merge 32 commits into
rust-lang:mainfrom
moskirathe:cargo-owner-username-disambiguation
Open

Cargo owner username disambiguation#14213
moskirathe wants to merge 32 commits into
rust-lang:mainfrom
moskirathe:cargo-owner-username-disambiguation

Conversation

@moskirathe

Copy link
Copy Markdown
Contributor

fixes: #13769

Comment thread crates/crates_io_database/src/models/oauth_github.rs Outdated
Comment thread crates/crates_io_database/src/models/owner.rs
@rustbot

This comment has been minimized.

Comment thread src/controllers/krate/owners.rs Outdated
Comment thread src/controllers/krate/owners.rs Outdated
Comment thread src/controllers/krate/owners.rs
Comment thread src/controllers/krate/owners.rs Outdated
let username = user.username.to_owned();

if let Some(oauth_github) = oauth_github
&& oauth_github.login != user.username

@Turbo87 Turbo87 Jul 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The surrounding username lookups are case-insensitive, but this comparison is case-sensitive. A crates.io username Alice associated with GitHub login alice would be reported as ambiguous even though both namespaces treat those names as equal. Could we compare using the same canonicalization and add a case-only regression test? _ vs. - might also be relevant for this.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, the case-only comparison and regression tests look fixed. One part is still inconsistent with the new canonical username behavior, though: this comparison uses lowercase only, so foo-bar and foo_bar are still treated as different. Since the new index and #13903 use canon_username(), could we use the same canonicalization here and add a separator regression test?

login: &str,
) -> QueryResult<OauthGithub> {
oauth_github::table
.filter(lower(oauth_github::login).eq(login.to_lowercase()))

@Turbo87 Turbo87 Jul 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

oauth_github.login is not unique (yet), so this unordered .first() can resolve github:<name> to an arbitrary crates.io account. The previous User::find_by_login() explicitly ordered by descending GitHub ID. Could we preserve the intended deterministic tie-breaker, or reject multiple matches, and cover duplicate case-insensitive logins in a regression test? 🙏

View changes since the review

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.

updated to preserve original functionality of explicitly ordering by Github ID.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, ordering by descending account_id restores the deterministic selection. Could we also add the duplicate case-insensitive login regression test requested here? That is the state which makes the ordering observable and protects it from being removed again later.

Comment thread src/controllers/krate/owners.rs Outdated
) -> QueryResult<User> {
User::query()
.filter(lower(users::gh_login).eq(login.to_lowercase()))
.filter(lower(users::username).eq(username.to_lowercase()))

@Turbo87 Turbo87 Jul 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Both new lookup paths filter on lower(...), but there are no matching functional indexes: the existing user index covers lower(gh_login), while the OAuth table only has an index on user_id. A request can resolve up to ten owners, causing repeated full scans of these identity tables. Could we add indexes for lower(users.username) and lower(oauth_github.login) as part of this change? Or given #13903 I think we might actually want canon_username(users.username) and lower(oauth_github.login)?

View changes since the review

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 catch. i've added functional indexes for both columns.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The indexes themselves now have the intended expressions, but the users lookup still filters on lower(users::username). PostgreSQL cannot use the canon_username(username) index for that expression, and the lookup does not canonicalize - and _. Could we change the query to use canon_username() consistently on both sides and add coverage for the separator case?

@moskirathe moskirathe Aug 4, 2026

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.

updated to use canon_username and added coverage for separator cases. thanks!

Comment thread src/controllers/krate/owners.rs Outdated
Comment thread src/bin/crates-admin/delete_crate.rs Outdated
Comment thread src/controllers/krate/owners.rs
@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch from 454d638 to a420795 Compare July 20, 2026 17:57
@rustbot

This comment has been minimized.

@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch 2 times, most recently from f43ce65 to 64efb97 Compare July 20, 2026 18:13
@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch 2 times, most recently from 542309c to 6811381 Compare July 20, 2026 18:33
@moskirathe

Copy link
Copy Markdown
Contributor Author

@Turbo87 thanks for the review! I've addressed your comments. the pr is ready for re-review.

@moskirathe
moskirathe requested a review from Turbo87 July 21, 2026 05:21
@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch 2 times, most recently from a228f14 to 8a44eae Compare July 21, 2026 06:00
@rustbot

This comment has been minimized.

pub gh_login: String,
// Rename this field to gh_login when gh_login is removed from this struct.
#[diesel(select_expression = oauth_github::login.nullable())]
pub gh_username: Option<String>,

@moskirathe moskirathe Jul 22, 2026

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.

this is the same as gh_login but reading from oauth_github instead of the users table. I considered a change to stop reading from users.gh_login and start reading from oauth_github.login throughout the codebase instead (similar to #14258), but I think that would be a much bigger change that would warrant being tackled in a separate pr

View changes since the review

@moskirathe

Copy link
Copy Markdown
Contributor Author

@carols10cents would also love your review on this when you have some time

@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch from 185aa74 to 1f3ff8a Compare July 25, 2026 14:40
@rustbot

This comment has been minimized.

@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch from 1f3ff8a to 4c528c3 Compare July 25, 2026 14:44

@carols10cents carols10cents left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Took a quick look and saw one little thing, and I agree with the comments @Turbo87 made.

View changes since this review

Comment thread src/controllers/krate/owners.rs Outdated
},
/// GitHub user (e.g. `github:username`).
GitHub(&'a str),
/// crates.io user (`crates.io:username`).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this comment should be:

Suggested change
/// crates.io user (`crates.io:username`).
/// crates.io user (`cratesio:username`).

based on the rest of this PR, right?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'd prefer crates.io. is there a technical reason why we would need to drop the .?

@moskirathe moskirathe Aug 4, 2026

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.

there is no technical reason for dropping the . here, but i updated this to be consistent with all other comments and error messages that include cratesio:username. i don't have a strong preference for either cratesio or crates.io, so happy to update this to crates.io everywhere if you think it would be better.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yeah, I think unless there is a technical reason why we would need to avoid the . character we should use our usual brand name and adjust it in the other "comments and error messages" too :)

@rustbot

This comment has been minimized.

@moskirathe
moskirathe force-pushed the cargo-owner-username-disambiguation branch from 3e8fc63 to b09e6a3 Compare August 4, 2026 22:13
@rustbot

rustbot commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@moskirathe

Copy link
Copy Markdown
Contributor Author

@Turbo87 @carols10cents ready for re-review. thanks!

Comment thread migrations/2026-07-18-120000-0000_add_users_username_index/up.sql Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement username disambiguation in cargo owner param handling and error messages

4 participants