@@ -7,6 +7,7 @@ use hyper::Body;
7
7
use hyper:: Request ;
8
8
use routerify:: prelude:: RequestExt ;
9
9
use routerify:: Router ;
10
+ use routerify_query:: RequestQueryExt ;
10
11
use tracing:: field;
11
12
use tracing:: instrument;
12
13
use tracing:: Instrument ;
@@ -46,6 +47,7 @@ pub fn admin_router() -> Router<Body, ApiError> {
46
47
)
47
48
. get ( "/tickets" , util:: auth ( util:: json ( list_tickets) ) )
48
49
. patch ( "/tickets/:id" , util:: auth ( util:: json ( patch_ticket) ) )
50
+ . get ( "/audit_logs" , util:: auth ( util:: json ( list_audit_logs) ) )
49
51
. build ( )
50
52
. unwrap ( )
51
53
}
@@ -112,9 +114,6 @@ pub async fn list_users(req: Request<Body>) -> ApiResult<ApiList<ApiFullUser>> {
112
114
fields( user_id)
113
115
) ]
114
116
pub async fn update_user ( mut req : Request < Body > ) -> ApiResult < ApiFullUser > {
115
- let iam = req. iam ( ) ;
116
- iam. check_admin_access ( ) ?;
117
-
118
117
let user_id = req. param_uuid ( "user_id" ) ?;
119
118
Span :: current ( ) . record ( "user_id" , field:: display ( & user_id) ) ;
120
119
let ApiAdminUpdateUserRequest {
@@ -124,16 +123,23 @@ pub async fn update_user(mut req: Request<Body>) -> ApiResult<ApiFullUser> {
124
123
} = decode_json ( & mut req) . await ?;
125
124
let db = req. data :: < Database > ( ) . unwrap ( ) ;
126
125
126
+ let iam = req. iam ( ) ;
127
+ let staff = iam. check_admin_access ( ) ?;
128
+
127
129
let mut updated_user = None ;
128
130
129
131
if let Some ( is_staff) = is_staff {
130
- updated_user = Some ( db. user_set_staff ( user_id, is_staff) . await ?) ;
132
+ updated_user = Some ( db. user_set_staff ( & staff . id , user_id, is_staff) . await ?) ;
131
133
}
132
134
if let Some ( is_blocked) = is_blocked {
133
- updated_user = Some ( db. user_set_blocked ( user_id, is_blocked) . await ?) ;
135
+ updated_user =
136
+ Some ( db. user_set_blocked ( & staff. id , user_id, is_blocked) . await ?) ;
134
137
}
135
138
if let Some ( scope_limit) = scope_limit {
136
- updated_user = Some ( db. user_set_scope_limit ( user_id, scope_limit) . await ?) ;
139
+ updated_user = Some (
140
+ db. user_set_scope_limit ( & staff. id , user_id, scope_limit)
141
+ . await ?,
142
+ ) ;
137
143
}
138
144
139
145
if let Some ( updated_user) = updated_user {
@@ -170,9 +176,6 @@ pub async fn list_scopes(
170
176
fields( scope)
171
177
) ]
172
178
pub async fn patch_scopes ( mut req : Request < Body > ) -> ApiResult < ApiFullScope > {
173
- let iam = req. iam ( ) ;
174
- iam. check_admin_access ( ) ?;
175
-
176
179
let scope = req. param_scope ( ) ?;
177
180
Span :: current ( ) . record ( "scope" , field:: display ( & scope) ) ;
178
181
@@ -182,6 +185,9 @@ pub async fn patch_scopes(mut req: Request<Body>) -> ApiResult<ApiFullScope> {
182
185
publish_attempts_per_week_limit,
183
186
} = decode_json ( & mut req) . await ?;
184
187
188
+ let iam = req. iam ( ) ;
189
+ let staff = iam. check_admin_access ( ) ?;
190
+
185
191
let db = req. data :: < Database > ( ) . unwrap ( ) ;
186
192
187
193
if package_limit. is_none ( )
@@ -195,6 +201,7 @@ pub async fn patch_scopes(mut req: Request<Body>) -> ApiResult<ApiFullScope> {
195
201
196
202
let scope = db
197
203
. update_scope_limits (
204
+ & staff. id ,
198
205
& scope,
199
206
package_limit,
200
207
new_package_per_week_limit,
@@ -212,13 +219,13 @@ pub async fn patch_scopes(mut req: Request<Body>) -> ApiResult<ApiFullScope> {
212
219
fields( scope, user_id)
213
220
) ]
214
221
pub async fn assign_scope ( mut req : Request < Body > ) -> ApiResult < ApiScope > {
215
- let iam = req. iam ( ) ;
216
- iam. check_admin_access ( ) ?;
217
-
218
222
let ApiAssignScopeRequest { scope, user_id } = decode_json ( & mut req) . await ?;
219
223
Span :: current ( ) . record ( "scope" , field:: display ( & scope) ) ;
220
224
Span :: current ( ) . record ( "user_id" , field:: display ( & user_id) ) ;
221
225
226
+ let iam = req. iam ( ) ;
227
+ let staff = iam. check_admin_access ( ) ?;
228
+
222
229
let db = req. data :: < Database > ( ) . unwrap ( ) ;
223
230
224
231
let scope_without_hyphens = scope. replace ( '-' , "" ) ;
@@ -228,7 +235,7 @@ pub async fn assign_scope(mut req: Request<Body>) -> ApiResult<ApiScope> {
228
235
}
229
236
230
237
let scope = db
231
- . create_scope ( & scope, user_id)
238
+ . create_scope ( & staff . id , true , & scope, user_id)
232
239
. await
233
240
. map_err ( |e| map_unique_violation ( e, ApiError :: ScopeAlreadyExists ) ) ?;
234
241
@@ -266,7 +273,7 @@ pub async fn list_publishing_tasks(
266
273
) ]
267
274
pub async fn requeue_publishing_tasks ( req : Request < Body > ) -> ApiResult < ( ) > {
268
275
let iam = req. iam ( ) ;
269
- iam. check_admin_access ( ) ?;
276
+ let staff = iam. check_admin_access ( ) ?;
270
277
271
278
let publishing_task_id = req. param_uuid ( "publishing_task" ) ?;
272
279
Span :: current ( )
@@ -280,6 +287,7 @@ pub async fn requeue_publishing_tasks(req: Request<Body>) -> ApiResult<()> {
280
287
281
288
if task. status == PublishingTaskStatus :: Processing {
282
289
db. update_publishing_task_status (
290
+ Some ( & staff. id ) ,
283
291
publishing_task_id,
284
292
PublishingTaskStatus :: Processing ,
285
293
PublishingTaskStatus :: Pending ,
@@ -292,7 +300,7 @@ pub async fn requeue_publishing_tasks(req: Request<Body>) -> ApiResult<()> {
292
300
let orama_client = req. data :: < Option < OramaClient > > ( ) . unwrap ( ) . clone ( ) ;
293
301
294
302
if let Some ( queue) = publish_queue {
295
- let body = serde_json:: to_vec ( & publishing_task_id) . unwrap ( ) ;
303
+ let body = serde_json:: to_vec ( & publishing_task_id) ? ;
296
304
queue. task_buffer ( None , Some ( body. into ( ) ) ) . await ?;
297
305
} else {
298
306
let buckets = req. data :: < Buckets > ( ) . unwrap ( ) . clone ( ) ;
@@ -326,25 +334,25 @@ pub async fn list_tickets(req: Request<Body>) -> ApiResult<ApiList<ApiTicket>> {
326
334
327
335
let ( total, tickets) = db. list_tickets ( start, limit, maybe_search) . await ?;
328
336
Ok ( ApiList {
329
- items : tickets. into_iter ( ) . map ( |scope| scope . into ( ) ) . collect ( ) ,
337
+ items : tickets. into_iter ( ) . map ( |ticket| ticket . into ( ) ) . collect ( ) ,
330
338
total,
331
339
} )
332
340
}
333
341
334
342
#[ instrument( name = "PATCH /api/admin/tickets/:id" , skip( req) , err) ]
335
343
pub async fn patch_ticket ( mut req : Request < Body > ) -> ApiResult < ApiTicket > {
336
- let iam = req. iam ( ) ;
337
- iam. check_admin_access ( ) ?;
338
-
339
344
let id = req. param_uuid ( "id" ) ?;
340
345
Span :: current ( ) . record ( "id" , field:: display ( id) ) ;
341
346
342
347
let ApiAdminUpdateTicketRequest { closed } = decode_json ( & mut req) . await ?;
343
348
349
+ let iam = req. iam ( ) ;
350
+ let staff = iam. check_admin_access ( ) ?;
351
+
344
352
let db = req. data :: < Database > ( ) . unwrap ( ) ;
345
353
346
354
let ticket = if let Some ( closed) = closed {
347
- db. update_ticket_closed ( id, closed) . await ?
355
+ db. update_ticket_closed ( & staff . id , id, closed) . await ?
348
356
} else {
349
357
return Err ( ApiError :: MalformedRequest {
350
358
msg : "missing 'closed' parameter" . into ( ) ,
@@ -354,6 +362,30 @@ pub async fn patch_ticket(mut req: Request<Body>) -> ApiResult<ApiTicket> {
354
362
Ok ( ticket. into ( ) )
355
363
}
356
364
365
+ #[ instrument( name = "GET /api/admin/audit_logs" , skip( req) , err) ]
366
+ pub async fn list_audit_logs (
367
+ req : Request < Body > ,
368
+ ) -> ApiResult < ApiList < ApiAuditLog > > {
369
+ let iam = req. iam ( ) ;
370
+ iam. check_admin_access ( ) ?;
371
+
372
+ let db = req. data :: < Database > ( ) . unwrap ( ) ;
373
+ let ( start, limit) = pagination ( & req) ;
374
+ let maybe_search = search ( & req) ;
375
+ let sudo_only = req. query ( "sudoOnly" ) . is_some ( ) ;
376
+
377
+ let ( total, audit_logs) = db
378
+ . list_audit_logs ( start, limit, maybe_search, sudo_only)
379
+ . await ?;
380
+ Ok ( ApiList {
381
+ items : audit_logs
382
+ . into_iter ( )
383
+ . map ( |audit_log| audit_log. into ( ) )
384
+ . collect ( ) ,
385
+ total,
386
+ } )
387
+ }
388
+
357
389
#[ cfg( test) ]
358
390
mod tests {
359
391
use crate :: api:: ApiFullScope ;
0 commit comments