22//
33// SPDX-License-Identifier: AGPL-3.0-only
44
5+ use std:: sync:: Arc ;
6+
57use aide:: { NoApi , OperationIo , transform:: TransformOperation } ;
6- use axum:: { Json , response:: IntoResponse } ;
8+ use axum:: { Json , extract :: State , response:: IntoResponse } ;
79use hyper:: StatusCode ;
10+ use mas_policy:: PolicyFactory ;
811use mas_storage:: BoxRng ;
912use schemars:: JsonSchema ;
1013use serde:: Deserialize ;
@@ -21,6 +24,9 @@ use crate::{
2124#[ derive( Debug , thiserror:: Error , OperationIo ) ]
2225#[ aide( output_with = "Json<ErrorResponse>" ) ]
2326pub enum RouteError {
27+ #[ error( "Failed to instanciate policy with the provided data" ) ]
28+ InvalidPolicyData ( #[ from] mas_policy:: LoadError ) ,
29+
2430 #[ error( transparent) ]
2531 Internal ( Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
2632}
@@ -30,7 +36,10 @@ impl_from_error_for_route!(mas_storage::RepositoryError);
3036impl IntoResponse for RouteError {
3137 fn into_response ( self ) -> axum:: response:: Response {
3238 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+ } ;
3443 ( status, Json ( error) ) . into_response ( )
3544 }
3645}
@@ -62,6 +71,12 @@ pub fn doc(operation: TransformOperation) -> TransformOperation {
6271 t. description ( "Policy data was successfully set" )
6372 . example ( response)
6473 } )
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+ } )
6580}
6681
6782#[ tracing:: instrument( name = "handler.admin.v1.policy_data.set" , skip_all, err) ]
@@ -70,13 +85,17 @@ pub async fn handler(
7085 mut repo, clock, ..
7186 } : CallContext ,
7287 NoApi ( mut rng) : NoApi < BoxRng > ,
88+ State ( policy_factory) : State < Arc < PolicyFactory > > ,
7389 Json ( request) : Json < SetPolicyDataRequest > ,
7490) -> Result < ( StatusCode , Json < SingleResponse < PolicyData > > ) , RouteError > {
7591 let policy_data = repo
7692 . policy_data ( )
7793 . set ( & mut rng, & clock, request. data )
7894 . await ?;
7995
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+
8099 repo. save ( ) . await ?;
81100
82101 Ok ( (
0 commit comments