From 0e9bd4ff970337cf9454b0adc549faa3098cb15c Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Thu, 6 Feb 2020 13:53:38 -0500 Subject: [PATCH 1/5] Add a failing test for inactive users getting invites over active ones --- src/tests/owners.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/tests/owners.rs b/src/tests/owners.rs index 58ea26f13ab..cad282f8b49 100644 --- a/src/tests/owners.rs +++ b/src/tests/owners.rs @@ -366,3 +366,36 @@ fn test_decline_invitation() { let json = anon.show_crate_owners("decline_invitation"); assert_eq!(json.users.len(), 1); } + +#[test] +fn inactive_users_dont_get_invitations() { + use cargo_registry::models::NewUser; + use std::borrow::Cow; + + let (app, _, owner, owner_token) = TestApp::init().with_token(); + let owner = owner.as_model(); + + // An inactive user with gh_id -1 and an active user with a non-negative gh_id both exist + let invited_gh_login = "user_bar"; + let krate_name = "inactive_test"; + + app.db(|conn| { + NewUser { + gh_id: -1, + gh_login: invited_gh_login, + name: None, + gh_avatar: None, + gh_access_token: Cow::Borrowed("some random token"), + } + .create_or_update(None, conn) + .unwrap(); + CrateBuilder::new(krate_name, owner.id).expect_build(conn); + }); + + let invited_user = app.db_new_user(invited_gh_login); + + owner_token.add_user_owner(krate_name, invited_user.as_model()); + + let json = invited_user.list_invitations(); + assert_eq!(json.crate_owner_invitations.len(), 1); +} From 2eadd7c3bcb92e530a47820298f1320c6a535319 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Thu, 6 Feb 2020 14:09:14 -0500 Subject: [PATCH 2/5] Exclude inactive accounts when considering which user to invite Accounts where the gh_id is -1 are accounts we know are inactive and should never be invited to own crates --- src/models/owner.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/models/owner.rs b/src/models/owner.rs index 88d6ec0fb6a..3bf7050d7f8 100644 --- a/src/models/owner.rs +++ b/src/models/owner.rs @@ -72,6 +72,7 @@ impl Owner { } else { users::table .filter(users::gh_login.eq(name)) + .filter(users::gh_id.ne(-1)) .first(conn) .map(Owner::User) .map_err(|_| cargo_err(&format_args!("could not find user with login `{}`", name))) From 12c5a5526e571157c61727214adcc7ecd7753cff Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Thu, 6 Feb 2020 14:18:49 -0500 Subject: [PATCH 3/5] Add a failing test for inviting a user with an older gh_id Assuming gh_id always increases, if we have multiple users with the same gh_login, the one with the higher id is the most recently valid account we know about --- src/tests/owners.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/tests/owners.rs b/src/tests/owners.rs index cad282f8b49..72a86817b43 100644 --- a/src/tests/owners.rs +++ b/src/tests/owners.rs @@ -399,3 +399,25 @@ fn inactive_users_dont_get_invitations() { let json = invited_user.list_invitations(); assert_eq!(json.crate_owner_invitations.len(), 1); } + +#[test] +fn highest_gh_id_is_most_recent_account_we_know_of() { + let (app, _, owner, owner_token) = TestApp::init().with_token(); + let owner = owner.as_model(); + + // An inactive user with a lower gh_id and an active user with a higher gh_id both exist + let invited_gh_login = "user_bar"; + let krate_name = "newer_user_test"; + + // This user will get a lower gh_id, given how crate::new_user works + app.db_new_user(invited_gh_login); + + let invited_user = app.db_new_user(invited_gh_login); + + app.db(|conn| { CrateBuilder::new(krate_name, owner.id).expect_build(conn); }); + + owner_token.add_user_owner(krate_name, invited_user.as_model()); + + let json = invited_user.list_invitations(); + assert_eq!(json.crate_owner_invitations.len(), 1); +} From 6cfa29db8680557bb31d7e83d5c70453af6c55a5 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Thu, 6 Feb 2020 14:25:52 -0500 Subject: [PATCH 4/5] Invite the account with the highest github id --- src/models/owner.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/models/owner.rs b/src/models/owner.rs index 3bf7050d7f8..8b41c04540d 100644 --- a/src/models/owner.rs +++ b/src/models/owner.rs @@ -73,6 +73,7 @@ impl Owner { users::table .filter(users::gh_login.eq(name)) .filter(users::gh_id.ne(-1)) + .order(users::gh_id.desc()) .first(conn) .map(Owner::User) .map_err(|_| cargo_err(&format_args!("could not find user with login `{}`", name))) From 61c840b72834eb573c572fc28e758445a0365137 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Thu, 6 Feb 2020 14:33:33 -0500 Subject: [PATCH 5/5] Format --- src/tests/owners.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/owners.rs b/src/tests/owners.rs index 72a86817b43..c37a48b2020 100644 --- a/src/tests/owners.rs +++ b/src/tests/owners.rs @@ -414,7 +414,9 @@ fn highest_gh_id_is_most_recent_account_we_know_of() { let invited_user = app.db_new_user(invited_gh_login); - app.db(|conn| { CrateBuilder::new(krate_name, owner.id).expect_build(conn); }); + app.db(|conn| { + CrateBuilder::new(krate_name, owner.id).expect_build(conn); + }); owner_token.add_user_owner(krate_name, invited_user.as_model());