Skip to content

Commit 7ebcfe7

Browse files
committed
Fix owner removal check.
1 parent 055df9b commit 7ebcfe7

File tree

3 files changed

+39
-17
lines changed

3 files changed

+39
-17
lines changed

src/controllers/krate/owners.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,28 +111,31 @@ fn modify_owners(req: &mut dyn Request, add: bool) -> CargoResult<Response> {
111111
}
112112
}
113113

114-
let mut msgs = Vec::new();
115-
116-
for login in &logins {
117-
if add {
114+
let comma_sep_msg = if add {
115+
let mut msgs = Vec::new();
116+
for login in &logins {
118117
let login_test =
119118
|owner: &Owner| owner.login().to_lowercase() == *login.to_lowercase();
120119
if owners.iter().any(login_test) {
121120
return Err(human(&format_args!("`{}` is already an owner", login)));
122121
}
123-
let msg = krate.owner_add(req.app(), &conn, user, login)?;
122+
let msg = krate.owner_add(app, &conn, user, login)?;
124123
msgs.push(msg);
125-
} else {
126-
// Removing the team that gives you rights is prevented because
127-
// team members only have Rights::Publish
128-
if owners.len() == 1 {
129-
return Err(human("cannot remove the sole owner of a crate"));
130-
}
131-
krate.owner_remove(req.app(), &conn, user, login)?;
132124
}
133-
}
134-
135-
let comma_sep_msg = msgs.join(",");
125+
msgs.join(",")
126+
} else {
127+
for login in &logins {
128+
krate.owner_remove(app, &conn, user, login)?;
129+
}
130+
if User::owning(&krate, &conn)?.is_empty() {
131+
return Err(human(
132+
"cannot remove all individual owners of a crate. \
133+
Team member don't have permission to modify owners, so \
134+
at least one individual owner is required.",
135+
));
136+
}
137+
"owners successfully removed".to_owned()
138+
};
136139

137140
#[derive(Serialize)]
138141
struct R {

src/tests/owners.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ fn owners_can_remove_self() {
139139
.bad_with_status(200);
140140
assert!(json.errors[0]
141141
.detail
142-
.contains("cannot remove the sole owner of a crate"));
142+
.contains("cannot remove all individual owners of a crate"));
143143

144144
create_and_add_owner(&app, &token, "secondowner", &krate);
145145

@@ -170,6 +170,15 @@ fn modify_multiple_owners() {
170170
let user2 = create_and_add_owner(&app, &token, "user2", &krate);
171171
let user3 = create_and_add_owner(&app, &token, "user3", &krate);
172172

173+
// Deleting all owners is not allowed.
174+
let json = token
175+
.remove_named_owners("owners_multiple", &[username, "user2", "user3"])
176+
.bad_with_status(200);
177+
assert!(&json.errors[0]
178+
.detail
179+
.contains("cannot remove all individual owners of a crate"));
180+
assert_eq!(app.db(|conn| krate.owners(&conn).unwrap()).len(), 3);
181+
173182
// Deleting two owners at once is allowed.
174183
let json = token
175184
.remove_named_owners("owners_multiple", &["user2", "user3"])

src/tests/team.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ fn add_team_as_non_member() {
184184
#[test]
185185
fn remove_team_as_named_owner() {
186186
let (app, _) = TestApp::with_proxy().empty();
187-
let user_on_both_teams = app.db_new_user(mock_user_on_both_teams().gh_login);
187+
let username = mock_user_on_both_teams().gh_login;
188+
let user_on_both_teams = app.db_new_user(username);
188189
let token_on_both_teams = user_on_both_teams.db_new_token("arbitrary token name");
189190

190191
app.db(|conn| {
@@ -195,6 +196,15 @@ fn remove_team_as_named_owner() {
195196
.add_named_owner("foo_remove_team", "github:crates-test-org:core")
196197
.good();
197198

199+
// Removing the individual owner is not allowed, since team members don't
200+
// have permission to manage ownership
201+
let json = token_on_both_teams
202+
.remove_named_owner("foo_remove_team", username)
203+
.bad_with_status(200);
204+
assert!(json.errors[0]
205+
.detail
206+
.contains("cannot remove all individual owners of a crate"));
207+
198208
token_on_both_teams
199209
.remove_named_owner("foo_remove_team", "github:crates-test-org:core")
200210
.good();

0 commit comments

Comments
 (0)