@@ -12,6 +12,8 @@ import (
12
12
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
13
13
"github.com/crowdsecurity/crowdsec/pkg/database/ent/allowlist"
14
14
"github.com/crowdsecurity/crowdsec/pkg/database/ent/allowlistitem"
15
+ "github.com/crowdsecurity/crowdsec/pkg/database/ent/decision"
16
+
15
17
"github.com/crowdsecurity/crowdsec/pkg/models"
16
18
"github.com/crowdsecurity/crowdsec/pkg/types"
17
19
)
@@ -389,3 +391,96 @@ func (c *Client) GetAllowlistsContentForAPIC(ctx context.Context) ([]net.IP, []*
389
391
390
392
return ips , nets , nil
391
393
}
394
+
395
+ func (c * Client ) ApplyAllowlistsToExistingDecisions (ctx context.Context ) (int , error ) {
396
+ // Soft delete (set expiration to now) all decisions that matches any allowlist
397
+
398
+ totalCount := 0
399
+
400
+ // Get all non-expired allowlist items
401
+ // We will match them one by one against all decisions
402
+ allowlistItems , err := c .Ent .AllowListItem .Query ().
403
+ Where (
404
+ allowlistitem .Or (
405
+ allowlistitem .ExpiresAtGTE (time .Now ().UTC ()),
406
+ allowlistitem .ExpiresAtIsNil (),
407
+ ),
408
+ ).All (ctx )
409
+ if err != nil {
410
+ return 0 , fmt .Errorf ("unable to get allowlist items: %w" , err )
411
+ }
412
+
413
+ now := time .Now ().UTC ()
414
+
415
+ for _ , item := range allowlistItems {
416
+ updateQuery := c .Ent .Decision .Update ().SetUntil (now ).Where (decision .UntilGTE (now ))
417
+ switch item .IPSize {
418
+ case 4 :
419
+ updateQuery = updateQuery .Where (
420
+ decision .And (
421
+ decision .IPSizeEQ (4 ),
422
+ decision .Or (
423
+ decision .And (
424
+ decision .StartIPLTE (item .StartIP ),
425
+ decision .EndIPGTE (item .EndIP ),
426
+ ),
427
+ decision .And (
428
+ decision .StartIPGTE (item .StartIP ),
429
+ decision .EndIPLTE (item .EndIP ),
430
+ ),
431
+ )))
432
+ case 16 :
433
+ updateQuery = updateQuery .Where (
434
+ decision .And (
435
+ decision .IPSizeEQ (16 ),
436
+ decision .Or (
437
+ decision .And (
438
+ decision .Or (
439
+ decision .StartIPLT (item .StartIP ),
440
+ decision .And (
441
+ decision .StartIPEQ (item .StartIP ),
442
+ decision .StartSuffixLTE (item .StartSuffix ),
443
+ )),
444
+ decision .Or (
445
+ decision .EndIPGT (item .EndIP ),
446
+ decision .And (
447
+ decision .EndIPEQ (item .EndIP ),
448
+ decision .EndSuffixGTE (item .EndSuffix ),
449
+ ),
450
+ ),
451
+ ),
452
+ decision .And (
453
+ decision .Or (
454
+ decision .StartIPGT (item .StartIP ),
455
+ decision .And (
456
+ decision .StartIPEQ (item .StartIP ),
457
+ decision .StartSuffixGTE (item .StartSuffix ),
458
+ )),
459
+ decision .Or (
460
+ decision .EndIPLT (item .EndIP ),
461
+ decision .And (
462
+ decision .EndIPEQ (item .EndIP ),
463
+ decision .EndSuffixLTE (item .EndSuffix ),
464
+ ),
465
+ ),
466
+ ),
467
+ ),
468
+ ),
469
+ )
470
+ default :
471
+ // This should never happen
472
+ // But better safe than sorry and just skip it instead of expiring all decisions
473
+ c .Log .Errorf ("unexpected IP size %d for allowlist item %s" , item .IPSize , item .Value )
474
+ continue
475
+ }
476
+ // Update the decisions
477
+ count , err := updateQuery .Save (ctx )
478
+ if err != nil {
479
+ c .Log .Errorf ("unable to expire existing decisions: %s" , err )
480
+ continue
481
+ }
482
+ totalCount += count
483
+ }
484
+
485
+ return totalCount , nil
486
+ }
0 commit comments