1- use std:: sync:: Arc ;
1+ use std:: { str :: FromStr , sync:: Arc } ;
22
33use axum:: {
4- extract:: { Path , Query , Request , State } ,
5- http:: { HeaderMap , StatusCode } ,
4+ extract:: { OriginalUri , Path , Query , Request , State } ,
5+ http:: { header , uri :: PathAndQuery , HeaderMap , HeaderValue , StatusCode , Uri } ,
66 middleware:: { self , Next } ,
77 response:: { IntoResponse , Redirect , Response } ,
88 routing:: { delete, get, patch, post} ,
@@ -18,6 +18,7 @@ use nebula_token::{
1818use sea_orm:: { DatabaseTransaction , DbErr , TransactionTrait } ;
1919use serde:: { Deserialize , Serialize } ;
2020use thiserror:: Error ;
21+ use tracing:: error;
2122use ulid:: Ulid ;
2223
2324use crate :: {
@@ -371,6 +372,9 @@ enum MachineIdentityError {
371372 #[ error( "Error occurrred by database" ) ]
372373 #[ status( StatusCode :: INTERNAL_SERVER_ERROR ) ]
373374 DatabaseError ( #[ from] DbErr ) ,
375+ #[ error( "failed to create location header" ) ]
376+ #[ status( StatusCode :: INTERNAL_SERVER_ERROR ) ]
377+ FailedToCreateLocationHeader ,
374378}
375379
376380impl From < machine_identity:: Error > for MachineIdentityError {
@@ -382,18 +386,43 @@ impl From<machine_identity::Error> for MachineIdentityError {
382386}
383387
384388async fn handle_post_machine_identity (
389+ OriginalUri ( uri) : OriginalUri ,
385390 Path ( workspace_name) : Path < String > ,
386391 State ( application) : State < Arc < Application > > ,
387392 Extension ( claim) : Extension < NebulaClaim > ,
388393 Json ( payload) : Json < PostMachineIdentityRequest > ,
389394) -> Result < impl IntoResponse , MachineIdentityError > {
390395 let transaction = application. database_connection . begin_with_workspace_scope ( & workspace_name) . await ?;
391396
392- application. machine_identity_service . register_machine_identity ( & transaction, & claim, & payload. label ) . await ?;
397+ let result =
398+ application. machine_identity_service . register_machine_identity ( & transaction, & claim, & payload. label ) . await ?;
399+
400+ let mut parts = uri. into_parts ( ) ;
401+
402+ let new_machine_identity_path = PathAndQuery :: from_str ( & format ! (
403+ "{}/{}" ,
404+ parts. path_and_query. ok_or_else( || {
405+ error!( "failed to get request path while creating location url" ) ;
406+ MachineIdentityError :: FailedToCreateLocationHeader
407+ } ) ?,
408+ result. id
409+ ) )
410+ . inspect_err ( |e| error ! ( error = %e, "failed to create uri path from new machine identity resource" ) )
411+ . map_err ( |_| MachineIdentityError :: FailedToCreateLocationHeader ) ?;
412+
413+ parts. path_and_query = Some ( new_machine_identity_path) ;
414+ let location_header_uri = Uri :: from_parts ( parts)
415+ . inspect_err ( |e| error ! ( error = %e, "failed to create location uri from new machine identity resource" ) )
416+ . map_err ( |_| MachineIdentityError :: FailedToCreateLocationHeader ) ?;
417+ let location_header_value = HeaderValue :: from_str ( & location_header_uri. to_string ( ) )
418+ . inspect_err (
419+ |e| error ! ( error = %e, "failed to create location header value from new machine identity resource" ) ,
420+ )
421+ . map_err ( |_| MachineIdentityError :: FailedToCreateLocationHeader ) ?;
393422
394423 transaction. commit ( ) . await ?;
395424
396- Ok ( StatusCode :: CREATED )
425+ Ok ( ( StatusCode :: CREATED , [ ( header :: LOCATION , location_header_value ) ] ) )
397426}
398427
399428#[ derive( Serialize ) ]
0 commit comments