2
2
//
3
3
// SPDX-License-Identifier: AGPL-3.0-only
4
4
5
+ use std:: sync:: Arc ;
6
+
5
7
use aide:: { NoApi , OperationIo , transform:: TransformOperation } ;
6
- use axum:: { Json , response:: IntoResponse } ;
8
+ use axum:: { Json , extract :: State , response:: IntoResponse } ;
7
9
use hyper:: StatusCode ;
10
+ use mas_policy:: PolicyFactory ;
8
11
use mas_storage:: BoxRng ;
9
12
use schemars:: JsonSchema ;
10
13
use serde:: Deserialize ;
@@ -21,6 +24,9 @@ use crate::{
21
24
#[ derive( Debug , thiserror:: Error , OperationIo ) ]
22
25
#[ aide( output_with = "Json<ErrorResponse>" ) ]
23
26
pub enum RouteError {
27
+ #[ error( "Failed to instanciate policy with the provided data" ) ]
28
+ InvalidPolicyData ( #[ from] mas_policy:: LoadError ) ,
29
+
24
30
#[ error( transparent) ]
25
31
Internal ( Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
26
32
}
@@ -30,7 +36,10 @@ impl_from_error_for_route!(mas_storage::RepositoryError);
30
36
impl IntoResponse for RouteError {
31
37
fn into_response ( self ) -> axum:: response:: Response {
32
38
let error = ErrorResponse :: from_error ( & self ) ;
33
- let status = StatusCode :: INTERNAL_SERVER_ERROR ;
39
+ let status = match self {
40
+ RouteError :: InvalidPolicyData ( _) => StatusCode :: BAD_REQUEST ,
41
+ RouteError :: Internal ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
42
+ } ;
34
43
( status, Json ( error) ) . into_response ( )
35
44
}
36
45
}
@@ -62,6 +71,12 @@ pub fn doc(operation: TransformOperation) -> TransformOperation {
62
71
t. description ( "Policy data was successfully set" )
63
72
. example ( response)
64
73
} )
74
+ . response_with :: < 400 , Json < ErrorResponse > , _ > ( |t| {
75
+ let error = ErrorResponse :: from_error ( & RouteError :: InvalidPolicyData (
76
+ mas_policy:: LoadError :: invalid_data_example ( ) ,
77
+ ) ) ;
78
+ t. description ( "Invalid policy data" ) . example ( error)
79
+ } )
65
80
}
66
81
67
82
#[ tracing:: instrument( name = "handler.admin.v1.policy_data.set" , skip_all, err) ]
@@ -70,13 +85,17 @@ pub async fn handler(
70
85
mut repo, clock, ..
71
86
} : CallContext ,
72
87
NoApi ( mut rng) : NoApi < BoxRng > ,
88
+ State ( policy_factory) : State < Arc < PolicyFactory > > ,
73
89
Json ( request) : Json < SetPolicyDataRequest > ,
74
90
) -> Result < ( StatusCode , Json < SingleResponse < PolicyData > > ) , RouteError > {
75
91
let policy_data = repo
76
92
. policy_data ( )
77
93
. set ( & mut rng, & clock, request. data )
78
94
. await ?;
79
95
96
+ // Swap the policy data. This will fail if the policy data is invalid
97
+ policy_factory. set_dynamic_data ( policy_data. clone ( ) ) . await ?;
98
+
80
99
repo. save ( ) . await ?;
81
100
82
101
Ok ( (
0 commit comments