1818
1919use crate :: {
2020 option:: CONFIG ,
21- storage:: object_storage:: alert_json_path,
21+ storage:: { object_storage:: alert_json_path, ALERTS_ROOT_DIRECTORY , PARSEABLE_ROOT_DIRECTORY } ,
2222 sync:: schedule_alert_task,
23- utils:: { actix:: extract_session_key_from_req, uid :: Uid } ,
23+ utils:: actix:: extract_session_key_from_req,
2424} ;
2525use actix_web:: { web, HttpRequest , Responder } ;
2626use bytes:: Bytes ;
27- use tracing :: warn ;
27+ use relative_path :: RelativePathBuf ;
2828
29- use super :: { alerts_utils:: user_auth_for_query, AlertConfig , AlertError , AlertState , ALERTS } ;
29+ use super :: {
30+ alerts_utils:: user_auth_for_query, AlertConfig , AlertError , AlertRequest , AlertState , ALERTS ,
31+ } ;
3032
3133// GET /alerts
3234/// User needs at least a read access to the stream(s) that is being referenced in an alert
@@ -39,10 +41,11 @@ pub async fn list(req: HttpRequest) -> Result<impl Responder, AlertError> {
3941}
4042
4143// POST /alerts
42- pub async fn post ( req : HttpRequest , alert : AlertConfig ) -> Result < impl Responder , AlertError > {
44+ pub async fn post ( req : HttpRequest , alert : AlertRequest ) -> Result < impl Responder , AlertError > {
45+ let alert: AlertConfig = alert. into ( ) ;
4346 // validate the incoming alert query
4447 // does the user have access to these tables or not?
45- let session_key = extract_session_key_from_req ( & req) . unwrap ( ) ;
48+ let session_key = extract_session_key_from_req ( & req) ? ;
4649 user_auth_for_query ( & session_key, & alert. query ) . await ?;
4750
4851 // now that we've validated that the user can run this query
@@ -71,7 +74,10 @@ pub async fn get(req: HttpRequest) -> Result<impl Responder, AlertError> {
7174 . get ( "alert_id" )
7275 . ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
7376
74- let alert = ALERTS . get_alert_by_id ( session_key, id) . await ?;
77+ let alert = ALERTS . get_alert_by_id ( id) . await ?;
78+ // validate that the user has access to the tables mentioned
79+ user_auth_for_query ( & session_key, & alert. query ) . await ?;
80+
7581 Ok ( web:: Json ( alert) )
7682}
7783
@@ -95,31 +101,34 @@ pub async fn delete(req: HttpRequest) -> Result<impl Responder, AlertError> {
95101// PUT /alerts/{alert_id}
96102/// first save on disk, then in memory
97103/// then modify scheduled task
98- pub async fn modify (
99- req : HttpRequest ,
100- mut alert : AlertConfig ,
101- ) -> Result < impl Responder , AlertError > {
104+ pub async fn modify ( req : HttpRequest , alert : AlertRequest ) -> Result < impl Responder , AlertError > {
102105 let session_key = extract_session_key_from_req ( & req) ?;
103106 let alert_id = req
104107 . match_info ( )
105108 . get ( "alert_id" )
106109 . ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
107110
108- // ensure that the user doesn't unknowingly change the ID
109- if alert_id != alert. id . to_string ( ) {
110- warn ! ( "Alert modify request is trying to change Alert ID, reverting ID" ) ;
111- alert. id = Uid :: from_string ( alert_id)
112- . map_err ( |_| AlertError :: CustomError ( "Unable to get Uid from String" . to_owned ( ) ) ) ?;
113- }
111+ // check if alert id exists in map
112+ ALERTS . get_alert_by_id ( alert_id) . await ?;
114113
115114 // validate that the user has access to the tables mentioned
116115 user_auth_for_query ( & session_key, & alert. query ) . await ?;
117116
118- // // fetch the alert from this ID to get AlertState
119- // let state = ALERTS.get_alert_by_id(session_key, alert_id).await?.state;
120-
121117 let store = CONFIG . storage ( ) . get_object_store ( ) ;
122118
119+ // fetch the alert object for the relevant ID
120+ let old_alert_config: AlertConfig = serde_json:: from_slice (
121+ & store
122+ . get_object ( & RelativePathBuf :: from_iter ( [
123+ PARSEABLE_ROOT_DIRECTORY ,
124+ ALERTS_ROOT_DIRECTORY ,
125+ & format ! ( "{alert_id}.json" ) ,
126+ ] ) )
127+ . await ?,
128+ ) ?;
129+
130+ let alert = alert. modify ( old_alert_config) ;
131+
123132 // modify on disk
124133 store. put_alert ( & alert. id . to_string ( ) , & alert) . await ?;
125134
@@ -136,11 +145,18 @@ pub async fn modify(
136145
137146// PUT /alerts/{alert_id}/update_state
138147pub async fn update_state ( req : HttpRequest , state : String ) -> Result < impl Responder , AlertError > {
148+ let session_key = extract_session_key_from_req ( & req) ?;
139149 let alert_id = req
140150 . match_info ( )
141151 . get ( "alert_id" )
142152 . ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
143153
154+ // check if alert id exists in map
155+ let alert = ALERTS . get_alert_by_id ( alert_id) . await ?;
156+
157+ // validate that the user has access to the tables mentioned
158+ user_auth_for_query ( & session_key, & alert. query ) . await ?;
159+
144160 // get current state
145161 let current_state = ALERTS . get_state ( alert_id) . await ?;
146162
0 commit comments