1
+ use std:: fmt;
2
+
1
3
use conduit:: { Request , Response } ;
2
4
use time:: Timespec ;
3
5
use pg:: GenericConnection ;
@@ -7,7 +9,7 @@ use rustc_serialize::json;
7
9
8
10
use db:: RequestTransaction ;
9
11
use user:: RequestUser ;
10
- use util:: { RequestUtils , CargoResult , internal, ChainError , human, read_fill} ;
12
+ use util:: { RequestUtils , CargoError , CargoResult , internal, ChainError , human, read_fill} ;
11
13
use Model ;
12
14
13
15
/// The model representing a row in the `api_tokens` database table.
@@ -136,6 +138,28 @@ impl Model for ApiToken {
136
138
fn table_name ( _: Option < ApiToken > ) -> & ' static str { "api_tokens" }
137
139
}
138
140
141
+ struct BadRequest < T : CargoError > ( T ) ;
142
+
143
+ impl < T : CargoError > CargoError for BadRequest < T > {
144
+ fn description ( & self ) -> & str { self . 0 . description ( ) }
145
+ fn response ( & self ) -> Option < Response > {
146
+ self . 0 . response ( ) . map ( |mut response| {
147
+ response. status = ( 400 , "Bad Request" ) ;
148
+ response
149
+ } )
150
+ }
151
+ }
152
+
153
+ impl < T : CargoError > fmt:: Display for BadRequest < T > {
154
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
155
+ write ! ( f, "Bad Request: {}" , self . 0 )
156
+ }
157
+ }
158
+
159
+ fn bad_request < T : CargoError > ( error : T ) -> Box < CargoError > {
160
+ Box :: new ( BadRequest ( error) )
161
+ }
162
+
139
163
/// Handles the `GET /me/tokens` route.
140
164
pub fn list ( req : & mut Request ) -> CargoResult < Response > {
141
165
let tokens = ApiToken :: find_for_user ( req. tx ( ) ?, req. user ( ) ?. id ) ?
@@ -155,31 +179,31 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
155
179
} ) ?;
156
180
157
181
if length > max_post_size {
158
- return Err ( human ( & format_args ! ( "max post size is: {}" , max_post_size) ) ) ;
182
+ return Err ( bad_request ( human ( & format_args ! ( "max post size is: {}" , max_post_size) ) ) ) ;
159
183
}
160
184
161
185
let mut json = vec ! [ 0 ; length as usize ] ;
162
186
read_fill ( req. body ( ) , & mut json) ?;
163
187
164
188
let json = String :: from_utf8 ( json) . map_err ( |_| {
165
- human ( "json body was not valid utf-8" )
189
+ bad_request ( human ( "json body was not valid utf-8" ) )
166
190
} ) ?;
167
191
168
192
let new: NewApiTokenRequest = json:: decode ( & json) . map_err ( |e| {
169
- human ( & format_args ! ( "invalid new token request: {:?}" , e) )
193
+ bad_request ( human ( & format_args ! ( "invalid new token request: {:?}" , e) ) )
170
194
} ) ?;
171
195
172
196
let name = & new. api_token . name ;
173
197
if name. len ( ) < 1 {
174
- return Err ( human ( "name must have a value" ) ) ;
198
+ return Err ( bad_request ( human ( "name must have a value" ) ) ) ;
175
199
}
176
200
177
201
let user = req. user ( ) ?;
178
202
179
203
let max_token_per_user = 500 ;
180
204
let count = ApiToken :: count_for_user ( req. tx ( ) ?, user. id ) ?;
181
205
if count >= max_token_per_user {
182
- return Err ( human ( & format_args ! ( "maximum tokens per user is: {}" , max_token_per_user) ) ) ;
206
+ return Err ( bad_request ( human ( & format_args ! ( "maximum tokens per user is: {}" , max_token_per_user) ) ) ) ;
183
207
}
184
208
185
209
let api_token = ApiToken :: insert ( req. tx ( ) ?, user. id , name) ?;
@@ -192,7 +216,9 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
192
216
/// Handles the `DELETE /me/tokens/:id` route.
193
217
pub fn revoke ( req : & mut Request ) -> CargoResult < Response > {
194
218
let user = req. user ( ) ?;
195
- let id = req. params ( ) [ "id" ] . parse ( ) ?;
219
+ let id = req. params ( ) [ "id" ] . parse ( ) . map_err ( |e| {
220
+ bad_request ( human ( & format_args ! ( "invalid token id: {:?}" , e) ) )
221
+ } ) ?;
196
222
197
223
ApiToken :: delete ( req. tx ( ) ?, user. id , id) ?;
198
224
0 commit comments