1919pub mod utils;
2020use actix_web:: http:: StatusCode ;
2121use actix_web:: http:: header:: HeaderMap ;
22+ use base64:: Engine ;
23+ use base64:: prelude:: BASE64_STANDARD ;
2224use futures:: { StreamExt , future, stream} ;
2325use http:: header;
2426use lazy_static:: lazy_static;
@@ -50,7 +52,9 @@ use crate::rbac::role::model::Role;
5052use crate :: rbac:: user:: User ;
5153use crate :: stats:: Stats ;
5254use crate :: storage:: { ObjectStorageError , ObjectStoreFormat } ;
53- use crate :: utils:: { create_intracluster_auth_headermap, get_tenant_id_from_request} ;
55+ use crate :: utils:: {
56+ create_intracluster_auth_headermap, get_tenant_id_from_request, get_user_from_request,
57+ } ;
5458
5559use super :: base_path_without_preceding_slash;
5660use super :: ingest:: PostError ;
@@ -519,6 +523,7 @@ pub async fn sync_users_with_roles_with_ingestors(
519523 let userid = userid. to_owned ( ) ;
520524 let headers = req. headers ( ) . clone ( ) ;
521525 let op = operation. to_string ( ) ;
526+ let caller_userid = get_user_from_request ( req) . unwrap ( ) ;
522527 for_each_live_node ( tenant_id, move |ingestor| {
523528 let url = format ! (
524529 "{}{}/user/{}/role/sync/{}" ,
@@ -529,7 +534,8 @@ pub async fn sync_users_with_roles_with_ingestors(
529534 ) ;
530535
531536 let role_data = role_data. clone ( ) ;
532- let headermap = create_intracluster_auth_headermap ( & headers, & ingestor. token ) ;
537+ let headermap =
538+ create_intracluster_auth_headermap ( & headers, & ingestor. token , & caller_userid) ;
533539 async move {
534540 let res = INTRA_CLUSTER_CLIENT
535541 . patch ( url)
@@ -568,6 +574,7 @@ pub async fn sync_user_deletion_with_ingestors(
568574 tenant_id : & Option < String > ,
569575) -> Result < ( ) , RBACError > {
570576 let userid = userid. to_owned ( ) ;
577+ let caller_userid = get_user_from_request ( req) . unwrap ( ) ;
571578 let headers = req. headers ( ) . clone ( ) ;
572579 for_each_live_node ( tenant_id, move |ingestor| {
573580 let url = format ! (
@@ -576,7 +583,8 @@ pub async fn sync_user_deletion_with_ingestors(
576583 base_path_without_preceding_slash( ) ,
577584 userid
578585 ) ;
579- let headermap = create_intracluster_auth_headermap ( & headers, & ingestor. token ) ;
586+ let headermap =
587+ create_intracluster_auth_headermap ( & headers, & ingestor. token , & caller_userid) ;
580588 async move {
581589 let res = INTRA_CLUSTER_CLIENT
582590 . delete ( url)
@@ -625,6 +633,7 @@ pub async fn sync_user_creation(
625633 RBACError :: SerdeError ( err)
626634 } ) ?;
627635
636+ let caller_userid = get_user_from_request ( req) ?;
628637 let userid = userid. to_string ( ) ;
629638 let headers = req. headers ( ) . clone ( ) ;
630639 for_each_live_node ( tenant_id, move |node| {
@@ -634,7 +643,7 @@ pub async fn sync_user_creation(
634643 base_path_without_preceding_slash( ) ,
635644 userid
636645 ) ;
637- let headermap = create_intracluster_auth_headermap ( & headers, & node. token ) ;
646+ let headermap = create_intracluster_auth_headermap ( & headers, & node. token , & caller_userid ) ;
638647 let user_data = user_data. clone ( ) ;
639648
640649 async move {
@@ -672,20 +681,23 @@ pub async fn sync_password_reset_with_ingestors(
672681 req : HttpRequest ,
673682 username : & str ,
674683) -> Result < ( ) , RBACError > {
675- let username = username. to_owned ( ) ;
684+ let userid = username. to_owned ( ) ;
676685 let tenant_id = get_tenant_id_from_request ( & req) ;
686+ let caller_userid = get_user_from_request ( & req) . unwrap ( ) ;
687+ let headers = req. headers ( ) . clone ( ) ;
677688 for_each_live_node ( & tenant_id, move |ingestor| {
678689 let url = format ! (
679690 "{}{}/user/{}/generate-new-password/sync" ,
680691 ingestor. domain_name,
681692 base_path_without_preceding_slash( ) ,
682- username
693+ userid
683694 ) ;
684-
695+ let headermap =
696+ create_intracluster_auth_headermap ( & headers, & ingestor. token , & caller_userid) ;
685697 async move {
686698 let res = INTRA_CLUSTER_CLIENT
687699 . post ( url)
688- . header ( header :: AUTHORIZATION , & ingestor . token )
700+ . headers ( headermap )
689701 . header ( header:: CONTENT_TYPE , "application/json" )
690702 . send ( )
691703 . await
@@ -713,11 +725,14 @@ pub async fn sync_password_reset_with_ingestors(
713725
714726// forward the put role request to all ingestors and queriers to keep them in sync
715727pub async fn sync_role_update (
728+ req : & HttpRequest ,
716729 name : String ,
717730 role : Role ,
718731 tenant_id : & Option < String > ,
719732) -> Result < ( ) , RoleError > {
720733 let tenant = tenant_id. to_owned ( ) ;
734+ let userid = get_user_from_request ( req) . unwrap ( ) ;
735+ let headers = req. headers ( ) . clone ( ) ;
721736 for_each_live_node ( tenant_id, move |node| {
722737 let url = format ! (
723738 "{}{}/role/{}/sync" ,
@@ -727,12 +742,12 @@ pub async fn sync_role_update(
727742 ) ;
728743
729744 let role = role. clone ( ) ;
730-
745+ let headermap = create_intracluster_auth_headermap ( & headers , & node . token , & userid ) ;
731746 let tenant_id = tenant. clone ( ) ;
732747 async move {
733748 let res = INTRA_CLUSTER_CLIENT
734749 . put ( url)
735- . header ( header :: AUTHORIZATION , & node . token )
750+ . headers ( headermap )
736751 . header ( header:: CONTENT_TYPE , "application/json" )
737752 . json ( & SyncRole :: new ( role, tenant_id. clone ( ) ) )
738753 . send ( )
@@ -759,6 +774,52 @@ pub async fn sync_role_update(
759774 . await
760775}
761776
777+ // forward the put role request to all ingestors and queriers to keep them in sync
778+ pub async fn sync_role_delete (
779+ req : & HttpRequest ,
780+ name : String ,
781+ tenant_id : & Option < String > ,
782+ ) -> Result < ( ) , RoleError > {
783+ let userid = get_user_from_request ( req) . unwrap ( ) ;
784+ let headers = req. headers ( ) . clone ( ) ;
785+ for_each_live_node ( tenant_id, move |node| {
786+ let url = format ! (
787+ "{}{}/role/{}/sync" ,
788+ node. domain_name,
789+ base_path_without_preceding_slash( ) ,
790+ name
791+ ) ;
792+
793+ let headermap = create_intracluster_auth_headermap ( & headers, & node. token , & userid) ;
794+ async move {
795+ let res = INTRA_CLUSTER_CLIENT
796+ . delete ( url)
797+ . headers ( headermap)
798+ . header ( header:: CONTENT_TYPE , "application/json" )
799+ . send ( )
800+ . await
801+ . map_err ( |err| {
802+ error ! (
803+ "Fatal: failed to forward request to node: {}\n Error: {:?}" ,
804+ node. domain_name, err
805+ ) ;
806+ RoleError :: Network ( err)
807+ } ) ?;
808+
809+ if !res. status ( ) . is_success ( ) {
810+ error ! (
811+ "failed to forward request to node: {}\n Response Returned: {:?}" ,
812+ node. domain_name,
813+ res. text( ) . await
814+ ) ;
815+ }
816+
817+ Ok ( ( ) )
818+ }
819+ } )
820+ . await
821+ }
822+
762823pub fn fetch_daily_stats (
763824 date : & str ,
764825 stream_meta_list : & [ ObjectStoreFormat ] ,
@@ -1904,7 +1965,6 @@ pub async fn send_query_request(
19041965 let mut map = reqwest:: header:: HeaderMap :: new ( ) ;
19051966
19061967 if let Some ( auth) = auth_token {
1907- // always basic auth
19081968 for ( key, value) in auth. iter ( ) {
19091969 if let Ok ( name) = reqwest:: header:: HeaderName :: from_bytes ( key. as_str ( ) . as_bytes ( ) )
19101970 && let Ok ( val) = reqwest:: header:: HeaderValue :: from_bytes ( value. as_bytes ( ) )
@@ -1918,6 +1978,16 @@ pub async fn send_query_request(
19181978 reqwest:: header:: HeaderValue :: from_str ( & querier. token ) . unwrap ( ) ,
19191979 ) ;
19201980 } ;
1981+ if map. get ( "intra-cluster-userid" ) . is_none ( ) {
1982+ let token: Vec < & str > = querier. token ( ) . split ( ' ' ) . collect ( ) ;
1983+ let decode = BASE64_STANDARD . decode ( token[ 1 ] ) . unwrap ( ) ;
1984+ let user = String :: from_utf8 ( decode) . unwrap ( ) ;
1985+ let user = user. split_once ( ':' ) . unwrap ( ) ;
1986+ map. insert (
1987+ reqwest:: header:: HeaderName :: from_static ( "intra-cluster-userid" ) ,
1988+ reqwest:: header:: HeaderValue :: from_str ( user. 0 ) . unwrap ( ) ,
1989+ ) ;
1990+ }
19211991 let res = match INTRA_CLUSTER_CLIENT
19221992 . post ( uri)
19231993 . timeout ( Duration :: from_secs ( 300 ) )
0 commit comments