1
1
use { Model , User } ;
2
2
use util:: { RequestUtils , CargoResult , internal, ChainError , human} ;
3
3
use db:: Connection ;
4
- use curl:: http ;
4
+ use curl;
5
5
use pg:: rows:: Row ;
6
6
use rustc_serialize:: json;
7
7
use util:: errors:: NotFound ;
8
8
use std:: str;
9
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
+ }
19
+
20
+ #[ repr( u32 ) ]
21
+ pub enum OwnerKind {
22
+ User = 0 ,
23
+ Team = 1 ,
24
+ }
10
25
11
26
/// Unifies the notion of a User or a Team.
12
27
pub enum Owner {
13
28
User ( User ) ,
14
- Team ( Team )
29
+ Team ( Team ) ,
15
30
}
16
31
17
32
/// For now, just a Github Team. Can be upgraded to other teams
18
33
/// later if desirable.
19
34
pub struct Team {
20
- /// Github annoyingly has some APIs talk about teams by name,
21
- /// and others by some opaque id. I couldn't find any docs
22
- /// suggesting these ids are stable, so let's just always
23
- /// ask github for it. *shrug*
24
- github_id : i32 ,
35
+ /// We're assuming these are stable
36
+ pub github_id : i32 ,
25
37
/// Unique table id
26
- cargo_id : i32 ,
38
+ pub id : i32 ,
27
39
/// "github:org:team"
28
40
/// An opaque unique ID, that was at one point parsed out to query Github.
29
41
/// We only query membership with github using the github_id, though.
30
- name : String ,
42
+ pub name : String ,
31
43
}
32
44
33
45
#[ derive( RustcDecodable , RustcEncodable ) ]
34
46
pub struct EncodableOwner {
35
47
pub id : i32 ,
36
- // Login is deprecated in favour of name, but needs to be printed for back-compat
37
48
pub login : String ,
38
49
pub kind : String ,
39
50
pub email : Option < String > ,
@@ -70,9 +81,7 @@ impl Team {
70
81
// github:rust-lang:owners
71
82
"github" => {
72
83
// Ok to unwrap since we know one ":" is contained
73
- let org = try!( chunks. next ( ) . ok_or_else ( ||
74
- human ( "missing github org argument; format is github:org:team" )
75
- ) ) ;
84
+ let org = chunks. next ( ) . unwrap ( ) ;
76
85
let team = try!( chunks. next ( ) . ok_or_else ( ||
77
86
human ( "missing github team argument; format is github:org:team" )
78
87
) ) ;
@@ -105,12 +114,8 @@ impl Team {
105
114
c) ) ) ;
106
115
}
107
116
108
- let resp = try!( http:: handle ( )
109
- . get ( format ! ( "https://api.github.com/orgs/{}/teams" , org_name) )
110
- . header ( "Accept" , "application/vnd.github.v3+json" )
111
- . header ( "User-Agent" , "hello!" )
112
- . header ( "Authorization" , & format ! ( "token {}" , & req_user. gh_access_token) )
113
- . exec ( ) ) ;
117
+ let resp = try!( json_http ( & format ! ( "https://api.github.com/orgs/{}/teams" , org_name) ,
118
+ & req_user. gh_access_token ) ) ;
114
119
115
120
match resp. get_code ( ) {
116
121
200 => { } // Ok!
@@ -154,20 +159,25 @@ impl Team {
154
159
human ( format ! ( "could not find the github team {}/{}" , org_name, team_name) )
155
160
} ) ) ;
156
161
157
- // mock Team (only need ID to check team status)
158
- let team = Team { github_id : github_id, cargo_id : 0 , name : String :: new ( ) } ;
162
+ // mock Team (only need github_id to check team status)
163
+ let team = Team { github_id : github_id, id : 0 , name : String :: new ( ) } ;
159
164
if !try!( team. contains_user ( req_user) ) {
160
165
return Err ( human ( "only members of a team can add it as an owner" ) ) ;
161
166
}
162
167
168
+ Team :: insert ( conn, name, github_id)
169
+ }
170
+
171
+ pub fn insert ( conn : & Connection , name : & str , github_id : i32 ) -> CargoResult < Self > {
163
172
// insert into DB for reals
164
- try!( conn. execute ( "INSERT INTO teams
165
- (name, github_id)
166
- VALUES ($1, $2)" ,
167
- & [ & name , & github_id ] ) ) ;
173
+ let stmt = try!( conn. prepare ( "INSERT INTO teams
174
+ (name, github_id)
175
+ VALUES ($1, $2)
176
+ RETURNING *" ) ) ;
168
177
169
- // read it right back out:
170
- Team :: find_by_name ( conn, name)
178
+ let rows = try!( stmt. query ( & [ & name, & github_id] ) ) ;
179
+ let row = rows. iter ( ) . next ( ) . unwrap ( ) ;
180
+ Ok ( Model :: from_row ( & row) )
171
181
}
172
182
173
183
/// Phones home to Github to ask if this User is a member of the given team.
@@ -178,13 +188,9 @@ impl Team {
178
188
// GET teams/:team_id/memberships/:user_name
179
189
// check that "state": "active"
180
190
181
- let resp = try!( http:: handle ( )
182
- . get ( format ! ( "https://api.github.com/teams/{}/memberships/{}" ,
183
- self . github_id, & user. gh_login) )
184
- . header ( "Accept" , "application/vnd.github.v3+json" )
185
- . header ( "User-Agent" , "hello!" )
186
- . header ( "Authorization" , & format ! ( "token {}" , & user. gh_access_token) )
187
- . exec ( ) ) ;
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 ) ) ;
188
194
189
195
match resp. get_code ( ) {
190
196
200 => { } // Ok!
@@ -226,7 +232,7 @@ impl Team {
226
232
impl Model for Team {
227
233
fn from_row ( row : & Row ) -> Self {
228
234
Team {
229
- cargo_id : row. get ( "id" ) ,
235
+ id : row. get ( "id" ) ,
230
236
name : row. get ( "name" ) ,
231
237
github_id : row. get ( "github_id" ) ,
232
238
}
@@ -302,7 +308,7 @@ impl Owner {
302
308
pub fn id ( & self ) -> i32 {
303
309
match * self {
304
310
Owner :: User ( ref user) => user. id ,
305
- Owner :: Team ( ref team) => team. cargo_id ,
311
+ Owner :: Team ( ref team) => team. id ,
306
312
}
307
313
}
308
314
@@ -318,14 +324,14 @@ impl Owner {
318
324
kind : String :: from ( "user" ) ,
319
325
}
320
326
}
321
- Owner :: Team ( Team { cargo_id , name, .. } ) => {
327
+ Owner :: Team ( Team { id , name, .. } ) => {
322
328
EncodableOwner {
323
- id : cargo_id ,
329
+ id : id ,
324
330
login : name,
325
331
email : None ,
326
332
avatar : None ,
327
333
name : None ,
328
- kind : String :: from ( "owner " ) ,
334
+ kind : String :: from ( "team " ) ,
329
335
}
330
336
}
331
337
}
0 commit comments