Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
93.75% covered (success)
93.75%
15 / 16
90.91% covered (success)
90.91%
10 / 11
66.67% covered (warning)
66.67%
6 / 9
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiKeyService
93.75% covered (success)
93.75%
15 / 16
90.91% covered (success)
90.91%
10 / 11
66.67% covered (warning)
66.67%
6 / 9
80.00% covered (warning)
80.00%
4 / 5
10.37
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hashKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createKey
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findValidKey
83.33% covered (warning)
83.33%
5 / 6
85.71% covered (warning)
85.71%
6 / 7
40.00% covered (danger)
40.00%
2 / 5
0.00% covered (danger)
0.00%
0 / 1
7.46
1<?php
2
3namespace App\Service\Data;
4
5use App\Dto\Result\GeneratedApiKey;
6use App\Entity\ApiKey;
7use App\Repository\ApiKeyRepositoryInterface;
8use Doctrine\ORM\EntityManagerInterface;
9use Psr\Clock\ClockInterface;
10
11/**
12 * @author Wilhelm Zwertvaegher
13 */
14readonly class ApiKeyService implements ApiKeyServiceInterface
15{
16    public function __construct(
17        private ApiKeyRepositoryInterface $repository,
18        private ApiKeyGeneratorInterface $generator,
19        private EntityManagerInterface $entityManager,
20        private ClockInterface $clock,
21    ) {
22    }
23
24    public function findKey(int $id): ?ApiKey
25    {
26        return $this->repository->findById($id);
27    }
28
29    private function hashKey(string $key): string
30    {
31        return hash('sha256', $key);
32    }
33
34    public function createKey(): GeneratedApiKey
35    {
36        $rawKey = $this->generator->generate();
37
38        $apiKey = new ApiKey(
39            $this->hashKey($rawKey),
40            $this->clock->now()
41        );
42
43        $this->entityManager->persist($apiKey);
44
45        return new GeneratedApiKey($apiKey, $rawKey);
46    }
47
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
52            return null;
53        }
54
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
56            return null;
57        }
58
59        return $apiKey;
60    }
61}

Paths

Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

ApiKeyService->__construct
16    public function __construct(
17        private ApiKeyRepositoryInterface $repository,
18        private ApiKeyGeneratorInterface $generator,
19        private EntityManagerInterface $entityManager,
20        private ClockInterface $clock,
21    ) {
22    }
ApiKeyService->createKey
36        $rawKey = $this->generator->generate();
37
38        $apiKey = new ApiKey(
39            $this->hashKey($rawKey),
40            $this->clock->now()
41        );
42
43        $this->entityManager->persist($apiKey);
44
45        return new GeneratedApiKey($apiKey, $rawKey);
46    }
ApiKeyService->findKey
24    public function findKey(int $id): ?ApiKey
25    {
26        return $this->repository->findById($id);
27    }
ApiKeyService->findValidKey
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
 
52            return null;
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
56            return null;
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
59        return $apiKey;
60    }
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
56            return null;
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
 
59        return $apiKey;
60    }
ApiKeyService->hashKey
29    private function hashKey(string $key): string
30    {
31        return hash('sha256', $key);
32    }
{main}
3namespace App\Service\Data;
4
5use App\Dto\Result\GeneratedApiKey;
6use App\Entity\ApiKey;
7use App\Repository\ApiKeyRepositoryInterface;
8use Doctrine\ORM\EntityManagerInterface;
9use Psr\Clock\ClockInterface;
10
11/**
12 * @author Wilhelm Zwertvaegher
13 */
14readonly class ApiKeyService implements ApiKeyServiceInterface
15{
16    public function __construct(
17        private ApiKeyRepositoryInterface $repository,
18        private ApiKeyGeneratorInterface $generator,
19        private EntityManagerInterface $entityManager,
20        private ClockInterface $clock,
21    ) {
22    }
23
24    public function findKey(int $id): ?ApiKey
25    {
26        return $this->repository->findById($id);
27    }
28
29    private function hashKey(string $key): string
30    {
31        return hash('sha256', $key);
32    }
33
34    public function createKey(): GeneratedApiKey
35    {
36        $rawKey = $this->generator->generate();
37
38        $apiKey = new ApiKey(
39            $this->hashKey($rawKey),
40            $this->clock->now()
41        );
42
43        $this->entityManager->persist($apiKey);
44
45        return new GeneratedApiKey($apiKey, $rawKey);
46    }
47
48    public function findValidKey(string $receivedKey): ?ApiKey
49    {
50        $apiKey = $this->repository->findByHash($this->hashKey($receivedKey));
51        if (!$apiKey) {
52            return null;
53        }
54
55        if ($apiKey->getExpiresAt() && $apiKey->getExpiresAt() < $this->clock->now()) {
56            return null;
57        }
58
59        return $apiKey;
60    }