• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

avoutic / web-framework / 19992797922

06 Dec 2025 06:45PM UTC coverage: 72.97%. First build
19992797922

push

github

avoutic
Use modern find() variants

27 of 29 new or added lines in 6 files covered. (93.1%)

1995 of 2734 relevant lines covered (72.97%)

2.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.78
/src/Security/DatabaseBlacklistService.php
1
<?php
2

3
/*
4
 * This file is part of WebFramework.
5
 *
6
 * (c) Avoutic <avoutic@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace WebFramework\Security;
13

14
use Carbon\Carbon;
15
use Psr\Log\LoggerInterface;
16
use WebFramework\Repository\BlacklistEntryRepository;
17

18
/**
19
 * Class DatabaseBlacklistService.
20
 *
21
 * Implements the BlacklistService interface using a database for storage.
22
 */
23
class DatabaseBlacklistService implements BlacklistService
24
{
25
    /**
26
     * DatabaseBlacklistService constructor.
27
     *
28
     * @param BlacklistEntryRepository $blacklistEntryRepository The blacklist entry repository
29
     * @param LoggerInterface          $logger                   The logger service
30
     * @param int                      $storePeriod              The period to store blacklist entries (in seconds)
31
     * @param int                      $threshold                The threshold for blacklisting
32
     * @param int                      $triggerPeriod            The period to consider for blacklisting (in seconds)
33
     */
34
    public function __construct(
2✔
35
        private BlacklistEntryRepository $blacklistEntryRepository,
36
        private LoggerInterface $logger,
37
        private int $storePeriod,
38
        private int $threshold,
39
        private int $triggerPeriod,
40
    ) {}
2✔
41

42
    /**
43
     * Perform cleanup of expired blacklist entries.
44
     */
45
    public function cleanup(): void
×
46
    {
47
        $this->logger->debug('Cleaning up blacklist entries');
×
48

49
        $cutoff = Carbon::now()->subSeconds($this->storePeriod);
×
50

NEW
51
        $this->blacklistEntryRepository
×
NEW
52
            ->query([
×
53
                'timestamp' => ['<', $cutoff->getTimestamp()],
×
54
            ])
×
55
            ->delete()
×
56
        ;
×
57
    }
58

59
    /**
60
     * Add an entry to the blacklist.
61
     *
62
     * @param string   $ip       The IP address to blacklist
63
     * @param null|int $userId   The user ID associated with the blacklist entry (if any)
64
     * @param string   $reason   The reason for blacklisting
65
     * @param int      $severity The severity of the blacklist entry
66
     */
67
    public function addEntry(string $ip, ?int $userId, string $reason, int $severity = 1): void
×
68
    {
69
        $this->logger->info('Adding blacklist entry', ['ip' => $ip, 'user_id' => $userId, 'reason' => $reason, 'severity' => $severity]);
×
70

71
        $fullReason = $reason;
×
72

73
        $entry = $this->blacklistEntryRepository->create([
×
74
            'ip' => $ip,
×
75
            'user_id' => $userId,
×
76
            'severity' => $severity,
×
77
            'reason' => $fullReason,
×
78
            'timestamp' => Carbon::now()->getTimestamp(),
×
79
        ]);
×
80
    }
81

82
    /**
83
     * Check if an IP address or user ID is blacklisted.
84
     *
85
     * @param string   $ip     The IP address to check
86
     * @param null|int $userId The user ID to check (if any)
87
     *
88
     * @return bool True if the IP or user is blacklisted, false otherwise
89
     */
90
    public function isBlacklisted(string $ip, ?int $userId): bool
2✔
91
    {
92
        $cutoff = Carbon::now()->subSeconds($this->triggerPeriod)->getTimestamp();
2✔
93
        $total = 0;
2✔
94

95
        $total = $this->blacklistEntryRepository
2✔
96
            ->query([
2✔
97
                'timestamp' => ['>', $cutoff],
2✔
98
            ])
2✔
99
            ->when(
2✔
100
                $userId !== null,
2✔
101
                fn ($query) => $query->where([
2✔
102
                    'OR' => [
2✔
103
                        'ip' => $ip,
2✔
104
                        'user_id' => $userId,
2✔
105
                    ],
2✔
106
                ]),
2✔
107
                fn ($query) => $query->where([
2✔
108
                    'ip' => $ip,
2✔
109
                ]),
2✔
110
            )
2✔
111
            ->sum('severity')
2✔
112
        ;
2✔
113

114
        $isBlacklisted = $total > $this->threshold;
2✔
115

116
        $this->logger->debug('Is blacklisted', ['ip' => $ip, 'user_id' => $userId, 'is_blacklisted' => $isBlacklisted, 'total' => $total]);
2✔
117

118
        return $isBlacklisted;
2✔
119
    }
120
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc