1
1
use { Model , User } ;
2
2
use util:: { RequestUtils , CargoResult , internal, ChainError , human} ;
3
3
use db:: Connection ;
4
- use curl;
5
4
use pg:: rows:: Row ;
6
5
use rustc_serialize:: json;
7
6
use util:: errors:: NotFound ;
8
7
use std:: str;
9
-
10
- pub fn json_http ( url : & str , auth_token : & str )
11
- -> Result < curl:: http:: Response , curl:: ErrCode > {
12
- curl:: http:: handle ( )
13
- . get ( url)
14
- . header ( "Accept" , "application/vnd.github.v3+json" )
15
- . header ( "User-Agent" , "hello!" )
16
- . header ( "Authorization" , & format ! ( "token {}" , auth_token) )
17
- . exec ( )
18
- }
8
+ use http;
19
9
20
10
#[ repr( u32 ) ]
21
11
pub enum OwnerKind {
@@ -45,6 +35,7 @@ pub struct Team {
45
35
#[ derive( RustcDecodable , RustcEncodable ) ]
46
36
pub struct EncodableOwner {
47
37
pub id : i32 ,
38
+ // TODO: duplicate this field with better name
48
39
pub login : String ,
49
40
pub kind : String ,
50
41
pub email : Option < String > ,
@@ -114,8 +105,9 @@ impl Team {
114
105
c) ) ) ;
115
106
}
116
107
117
- let resp = try!( json_http ( & format ! ( "https://api.github.com/orgs/{}/teams" , org_name) ,
118
- & req_user. gh_access_token ) ) ;
108
+ let resp = try!( http:: github (
109
+ & format ! ( "https://api.github.com/orgs/{}/teams" , org_name) ,
110
+ & http:: token ( req_user. gh_access_token . clone ( ) ) ) ) ;
119
111
120
112
match resp. get_code ( ) {
121
113
200 => { } // Ok!
@@ -159,9 +151,7 @@ impl Team {
159
151
human ( format ! ( "could not find the github team {}/{}" , org_name, team_name) )
160
152
} ) ) ;
161
153
162
- // mock Team (only need github_id to check team status)
163
- let team = Team { github_id : github_id, id : 0 , name : String :: new ( ) } ;
164
- if !try!( team. contains_user ( req_user) ) {
154
+ if !try!( team_with_gh_id_contains_user ( github_id, req_user) ) {
165
155
return Err ( human ( "only members of a team can add it as an owner" ) ) ;
166
156
}
167
157
@@ -185,48 +175,52 @@ impl Team {
185
175
/// the answer. If this is not the case, then we could accidentally leak
186
176
/// private membership information here.
187
177
pub fn contains_user ( & self , user : & User ) -> CargoResult < bool > {
188
- // GET teams/:team_id/memberships/:user_name
189
- // check that "state": "active"
178
+ team_with_gh_id_contains_user ( self . github_id , user)
179
+ }
180
+ }
190
181
191
- let resp = try! ( json_http ( & format ! ( "https://api.github.com/teams/{}/memberships/{}" ,
192
- self . github_id , & user . gh_login ) ,
193
- & user . gh_access_token ) ) ;
182
+ fn team_with_gh_id_contains_user ( github_id : i32 , user : & User ) -> CargoResult < bool > {
183
+ // GET teams/:team_id/memberships/:user_name
184
+ // check that "state": "active"
194
185
195
- match resp. get_code ( ) {
196
- 200 => { } // Ok!
197
- 404 => {
198
- // Yes, this is actually how "no membership" is signaled
199
- return Ok ( false ) ;
200
- }
201
- 403 => {
202
- return Err ( human ( "It looks like you don't have permission \
203
- to query an organization that owns this \
204
- crate. You may need to re-authenticate on \
205
- crates.io to grant permission to read \
206
- github org memberships. Just go to \
207
- https://crates.io/login") ) ;
208
- }
209
- _ => {
210
- return Err ( internal ( format ! ( "didn't get a 200 result from github: {}" ,
211
- resp) ) )
212
- }
213
- }
186
+ let resp = try!( http:: github (
187
+ & format ! ( "https://api.github.com/teams/{}/memberships/{}" , & github_id, & user. gh_login) ,
188
+ & http:: token ( user. gh_access_token . clone ( ) ) ) ) ;
214
189
215
- #[ derive( RustcDecodable ) ]
216
- struct Membership {
217
- state : String ,
190
+ match resp. get_code ( ) {
191
+ 200 => { } // Ok!
192
+ 404 => {
193
+ // Yes, this is actually how "no membership" is signaled
194
+ return Ok ( false ) ;
218
195
}
219
- let json = try!( str:: from_utf8 ( resp. get_body ( ) ) . ok ( ) . chain_error ( ||{
220
- internal ( "github didn't send a utf8-response" )
221
- } ) ) ;
222
- let membership: Membership = try!( json:: decode ( json) . chain_error ( || {
223
- internal ( "github didn't send a valid json response" )
224
- } ) ) ;
196
+ 403 => {
197
+ return Err ( human ( "It looks like you don't have permission \
198
+ to query an organization that owns this \
199
+ crate. You may need to re-authenticate on \
200
+ crates.io to grant permission to read \
201
+ github org memberships. Just go to \
202
+ https://crates.io/login") ) ;
203
+ }
204
+ _ => {
205
+ return Err ( internal ( format ! ( "didn't get a 200 result from github: {}" ,
206
+ resp) ) )
207
+ }
208
+ }
225
209
226
- // There is also `state: pending` for which we could possibly give
227
- // some feedback, but it's not obvious how that should work.
228
- Ok ( membership . state == "active" )
210
+ # [ derive ( RustcDecodable ) ]
211
+ struct Membership {
212
+ state : String ,
229
213
}
214
+ let json = try!( str:: from_utf8 ( resp. get_body ( ) ) . ok ( ) . chain_error ( ||{
215
+ internal ( "github didn't send a utf8-response" )
216
+ } ) ) ;
217
+ let membership: Membership = try!( json:: decode ( json) . chain_error ( || {
218
+ internal ( "github didn't send a valid json response" )
219
+ } ) ) ;
220
+
221
+ // There is also `state: pending` for which we could possibly give
222
+ // some feedback, but it's not obvious how that should work.
223
+ Ok ( membership. state == "active" )
230
224
}
231
225
232
226
impl Model for Team {
@@ -293,8 +287,8 @@ impl Owner {
293
287
294
288
pub fn kind ( & self ) -> i32 {
295
289
match * self {
296
- Owner :: User ( _) => 0 ,
297
- Owner :: Team ( _) => 1 ,
290
+ Owner :: User ( _) => OwnerKind :: User as i32 ,
291
+ Owner :: Team ( _) => OwnerKind :: Team as i32 ,
298
292
}
299
293
}
300
294
0 commit comments