This should only require changes to the crates.io owners API in how it handles parameters and what error messages it might return. However, if changes to cargo would make this change more user-friendly, a cargo issue should be opened to discuss those changes with the Cargo Team.
From the RFC:
If you run cargo owner --add example_username and the account's crates.io username differs from
the GitHub username associated with the account, the command will error with a message similar to:
$ cargo owner --add example_username
error: username `example_username` is possibly ambiguous
Caused by:
The crates.io account `example_username` is associated with:
- https://github.com/something_else
- [any other accounts once we have that ability]
To confirm this is the account you want to add, please run one of the following:
$ cargo owner --add cratesio:example_username
$ cargo owner --add github:something_else
If this is not the account you want to add, verify the crates.io username of the account you want.
Returning an error and requesting the user re-run a command with a disambiguation prefix to confirm
is the easiest way to maintain compatibility with existing versions of Cargo. With some additional
work on Cargo, newer versions could be made that only require a y or n confirmation; see the
"Prior Art" section on Keybase for one possibility.
The current API request for inviting user owners or adding team owners consists of a PUT request
to /api/v1/crates/[crate name]/owners with the following JSON (using a request to add user
some_user and team some_team from the some_org GitHub organization as an example):
{
"owners": [
"some_user",
"github:some_org:some_team"
]
}
The backend processes owner strings starting with github and containing two colons as an organization name and a team name; this behavior will be unchanged.
This request will begin to accept owners specified by strings containing one colon and starting
with cratesio1, github, and any other OAuth service we eventually add. An owner specification
of cratesio:some_user will only query users.username and not any other table. An owner
specification of github:some_user will only query oauth_github.login and not any other table.
As other services are added, we will add a prefix that can be used to only look up usernames in
that service's table. If the username isn't found in the specified table (say, the cratesio
prefix that specfies the users table), the request will return an error even if the username is
in another table (such as the oauth_github table, for this example).
If the owner specification doesn't contain any colons, the behavior is similar to that of the users
API: we assume it's a crates.io username and look it up in users.username only. We will also
query the oauth_github table to see if the crates.io username and GitHub username match. If they
do match, we will continue with adding this user as an owner. If they don't match, we will return
an error containing information about the mismatch and asking the user to rerun the command with a
service prefix and colon in front of the username to ensure we're adding the account they mean to
add.
An error response would look something like this:
{
"errors": [
{
"detail": "username `some_user` is possibly ambiguous. The crates.io account
`example_username` is associated with:
- https://github.com/something_else
- [any other accounts once we have that ability]
To confirm this is the account you want to add, please run one of the following:
$ cargo owner --add cratesio:example_username
$ cargo owner --add github:something_else
If this is not the account you want to add, verify the crates.io username of the account you want.
"
}
]
}
This maintains backwards compatibilty with existing cargo versions. We could do additional work
on Cargo and add more fields if a newer version of Cargo is making the request, to support a
"confirmation" flow as presented in the "Prior Art" section under Keybase.
The "remove owner" API would behave similarly as the "add owner" API - it will support cratesio:
or github: (etc) prefixes to usernames and will return an error if there is no current owner with
the specified username in the specified service's table. If given a username without a prefix, the
"remove owner" API will only return an error if there are two current owners of the crate that have
the username on different services, and will then ask the user to rerun with a prefix to
disambiguate. That is, if the user runs cargo owner --remove some_user and there's a crates.io
user with the users.username of some_user and a different account that has the GitHub user
some_user, the API will only return an error if both these accounts are owners of the crate the
request is being made about. If only one account is an owner, that account will be removed as an
owner.
Also read some of the comments on the RFC about possible information leakage via error messages and keep those comments in mind during implementation.
Even though it's not currently possible to have a crates.io username that's different from your GitHub username in the live crates.io site, it should be possible to create a users record with a username value that's different from the associated oauth_github.login in tests.
This should only require changes to the crates.io owners API in how it handles parameters and what error messages it might return. However, if changes to
cargowould make this change more user-friendly, a cargo issue should be opened to discuss those changes with the Cargo Team.From the RFC:
Also read some of the comments on the RFC about possible information leakage via error messages and keep those comments in mind during implementation.
Even though it's not currently possible to have a crates.io username that's different from your GitHub username in the live crates.io site, it should be possible to create a
usersrecord with ausernamevalue that's different from the associatedoauth_github.loginin tests.Footnotes
The
cratesioprefix may possibly becrates.io,crates_io,crates-io, or all of them,to be bikeshed during implementation. ↩