Skip to content

Commit 482020c

Browse files
committed
Extract rights into a model used by User
1 parent 4d9580b commit 482020c

File tree

7 files changed

+40
-43
lines changed

7 files changed

+40
-43
lines changed

src/controllers/krate/owners.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
33
use serde_json;
44

5-
use owner::rights;
6-
75
use controllers::prelude::*;
86
use views::EncodableOwner;
97
use models::{Crate, Owner, Rights, Team, User};
@@ -79,7 +77,7 @@ fn modify_owners(req: &mut Request, add: bool) -> CargoResult<Response> {
7977
let krate = Crate::by_name(&req.params()["crate_id"]).first::<Crate>(&*conn)?;
8078
let owners = krate.owners(&conn)?;
8179

82-
match rights(req.app(), &owners, user)? {
80+
match user.rights(req.app(), &owners)? {
8381
Rights::Full => {}
8482
// Yes!
8583
Rights::Publish => {

src/controllers/krate/publish.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use serde_json;
99

1010
use dependency;
1111
use git;
12-
use owner::rights;
1312
use render;
1413
use util::{read_fill, read_le_u32};
1514
use util::{internal, ChainError};
@@ -72,7 +71,7 @@ pub fn publish(req: &mut Request) -> CargoResult<Response> {
7271
let krate = persist.create_or_update(&conn, license_file, user.id)?;
7372

7473
let owners = krate.owners(&conn)?;
75-
if rights(req.app(), &owners, &user)? < Rights::Publish {
74+
if user.rights(req.app(), &owners)? < Rights::Publish {
7675
return Err(human(
7776
"this crate exists but you don't seem to be an owner. \
7877
If you believe this is a mistake, perhaps you need \

src/models/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ pub use download::VersionDownload;
66
pub use self::follow::Follow;
77
pub use self::keyword::{CrateKeyword, Keyword};
88
pub use self::krate::{Crate, CrateDownload, NewCrate};
9-
pub use owner::{CrateOwner, NewTeam, Owner, OwnerKind, Rights, Team};
9+
pub use owner::{CrateOwner, NewTeam, Owner, OwnerKind, Team};
10+
pub use self::rights::Rights;
1011
pub use user::{Email, NewUser, User};
1112
pub use token::ApiToken;
1213
pub use version::{NewVersion, Version};
@@ -18,3 +19,4 @@ mod category;
1819
mod follow;
1920
mod keyword;
2021
pub mod krate;
22+
mod rights;

src/models/rights.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// Access rights to the crate (publishing and ownership management)
2+
/// NOTE: The order of these variants matters!
3+
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
4+
pub enum Rights {
5+
None,
6+
Publish,
7+
Full,
8+
}

src/owner.rs

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use github;
55
use util::{human, CargoResult};
66

77
use models::{Crate, User};
8-
use schema::*;
8+
use schema::{crate_owners, teams, users};
99

1010
#[derive(Insertable, Associations, Identifiable, Debug, Clone, Copy)]
1111
#[belongs_to(Crate)]
@@ -72,15 +72,6 @@ pub struct EncodableOwner {
7272
pub avatar: Option<String>,
7373
}
7474

75-
/// Access rights to the crate (publishing and ownership management)
76-
/// NOTE: The order of these variants matters!
77-
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
78-
pub enum Rights {
79-
None,
80-
Publish,
81-
Full,
82-
}
83-
8475
#[derive(Insertable, AsChangeset, Debug)]
8576
#[table_name = "teams"]
8677
pub struct NewTeam<'a> {
@@ -385,26 +376,3 @@ impl Owner {
385376
}
386377
}
387378
}
388-
389-
/// Given this set of owners, determines the strongest rights the
390-
/// given user has.
391-
///
392-
/// Shortcircuits on `Full` because you can't beat it. In practice we'll always
393-
/// see `[user, user, user, ..., team, team, team]`, so we could shortcircuit on
394-
/// `Publish` as well, but this is a non-obvious invariant so we don't bother.
395-
/// Sweet free optimization if teams are proving burdensome to check.
396-
/// More than one team isn't really expected, though.
397-
pub fn rights(app: &App, owners: &[Owner], user: &User) -> CargoResult<Rights> {
398-
let mut best = Rights::None;
399-
for owner in owners {
400-
match *owner {
401-
Owner::User(ref other_user) => if other_user.id == user.id {
402-
return Ok(Rights::Full);
403-
},
404-
Owner::Team(ref team) => if team.contains_user(app, user)? {
405-
best = Rights::Publish;
406-
},
407-
}
408-
}
409-
Ok(best)
410-
}

src/user/mod.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rand::{thread_rng, Rng};
88
use std::borrow::Cow;
99
use serde_json;
1010

11-
use app::RequestApp;
11+
use app::{App, RequestApp};
1212
use db::RequestTransaction;
1313
use controllers::helpers::Paginate;
1414
use util::{bad_request, human, CargoResult, RequestUtils};
@@ -20,7 +20,7 @@ pub use self::middleware::{AuthenticationSource, Middleware, RequestUser};
2020
pub mod middleware;
2121

2222
use views::{EncodableTeam, EncodableVersion};
23-
use models::{Crate, CrateOwner, Follow, Owner, OwnerKind, Team, Version};
23+
use models::{Crate, CrateOwner, Follow, Owner, OwnerKind, Rights, Team, Version};
2424
use schema::*;
2525

2626
/// The model representing a row in the `users` database table.
@@ -190,6 +190,29 @@ impl User {
190190
Ok(users.collect())
191191
}
192192

193+
/// Given this set of owners, determines the strongest rights the
194+
/// user has.
195+
///
196+
/// Shortcircuits on `Full` because you can't beat it. In practice we'll always
197+
/// see `[user, user, user, ..., team, team, team]`, so we could shortcircuit on
198+
/// `Publish` as well, but this is a non-obvious invariant so we don't bother.
199+
/// Sweet free optimization if teams are proving burdensome to check.
200+
/// More than one team isn't really expected, though.
201+
pub fn rights(&self, app: &App, owners: &[Owner]) -> CargoResult<Rights> {
202+
let mut best = Rights::None;
203+
for owner in owners {
204+
match *owner {
205+
Owner::User(ref other_user) => if other_user.id == self.id {
206+
return Ok(Rights::Full);
207+
},
208+
Owner::Team(ref team) => if team.contains_user(app, self)? {
209+
best = Rights::Publish;
210+
},
211+
}
212+
}
213+
Ok(best)
214+
}
215+
193216
/// Converts this `User` model into an `EncodablePrivateUser` for JSON serialization.
194217
pub fn encodable_private(
195218
self,

src/version/yank.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use diesel::prelude::*;
77
use app::RequestApp;
88
use db::RequestTransaction;
99
use git;
10-
use owner::rights;
1110
use user::RequestUser;
1211
use util::errors::CargoError;
1312
use util::{human, CargoResult, RequestUtils};
@@ -41,7 +40,7 @@ fn modify_yank(req: &mut Request, yanked: bool) -> CargoResult<Response> {
4140
let user = req.user()?;
4241
let conn = req.db_conn()?;
4342
let owners = krate.owners(&conn)?;
44-
if rights(req.app(), &owners, user)? < Rights::Publish {
43+
if user.rights(req.app(), &owners)? < Rights::Publish {
4544
return Err(human("must already be an owner to yank or unyank"));
4645
}
4746

0 commit comments

Comments
 (0)