-
Notifications
You must be signed in to change notification settings - Fork 626
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
We shouldn't let you add someone as an owner without their consent #924
Comments
Workflow sketch:
|
Unclear what the process for teams should be. I think you need to be a member of a team to add it already? I don't really remember. |
Running cargo publish should tell the user that they are still pending verification. For teams, would it be feasible to keep people's verification status on a per team basis? i.e. you have publishing rights as long as you're on that team but you have to verify that you want those rights before you can actually publish. Keeping that kind of information isn't bullet proof though because people can leave or be removed from teams so I don't know how you'd verify them again after that. A future feature that would be nice would be something that would allow you to block people from requesting to add you. Or maybe that could be done for the time being by just leaving the invite pending? We could streamline the consent process by asking them if they consent during cargo publish. That would look like this:
Also to consider when adding consent: how do people remove consent later? This needs to be thought about both from the perspective of the old owner and the new owner since either may want to remove publishing rights from new owner. Sorry for just dropping ideas here but I wanted to make sure these things get considered. |
Also I just checked and my crates user page doesn't actually list crates published by the teams that I'm on, so maybe teams isn't as high of a priority for this? I can't think of a way right now that someone could abuse GitHub organizations to spam, annoy or abuse someone through crates.io. |
so, one large blocking issue here is that crates.io does not have guaranteed email information for users as GitHub does not reliably send it. |
@ashleygwilliams Hmm. If we ask for the consent at publish time as well as do the email confirmation, we don't necessarily need people's emails. We just won't list them as owners until they've consented. Could also add a custom cargo command just to accept the invitation to be an owner. |
Also to address the email thing, when I was working with the passport-github package, I found out that they actually do a separate API call to fetch the email after authentication. Maybe that could work as a longer term solution for getting emails? It's not ideal, but it does seem to work. |
so i think the first step here is to improve the crates.io ACL to include and require an email address. i'm down for any strategy re: that, so @sunjay your suggestion seems good to me. backfill, however, is gonna be a large task- either requiring a lot of user effort or a kinda tricky migration. the next thing is that, afaik, since we never reliably had email addresses, we don't have any mailer service... at all. so writing one of those and making sure it works for non critical things, is the next step. probably a welcome email or something. these are two Very Large changes to make. once they are in place and stable, i think figuring out how to properly implement an access invite service would be the next step. (full disclosure: i care about this issue a lot. but, even npm does not have this yet. i am also not happy about that, but it is a lot of work and it's work that needs to be done right.) |
Natalie is working on the email ish #808 so emails are coming. |
By mailer service do you mean something that sends emails? What about using something existing like mailgun? The pricing is really great even at scale. I care about this issue a lot too and would be happy to donate my time in a few weeks to making it happen. (I've never worked on this codebase so I can't do it alone!) I can help with the Rust backend stuff and probably the migration too. I haven't used Ember in about 3 years so I'm probably not going to be able to do any changes we need there. Maybe we can even figure out a way to fetch emails lazily (and then store them) as we need to. To prevent being spammy, it might be prudent to also ask people if we can email them at all. At minimum I can help in the planning and figuring out to work this in and make sure the experience is right. Like you said, it's a lot of work and it's work that needs to be done right. Edit: just saw @carols10cents comment. 🎉 |
I think I kinda just like @sunjay's suggestion of hooking verification into the publish process? Absolutely no notification if you've been added as an owner (so there's no way to even spam someone with ownership requests), and you can claim ownership the moment it's actually relevant (when you need to publish). We could do the same thing for owner --remove, in the case of an ownership transfer (and then it's kinda like an atomic transfer op, which is neat). Presumably, if you're adding someone as an owner, you have another communication channel to inform them that you did this. |
If we go with just implementing this through the cargo commands then this mostly becomes a task of adding some things to the API and database, then modifying the appropriate cargo commands. What do you think @ashleygwilliams? We could have something like |
Reflecting further on teams: I don't think we need to worry about them. You need to be on a team to add it (partly this is because Github is incredibly unreliable in acknowledging a team's existence unless you're on it), so basically the abuse vector is someone on a team is trying to harass the entire team? Only case I can think of is someone rage quitting a community, and in that case that person already has plenty of gas to do worse things, i would think. |
i am coming around to this CLI solution. it's really elegant actually. i think people will eventually ask for email integration, but that gives us time to build all that shenanigans out. good call @sunjay ! |
Thanks! I'll admit I felt apprehensive about sharing the idea in the first place given that I've never even touched the code in this repo. I'm happy to hear you both liking it. Thanks for being open to that. 😊 I can help with the cargo integration stuff in about a week or so. What needs to be done from the crates.io side? I think much of your initial comments still apply just without the email stuff. |
A small but notable issue with CI-based solutions is that you won't be able to transfer ownership to people with old Cargo installs. This mostly just means we should delay flipping the switch in the backend for a bit. I don't think that's a big deal? |
It might be possible to auto-confirm anyone with an old cargo version who tries to perform an owner action, but idk if that's possible or reasonable |
I need a bit of time to think about this but I will absolutely get back to you within a day or so :) |
@gankro is it a reasonable solution to return an error from crates.io to anyone who is using an old version? The error could contain a message asking them to upgrade their cargo version and a link to instructions on how to do so. The new version would handle this error and instead ask for their consent. I think it's reasonable to say that all current owners don't need to be confirmed and that this change only applies for newly added owners going further in the future. Thanks @carols10cents! |
Ok here's what I'm thinking for the overall flow:
Other thoughts/constraints/things I would expect test cases for if applicable:
Implementation thoughts:
I'm going to submit this comment because it's getting long, then I'm going to edit the issue description with a list of tasks that I think need to be done and how we might break this into smaller deployable pieces. |
Ok, I've added a list of things to the issue description that I think need to be done in the form of a plan that splits these steps into smaller, independently mergeable and deployable chunks. Am I forgetting anything that anyone can think of? @sunjay do these steps all make sense? Please ask questions if anything is unclear, either now or during implementation! To address some other things people brought up in the comments:
I'm not a fan of this because currently this enum consists of
Agreed! I think blocking could be done as a separate issue from this; I've filed #928 for this and I can flesh that out a bit more as we figure out how this issue is going to go.
It's possible to remove owners today, I think that feature covers this aside from making removal also remove pending/declined invitations. Regarding teams:
Also, I'm going to have Natalie update #808 with our plans on emails and address questions about that; please check over there later if you have email thoughts :) Once we have email support in general, we can decide if we want to send email notifications that someone has invited you to own a crate or not, but I think for now the CLI/UI solution I've outlined in the description should be enough, and it sounds like that was the conclusion everyone was coming to as well. |
Sounds good, some quick notes:
I would advise against this, as it strikes me as a recipe for a very bad surprise for whoever owns a crate years later.
I'm 95% sure making Pending an OwnerKind avoids this issue, because:
That said I'm sympathetic to this as a broader longterm maintenance concern. It's a reasonable hardening strategy. I also agree it's a bit sketchy in terms of overloading. (PendingUser?)
An incredibly bare bones solution might be any GET to |
The plan looks great and I have lots of comments and some ideas that I think we should consider. I'll need a few days to get back to you as this week is particularly hectic for me. Expect my reply on Friday or Saturday. Thanks for your patience and thanks for continuing to include me in the discussions. This is fun. :) |
Thanks for giving me a few days! Sorry it took me longer than expected for me to get back to you all. @carols10cents has done a wonderful job designing everything so if it's alright I'll just address a few specific points I had some comments about. :)
This was more of a convenience feature. The idea was that instead of having to execute a separate command at publish, we would give them the option to accept the invitation right when they need it. This would be something in addition to the What will be necessary is to have a useful error message when someone tries to publish without having accepted the invitation first. The tricky part as you've mentioned is to make the error backwards-compatible so that people with older cargo versions can still know to upgrade or whatever.
Regarding this, I think it's alright for now to just make it so you can send someone an invitation again after it is declined. We're not sending emails right now so there isn't actually much abuse that can happen. I think a Having said that, I think it would be a good idea to brainstorm a list of ways people can abuse using cargo and then systematically address those things. I already have somethings that I have thought about which I would be happy to share.
I think
This makes sense. To transfer ownership from user1 to user2:
This seems like a fairly natural flow for this to take.
Could we have the URL only option that @gankro suggested? We would only need people to upgrade their cargo if they want to accept/decline/block invitations. Everything else would remain the same. Is it still not sufficient to just produce a message saying that they need to have cargo version x.x or higher? We could make this very clear in the documentation too. I'm asking because I think strict backwards compatibility while desirable is really hard to maintain and the cases where people would need to be able to do this are few. If we were to stick to command line only for now, we would still add the web UI in the future. It just wouldn't be mandatory for the release of invitations. (I think prioritizing the bare minimum implementation is really important.)
This is definitely important to know. :)
If we do add something to publish, I don't think it should be automatic. I think we should ask the user to say yes or no to whether they want to accept the invitation. Or at least hit enter to confirm. I think it's important that they know that they're accepting an invitation instead of it happening automatically without their knowledge.
I think the basic flow is really clear. Here's how I see it:
There's some more I want to say but this comment is long and I've rewritten it 4 times over the past few days so I'm going to submit it. Please don't hesitate to give me any feedback about any of this! :) |
One thing I would really like as part of all of this abuse prevention work (but not this issue specifically) is to setup some integration tests that actually simulate abuse on a test user. I am happy to help out with this since I have some ideas already. Some important points about this:
I'm not talking about load testing or anything else related to that. I would specifically like to help setup scenarios that demonstrate that abusing a user isn't possible. Even though we definitely can't cover every case with this, it would be nice to have the infrastructure setup so that if in the future someone finds a way to abuse the system, we can write a regression test which demonstrates that the issue has been fixed and remains fixed. I have to catch a flight right now but I'll post some more ideas and the things I have in mind later. I can move this to another issue too since this is kind of out of scope for what we're focusing on. |
Thank you for your comments @sunjay!
Yes, I don't think integrating acceptance with publish is necessary for an MVP of this feature.
Enterprises and linux distributions are not able to just upgrade whenever. So no, we can't just make people upgrade in order to be able to accept/decline publishing invitations, unfortunately.
Since we can't make people upgrade, the bare minimum implementation can be the web UI, and we can add the command line UI in the future.
Please open a new issue to discuss the more general things you have in mind-- I'd be interested to hear what you're thinking about that couldn't be implemented with the tests we have today that run in CI and why they'd have to run against the live site. |
1045: Sending an email to a user to confirm their email address r=carols10cents This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see [this comment](#808 (comment)) I left which should fully explain the changes made, as well as parts 1 and 3. In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and `email_verified` is set to `true` in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account. This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.
1045: Sending an email to a user to confirm their email address r=carols10cents This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see [this comment](#808 (comment)) I left which should fully explain the changes made, as well as parts 1 and 3. In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and `email_verified` is set to `true` in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account. This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.
1045: Sending an email to a user to confirm their email address r=carols10cents This PR addresses issue #808, allow editing your own email address. Following the discussion on the issue, this implements the second of three parts, the ability to send a confirmation email to a user for verification. For a full explanation of the issue, see [this comment](#808 (comment)) I left which should fully explain the changes made, as well as parts 1 and 3. In short, I added two tables to the database: one for the user's email, the other for a confirmation token associated with the email. Once the user clicks the link sent, the associated token is deleted from the token table and `email_verified` is set to `true` in the email table. It is indicated to the user if they have not verified their email on the account settings page, a message and email resend button being displayed. Sending emails requires Mailgun to be added to the crates.io Heroku account. This has applications for issue #924 in that we should now be able to send an email to a user, if they have added their email. I know there was a lot of discussion on that issue regarding the ability to send users an email to be added as an owner.
1057: Frontend page for listing pending owner invites r=carols10cents This implements the last checkbox in Deployable chunk 1: Listing invitations of issue #924. The frontend route created, `/me/pending-invites`, calls the API route previously created and will list all current invitations associated with the user's account. Although the buttons for accepting/denying invitations have been added, they do not currently do anything as that chunk has not been implemented yet (Deployable chunks 2 & 3). It was easier to add them now for styling purposes. The page isn't linked to anywhere but can be accessed via `crates.io/me/pending-invites` if logged in.
1073: Accept owner invites r=carols10cents This implements deployable chunk 2, accepting invitations of issue #924. I created a new route, `/me/crate_invitations/:crate_id` where a `PUT` request is submitted to. The request body contains the invitation information along with a boolean field `accepted`, indicating whether or not the invitation was accepted. This same route can then also be used for the decline route, a matter of toggling the `accepted` field. When an invitation is accepted, the user should receive a message where the invitation used to be acknowledging the successful addition. If an error occurs, a message should also appear indicating so.
1085: Decline owner invites r=carols10cents This implements deployable chunk 3: declining invitations of issue #924. The api route for declining an invite is the same as for accepting an invite. To know that an invite is being declined instead of accepted, the `accepted` field passed to the backend is set to `false`. If declined, the invite should be replaced with a message to the user confirming that they declined the invitation for the crate.
Owner invite messages This PR addresses issue #4537, the plan for `cargo owner --add` requiring invitations in Cargo and the encompassing issue [#924](rust-lang/crates.io#924), requiring an invite to add someone as an owner in Crates.io. Regarding the Cargo issue, we went with Option 2, changing the `add_owners` function to decode a struct sent from Crates containing a `boolean` and `String`, the `boolean` being the response status and `String` being the success message. This may sound redundant however we concluded that using both of these fields were necessary to support older versions of Cargo - if we changed Crates.io to only return the `String` message on success this would likely break systems using the older version of `add_owner` expecting a response containing a `boolean`. Matching this schema, `add_owners` on the Crates.io side will soon return a struct containing a `boolean` and `String`, and instead of adding a new crate owner to the database will add a crate owner invite. If successful, `modify_owners` now prints the message sent from Crates.io instead of the old hardcoded message. Resolves #4537
1108: Require owner approval r=carols10cents This PR addresses issue #924, adding owners with their consent, deployable chunk 4. It implements the Crates functionality necessary for Cargo to invite a user to be an owner instead of automatically adding any user to be an owner of any crate. These changes correlate with the Cargo changes made in [this PR](rust-lang/cargo#4551). Function `owner_add` now creates an owner invitation instead of adding a user to be an owner, and returns a `boolean` okay value with a `String` message indicating that the user was invited to be an owner of the crate. This `boolean` okay value is not explicitly used for anything but is necessary to support older versions of Cargo, without which older versions will fail to decode only a `String` response.
Maybe trying to publish new version of a crate when you are invited should count as implied acceptance? This way user can just not bother with accepting or declining anything. |
This is a vector for abuse. We should require confirmation from the person being added before adding them, just like Github does for adding someone as an owner to a repo/team.
Implementation steps added by carols10cents:
The following tasks assume we'll need a web UI for this in order to support users with arbitrarily old versions of cargo. I don't think crates.io can have a state where this feature is "half on", and even if we did, I think we'd have to stay in that state forever because people are always going to be using older versions of cargo. I'm open to hearing ideas on this issue though!
Crates.io Deployable chunk 1: Listing invitations
cargo owner --add
status of the invitiationthe only invitations in this table should be pending invitations; accepted invitations can be removed from this table and records added to crate_owners instead; declined invitations can be removed from this table.cargo owner --add
in this PR, add records to this table either manually withpsql
or in testsCrates.io Deployable chunk 2: Accepting invitations
Still not creating records in crate_owner_invitations when
cargo owner --add
is runCrates.io Deployable chunk 3: Declining invitations
Still not creating records in crate_owner_invitations when
cargo owner --add
is runCrates.io Deployable chunk 4: Requiring approval for ownership
Assume no changes to cargo, because we can't change old cargo anyway!
cargo owner --add
for a user (not a team):cargo publish
on a crate where there's a pending invitation to add them as an owner:Document this requirement in the cargo owner docs (which currently live in cargo's repo)split into Document that adding someone as an owner now invites them, not adds immediately cargo#4599Super nice would be some sort of notification that shows up anywhere on crates.io and lets you know you have outstanding ownership invitations and you should go to the invitation list page to approve or decline them (thank you for this idea @natboehm!!!)split into Add some sort of notification that you have invitations to own a crate #1116Cargo deployable chunk 5: adding CLI support for accept/decline
split into rust-lang/cargo#4600
Crates.io deployable chunk 6: UI for adding someone as an owner
split into #1117
The text was updated successfully, but these errors were encountered: