Skip to content

Commit ead0cc8

Browse files
authored
Merge pull request #5572 from Turbo87/token-scope-endpoints
Implement token scope restrictions for our endpoints
2 parents 036f39e + 3399875 commit ead0cc8

11 files changed

+714
-19
lines changed

src/controllers/krate/owners.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::auth::AuthCheck;
44
use crate::controllers::prelude::*;
5+
use crate::models::token::EndpointScope;
56
use crate::models::{Crate, Owner, Rights, Team, User};
67
use crate::views::EncodableOwner;
78

@@ -80,7 +81,12 @@ fn parse_owners_request(req: &mut dyn RequestExt) -> AppResult<Vec<String>> {
8081
}
8182

8283
fn modify_owners(req: &mut dyn RequestExt, add: bool) -> EndpointResult {
83-
let auth = AuthCheck::default().check(req)?;
84+
let crate_name = &req.params()["crate_id"];
85+
86+
let auth = AuthCheck::default()
87+
.with_endpoint_scope(EndpointScope::ChangeOwners)
88+
.for_crate(crate_name)
89+
.check(req)?;
8490

8591
let logins = parse_owners_request(req)?;
8692
let app = req.app();

src/controllers/krate/publish.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::models::{
1818
use crate::worker;
1919

2020
use crate::middleware::log_request::add_custom_metadata;
21+
use crate::models::token::EndpointScope;
2122
use crate::schema::*;
2223
use crate::util::errors::{cargo_err, AppResult};
2324
use crate::util::{read_fill, read_le_u32, CargoVcsInfo, LimitErrorReader, Maximums};
@@ -65,7 +66,24 @@ pub fn publish(req: &mut dyn RequestExt) -> EndpointResult {
6566
add_custom_metadata("crate_version", new_crate.vers.to_string());
6667

6768
let conn = app.primary_database.get()?;
68-
let auth = AuthCheck::default().check(req)?;
69+
70+
// this query should only be used for the endpoint scope calculation
71+
// since a race condition there would only cause `publish-new` instead of
72+
// `publish-update` to be used.
73+
let existing_crate = Crate::by_name(&new_crate.name)
74+
.first::<Crate>(&*conn)
75+
.optional()?;
76+
77+
let endpoint_scope = match existing_crate {
78+
Some(_) => EndpointScope::PublishUpdate,
79+
None => EndpointScope::PublishNew,
80+
};
81+
82+
let auth = AuthCheck::default()
83+
.with_endpoint_scope(endpoint_scope)
84+
.for_crate(&new_crate.name)
85+
.check(req)?;
86+
6987
let api_token_id = auth.api_token_id();
7088
let user = auth.user();
7189

src/controllers/version/yank.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use swirl::Job;
55

66
use super::{extract_crate_name_and_semver, version_and_crate};
77
use crate::controllers::cargo_prelude::*;
8+
use crate::models::token::EndpointScope;
89
use crate::models::Rights;
910
use crate::models::{insert_version_owner_action, VersionAction};
1011
use crate::schema::versions;
@@ -32,9 +33,14 @@ pub fn unyank(req: &mut dyn RequestExt) -> EndpointResult {
3233
fn modify_yank(req: &mut dyn RequestExt, yanked: bool) -> EndpointResult {
3334
// FIXME: Should reject bad requests before authentication, but can't due to
3435
// lifetime issues with `req`.
35-
let auth = AuthCheck::default().check(req)?;
36+
3637
let (crate_name, semver) = extract_crate_name_and_semver(req)?;
3738

39+
let auth = AuthCheck::default()
40+
.with_endpoint_scope(EndpointScope::Yank)
41+
.for_crate(crate_name)
42+
.check(req)?;
43+
3844
let conn = req.db_write()?;
3945
let (version, krate) = version_and_crate(&conn, crate_name, semver)?;
4046
let api_token_id = auth.api_token_id();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
[
2+
{
3+
"request": {
4+
"uri": "http://alexcrichton-test.s3.amazonaws.com/crates/fyk/fyk-1.0.0.crate",
5+
"method": "PUT",
6+
"headers": [
7+
[
8+
"accept",
9+
"*/*"
10+
],
11+
[
12+
"accept-encoding",
13+
"gzip"
14+
],
15+
[
16+
"content-length",
17+
"35"
18+
],
19+
[
20+
"content-type",
21+
"application/gzip"
22+
]
23+
],
24+
"body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA="
25+
},
26+
"response": {
27+
"status": 200,
28+
"headers": [],
29+
"body": ""
30+
}
31+
},
32+
{
33+
"request": {
34+
"uri": "http://alexcrichton-test.s3.amazonaws.com/3/f/fyk",
35+
"method": "PUT",
36+
"headers": [
37+
[
38+
"accept",
39+
"*/*"
40+
],
41+
[
42+
"accept-encoding",
43+
"gzip"
44+
],
45+
[
46+
"content-length",
47+
"157"
48+
],
49+
[
50+
"content-type",
51+
"text/plain"
52+
]
53+
],
54+
"body": "eyJuYW1lIjoiZnlrIiwidmVycyI6IjEuMC4wIiwiZGVwcyI6W10sImNrc3VtIjoiYWNiNTYwNGIxMjZhYzg5NGMxZWIxMWM0NTc1YmYyMDcyZmVhNjEyMzJhODg4ZTQ1Mzc3MGM3OWQ3ZWQ1NjQxOSIsImZlYXR1cmVzIjp7fSwieWFua2VkIjpmYWxzZSwibGlua3MiOm51bGx9Cg=="
55+
},
56+
"response": {
57+
"status": 200,
58+
"headers": [],
59+
"body": ""
60+
}
61+
},
62+
{
63+
"request": {
64+
"uri": "http://alexcrichton-test.s3.amazonaws.com/3/f/fyk",
65+
"method": "PUT",
66+
"headers": [
67+
[
68+
"accept",
69+
"*/*"
70+
],
71+
[
72+
"accept-encoding",
73+
"gzip"
74+
],
75+
[
76+
"content-length",
77+
"156"
78+
],
79+
[
80+
"content-type",
81+
"text/plain"
82+
]
83+
],
84+
"body": "eyJuYW1lIjoiZnlrIiwidmVycyI6IjEuMC4wIiwiZGVwcyI6W10sImNrc3VtIjoiYWNiNTYwNGIxMjZhYzg5NGMxZWIxMWM0NTc1YmYyMDcyZmVhNjEyMzJhODg4ZTQ1Mzc3MGM3OWQ3ZWQ1NjQxOSIsImZlYXR1cmVzIjp7fSwieWFua2VkIjp0cnVlLCJsaW5rcyI6bnVsbH0K"
85+
},
86+
"response": {
87+
"status": 200,
88+
"headers": [],
89+
"body": ""
90+
}
91+
},
92+
{
93+
"request": {
94+
"uri": "http://alexcrichton-test.s3.amazonaws.com/3/f/fyk",
95+
"method": "PUT",
96+
"headers": [
97+
[
98+
"accept",
99+
"*/*"
100+
],
101+
[
102+
"accept-encoding",
103+
"gzip"
104+
],
105+
[
106+
"content-length",
107+
"157"
108+
],
109+
[
110+
"content-type",
111+
"text/plain"
112+
]
113+
],
114+
"body": "eyJuYW1lIjoiZnlrIiwidmVycyI6IjEuMC4wIiwiZGVwcyI6W10sImNrc3VtIjoiYWNiNTYwNGIxMjZhYzg5NGMxZWIxMWM0NTc1YmYyMDcyZmVhNjEyMzJhODg4ZTQ1Mzc3MGM3OWQ3ZWQ1NjQxOSIsImZlYXR1cmVzIjp7fSwieWFua2VkIjpmYWxzZSwibGlua3MiOm51bGx9Cg=="
115+
},
116+
"response": {
117+
"status": 200,
118+
"headers": [],
119+
"body": ""
120+
}
121+
}
122+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
[
2+
{
3+
"request": {
4+
"uri": "http://alexcrichton-test.s3.amazonaws.com/crates/fyk/fyk-1.0.0.crate",
5+
"method": "PUT",
6+
"headers": [
7+
[
8+
"accept",
9+
"*/*"
10+
],
11+
[
12+
"accept-encoding",
13+
"gzip"
14+
],
15+
[
16+
"content-length",
17+
"35"
18+
],
19+
[
20+
"content-type",
21+
"application/gzip"
22+
]
23+
],
24+
"body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA="
25+
},
26+
"response": {
27+
"status": 200,
28+
"headers": [],
29+
"body": ""
30+
}
31+
},
32+
{
33+
"request": {
34+
"uri": "http://alexcrichton-test.s3.amazonaws.com/3/f/fyk",
35+
"method": "PUT",
36+
"headers": [
37+
[
38+
"accept",
39+
"*/*"
40+
],
41+
[
42+
"accept-encoding",
43+
"gzip"
44+
],
45+
[
46+
"content-length",
47+
"157"
48+
],
49+
[
50+
"content-type",
51+
"text/plain"
52+
]
53+
],
54+
"body": "eyJuYW1lIjoiZnlrIiwidmVycyI6IjEuMC4wIiwiZGVwcyI6W10sImNrc3VtIjoiYWNiNTYwNGIxMjZhYzg5NGMxZWIxMWM0NTc1YmYyMDcyZmVhNjEyMzJhODg4ZTQ1Mzc3MGM3OWQ3ZWQ1NjQxOSIsImZlYXR1cmVzIjp7fSwieWFua2VkIjpmYWxzZSwibGlua3MiOm51bGx9Cg=="
55+
},
56+
"response": {
57+
"status": 200,
58+
"headers": [],
59+
"body": ""
60+
}
61+
},
62+
{
63+
"request": {
64+
"uri": "http://alexcrichton-test.s3.amazonaws.com/3/f/fyk",
65+
"method": "PUT",
66+
"headers": [
67+
[
68+
"accept",
69+
"*/*"
70+
],
71+
[
72+
"accept-encoding",
73+
"gzip"
74+
],
75+
[
76+
"content-length",
77+
"156"
78+
],
79+
[
80+
"content-type",
81+
"text/plain"
82+
]
83+
],
84+
"body": "eyJuYW1lIjoiZnlrIiwidmVycyI6IjEuMC4wIiwiZGVwcyI6W10sImNrc3VtIjoiYWNiNTYwNGIxMjZhYzg5NGMxZWIxMWM0NTc1YmYyMDcyZmVhNjEyMzJhODg4ZTQ1Mzc3MGM3OWQ3ZWQ1NjQxOSIsImZlYXR1cmVzIjp7fSwieWFua2VkIjp0cnVlLCJsaW5rcyI6bnVsbH0K"
85+
},
86+
"response": {
87+
"status": 200,
88+
"headers": [],
89+
"body": ""
90+
}
91+
},
92+
{
93+
"request": {
94+
"uri": "http://alexcrichton-test.s3.amazonaws.com/3/f/fyk",
95+
"method": "PUT",
96+
"headers": [
97+
[
98+
"accept",
99+
"*/*"
100+
],
101+
[
102+
"accept-encoding",
103+
"gzip"
104+
],
105+
[
106+
"content-length",
107+
"157"
108+
],
109+
[
110+
"content-type",
111+
"text/plain"
112+
]
113+
],
114+
"body": "eyJuYW1lIjoiZnlrIiwidmVycyI6IjEuMC4wIiwiZGVwcyI6W10sImNrc3VtIjoiYWNiNTYwNGIxMjZhYzg5NGMxZWIxMWM0NTc1YmYyMDcyZmVhNjEyMzJhODg4ZTQ1Mzc3MGM3OWQ3ZWQ1NjQxOSIsImZlYXR1cmVzIjp7fSwieWFua2VkIjpmYWxzZSwibGlua3MiOm51bGx9Cg=="
115+
},
116+
"response": {
117+
"status": 200,
118+
"headers": [],
119+
"body": ""
120+
}
121+
}
122+
]

0 commit comments

Comments
 (0)