18
18
19
19
use crate :: {
20
20
option:: CONFIG ,
21
- storage:: object_storage:: alert_json_path,
21
+ storage:: { object_storage:: alert_json_path, ALERTS_ROOT_DIRECTORY , PARSEABLE_ROOT_DIRECTORY } ,
22
22
sync:: schedule_alert_task,
23
- utils:: { actix:: extract_session_key_from_req, uid :: Uid } ,
23
+ utils:: actix:: extract_session_key_from_req,
24
24
} ;
25
25
use actix_web:: { web, HttpRequest , Responder } ;
26
26
use bytes:: Bytes ;
27
- use tracing :: warn ;
27
+ use relative_path :: RelativePathBuf ;
28
28
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
+ } ;
30
32
31
33
// GET /alerts
32
34
/// 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> {
39
41
}
40
42
41
43
// 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 ( ) ;
43
46
// validate the incoming alert query
44
47
// 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) ? ;
46
49
user_auth_for_query ( & session_key, & alert. query ) . await ?;
47
50
48
51
// now that we've validated that the user can run this query
@@ -71,18 +74,27 @@ pub async fn get(req: HttpRequest) -> Result<impl Responder, AlertError> {
71
74
. get ( "alert_id" )
72
75
. ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
73
76
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
+
75
81
Ok ( web:: Json ( alert) )
76
82
}
77
83
78
84
// DELETE /alerts/{alert_id}
79
85
/// Deletion should happen from disk, sheduled tasks, then memory
80
86
pub async fn delete ( req : HttpRequest ) -> Result < impl Responder , AlertError > {
87
+ let session_key = extract_session_key_from_req ( & req) ?;
81
88
let alert_id = req
82
89
. match_info ( )
83
90
. get ( "alert_id" )
84
91
. ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
85
92
93
+ let alert = ALERTS . get_alert_by_id ( alert_id) . await ?;
94
+
95
+ // validate that the user has access to the tables mentioned
96
+ user_auth_for_query ( & session_key, & alert. query ) . await ?;
97
+
86
98
// delete from disk and memory
87
99
ALERTS . delete ( alert_id) . await ?;
88
100
@@ -95,31 +107,34 @@ pub async fn delete(req: HttpRequest) -> Result<impl Responder, AlertError> {
95
107
// PUT /alerts/{alert_id}
96
108
/// first save on disk, then in memory
97
109
/// then modify scheduled task
98
- pub async fn modify (
99
- req : HttpRequest ,
100
- mut alert : AlertConfig ,
101
- ) -> Result < impl Responder , AlertError > {
110
+ pub async fn modify ( req : HttpRequest , alert : AlertRequest ) -> Result < impl Responder , AlertError > {
102
111
let session_key = extract_session_key_from_req ( & req) ?;
103
112
let alert_id = req
104
113
. match_info ( )
105
114
. get ( "alert_id" )
106
115
. ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
107
116
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
- }
117
+ // check if alert id exists in map
118
+ ALERTS . get_alert_by_id ( alert_id) . await ?;
114
119
115
120
// validate that the user has access to the tables mentioned
116
121
user_auth_for_query ( & session_key, & alert. query ) . await ?;
117
122
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
-
121
123
let store = CONFIG . storage ( ) . get_object_store ( ) ;
122
124
125
+ // fetch the alert object for the relevant ID
126
+ let old_alert_config: AlertConfig = serde_json:: from_slice (
127
+ & store
128
+ . get_object ( & RelativePathBuf :: from_iter ( [
129
+ PARSEABLE_ROOT_DIRECTORY ,
130
+ ALERTS_ROOT_DIRECTORY ,
131
+ & format ! ( "{alert_id}.json" ) ,
132
+ ] ) )
133
+ . await ?,
134
+ ) ?;
135
+
136
+ let alert = alert. modify ( old_alert_config) ;
137
+
123
138
// modify on disk
124
139
store. put_alert ( & alert. id . to_string ( ) , & alert) . await ?;
125
140
@@ -136,11 +151,18 @@ pub async fn modify(
136
151
137
152
// PUT /alerts/{alert_id}/update_state
138
153
pub async fn update_state ( req : HttpRequest , state : String ) -> Result < impl Responder , AlertError > {
154
+ let session_key = extract_session_key_from_req ( & req) ?;
139
155
let alert_id = req
140
156
. match_info ( )
141
157
. get ( "alert_id" )
142
158
. ok_or ( AlertError :: Metadata ( "No alert ID Provided" ) ) ?;
143
159
160
+ // check if alert id exists in map
161
+ let alert = ALERTS . get_alert_by_id ( alert_id) . await ?;
162
+
163
+ // validate that the user has access to the tables mentioned
164
+ user_auth_for_query ( & session_key, & alert. query ) . await ?;
165
+
144
166
// get current state
145
167
let current_state = ALERTS . get_state ( alert_id) . await ?;
146
168
0 commit comments