@@ -5,6 +5,7 @@ use crate::db::installation_code::InstallationCode;
5
5
use crate :: db:: tables:: DbTable ;
6
6
use crate :: firewall:: firewall:: Firewall ;
7
7
use crate :: proto:: appguard:: { AppGuardIpInfo , Log } ;
8
+ use chrono:: Utc ;
8
9
use ipnetwork:: IpNetwork ;
9
10
use nullnet_libdatastore:: {
10
11
AdvanceFilter , BatchCreateBody , BatchCreateRequest , BatchDeleteBody , BatchDeleteRequest ,
@@ -19,7 +20,9 @@ use nullnet_liberror::{location, Error, ErrorHandler, Location};
19
20
use serde_json:: { json, Value } ;
20
21
use std:: collections:: HashMap ;
21
22
use std:: net:: IpAddr ;
23
+ use std:: ops:: Sub ;
22
24
use std:: str:: FromStr ;
25
+ use std:: time:: Duration ;
23
26
24
27
#[ derive( Debug , Clone ) ]
25
28
pub struct DatastoreWrapper {
@@ -1231,6 +1234,91 @@ impl DatastoreWrapper {
1231
1234
1232
1235
Ok ( id)
1233
1236
}
1237
+
1238
+ pub async fn get_recent_urls_for_ip (
1239
+ & self ,
1240
+ token : & str ,
1241
+ ip : IpAddr ,
1242
+ period : usize ,
1243
+ ) -> Result < Vec < String > , Error > {
1244
+ let table = DbTable :: HttpRequest . to_str ( ) ;
1245
+ let filter_1 = AdvanceFilter {
1246
+ r#type : String :: from ( "criteria" ) ,
1247
+ field : String :: from ( "ip" ) ,
1248
+ operator : String :: from ( "equal" ) ,
1249
+ entity : String :: from ( table) ,
1250
+ values : format ! ( "[\" {ip}\" ]" ) ,
1251
+ } ;
1252
+
1253
+ let filter_2 = AdvanceFilter {
1254
+ r#type : String :: from ( "operator" ) ,
1255
+ field : String :: new ( ) ,
1256
+ operator : String :: from ( "and" ) ,
1257
+ entity : String :: new ( ) ,
1258
+ values : String :: new ( ) ,
1259
+ } ;
1260
+
1261
+ let timestamp = Utc :: now ( )
1262
+ . sub ( Duration :: from_secs (
1263
+ u64:: try_from ( period) . handle_err ( location ! ( ) ) ?,
1264
+ ) )
1265
+ . to_rfc3339 ( ) ;
1266
+ let filter_3 = AdvanceFilter {
1267
+ r#type : String :: from ( "criteria" ) ,
1268
+ field : String :: from ( "timestamp" ) ,
1269
+ operator : String :: from ( "greater_than_or_equal" ) ,
1270
+ entity : String :: from ( table) ,
1271
+ values : format ! ( "[\" {timestamp}\" ]" ) ,
1272
+ } ;
1273
+
1274
+ let request = GetByFilterRequest {
1275
+ body : Some ( GetByFilterBody {
1276
+ pluck : vec ! [ "id" . into( ) , "original_url" . into( ) ] ,
1277
+ advance_filters : vec ! [ filter_1, filter_2, filter_3] ,
1278
+ order_by : String :: new ( ) ,
1279
+ limit : i32:: MAX ,
1280
+ offset : 0 ,
1281
+ order_direction : String :: new ( ) ,
1282
+ joins : vec ! [ ] ,
1283
+ multiple_sort : vec ! [ ] ,
1284
+ pluck_object : HashMap :: new ( ) ,
1285
+ date_format : String :: new ( ) ,
1286
+ is_case_sensitive_sorting : true ,
1287
+ } ) ,
1288
+ params : Some ( Params {
1289
+ id : String :: new ( ) ,
1290
+ table : table. to_string ( ) ,
1291
+ r#type : String :: from ( "root" ) ,
1292
+ } ) ,
1293
+ } ;
1294
+
1295
+ let result = self . inner . clone ( ) . get_by_filter ( request, token) . await ?. data ;
1296
+
1297
+ Self :: internal_recent_urls_for_ip_parse_response_data ( result)
1298
+ }
1299
+
1300
+ fn internal_recent_urls_for_ip_parse_response_data ( data : String ) -> Result < Vec < String > , Error > {
1301
+ let array_val = serde_json:: from_str :: < serde_json:: Value > ( & data) . handle_err ( location ! ( ) ) ?;
1302
+ let array = array_val
1303
+ . as_array ( )
1304
+ . ok_or ( "Failed to parse response" )
1305
+ . handle_err ( location ! ( ) ) ?;
1306
+
1307
+ let mut ret_val = Vec :: new ( ) ;
1308
+
1309
+ for i in array {
1310
+ let Some ( map) = i. as_object ( ) else { continue } ;
1311
+ let Some ( original_url_val) = map. get ( "original_url" ) else {
1312
+ continue ;
1313
+ } ;
1314
+ let Some ( original_url) = original_url_val. as_str ( ) else {
1315
+ continue ;
1316
+ } ;
1317
+ ret_val. push ( original_url. to_string ( ) ) ;
1318
+ }
1319
+
1320
+ Ok ( ret_val)
1321
+ }
1234
1322
}
1235
1323
1236
1324
#[ cfg( test) ]
0 commit comments