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

ptondereau / biscuit-sf-bundle / 30813598889

03 Aug 2026 12:26PM UTC coverage: 91.238% (-1.9%) from 93.09%
30813598889

push

github

web-flow
feat(revocation)!: compose revocation stores and align 401s with RFC 6750 (#7)

739 of 842 new or added lines in 27 files covered. (87.77%)

1843 of 2020 relevant lines covered (91.24%)

13.53 hits per line

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

80.0
/src/Revocation/Store/ChainRevocationWriter.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Biscuit\BiscuitBundle\Revocation\Store;
6

7
use Biscuit\BiscuitBundle\Event\BiscuitTokenRevokedEvent;
8
use Biscuit\BiscuitBundle\Revocation\Exception\RevocationStoreUnavailableException;
9
use Biscuit\BiscuitBundle\Revocation\RevocationEntry;
10
use Biscuit\BiscuitBundle\Revocation\RevocationWriterInterface;
11
use DateTimeImmutable;
12
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
13

14
final class ChainRevocationWriter implements RevocationWriterInterface
15
{
16
    /**
17
     * @param iterable<array-key, RevocationWriterInterface> $writers
18
     */
19
    public function __construct(
13 ✔
20
        private readonly iterable $writers,
21
        private readonly ?EventDispatcherInterface $eventDispatcher = null,
22
    ) {
23
    }
13 ✔
24

25
    public function revoke(RevocationEntry $entry): void
7 ✔
26
    {
27
        $failure = null;
7 ✔
28

29
        foreach ($this->writers as $writer) {
7 ✔
30
            try {
31
                $writer->revoke($entry);
7 ✔
32
            } catch (RevocationStoreUnavailableException $e) {
2 ✔
33
                $failure ??= $e;
2 ✔
34
            }
35
        }
36

37
        if (null !== $failure) {
7 ✔
38
            throw $failure;
2 ✔
39
        }
40

41
        $this->eventDispatcher?->dispatch(new BiscuitTokenRevokedEvent($entry));
5 ✔
42
    }
43

44
    public function unrevoke(string $revocationId): void
1 ✔
45
    {
46
        $failure = null;
1 ✔
47

48
        foreach ($this->writers as $writer) {
1 ✔
49
            try {
50
                $writer->unrevoke($revocationId);
1 ✔
NEW
51
            } catch (RevocationStoreUnavailableException $e) {
×
NEW
52
                $failure ??= $e;
×
53
            }
54
        }
55

56
        if (null !== $failure) {
1 ✔
NEW
57
            throw $failure;
×
58
        }
59
    }
60

61
    public function purgeExpired(?DateTimeImmutable $now = null): int
2 ✔
62
    {
63
        $now ??= new DateTimeImmutable();
2 ✔
64
        $purged = 0;
2 ✔
65
        $failure = null;
2 ✔
66

67
        foreach ($this->writers as $writer) {
2 ✔
68
            try {
69
                $purged += $writer->purgeExpired($now);
2 ✔
NEW
70
            } catch (RevocationStoreUnavailableException $e) {
×
NEW
71
                $failure ??= $e;
×
72
            }
73
        }
74

75
        if (null !== $failure) {
2 ✔
NEW
76
            throw $failure;
×
77
        }
78

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

© 2026 Coveralls, Inc