InMemoryTokensRepository.php 3.29 KB
Newer Older
Jacob Priddy's avatar
Jacob Priddy committed
1
2
3
4
5
<?php


namespace Source\Gateways\Tokens;

Jacob Priddy's avatar
Jacob Priddy committed
6
use Carbon\Carbon;
Jacob Priddy's avatar
Jacob Priddy committed
7
use Source\Entities\Token;
8
9
use Source\Entities\RawToken;
use Source\Entities\HashedSearchable;
10
use Source\Exceptions\EntityNotFoundException;
Jacob Priddy's avatar
Jacob Priddy committed
11

Jacob Priddy's avatar
Jacob Priddy committed
12
13
class InMemoryTokensRepository implements TokensRepository
{
14
    protected static int $idCounter = 100;
15

Jacob Priddy's avatar
Jacob Priddy committed
16
17
18
19
20
21
    /**
     * @var Token[]
     */
    protected array $tokens = [];

    /** @inheritDoc */
Jacob Priddy's avatar
Jacob Priddy committed
22
23
    public function create(Token $token): Token
    {
24
25
26
27
        if ($token->hasIdOf(0)) {
            $token->setId(static::$idCounter++);
        }

Jacob Priddy's avatar
Jacob Priddy committed
28
        $this->tokens[] = $token;
29

Jacob Priddy's avatar
Jacob Priddy committed
30
31
32
        return $token;
    }

33
34
35
    /**
     * @inheritDoc
     */
36
    public function createLoginToken(string $userId, string $salt): RawToken
37
    {
38
39
40
        $raw = self::generateTokenString();
        return new RawToken($raw, $this->create(new Token(
            0,
41
            $userId,
42
            HashedSearchable::hash($salt, $raw),
43
44
            null,
            Carbon::now()->addDay()
45
        )));
46
47
    }

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    /**
     * @inheritDoc
     */
    public function update(string $tokenId, Token $token): Token
    {
        foreach ($this->tokens as $key=>$tok) {
            if ($tok->hasIdOf($tokenId)) {
                $this->tokens[$key] = $token;

                return $token;
            }
        }

        throw new EntityNotFoundException();
    }

64
    /**
65
66
     * @param string|null         $userId
     * @param \Carbon\Carbon|null $validAt
67
68
     * @return Token[]
     */
69
    public function filter(?string $userId = null, ?Carbon $validAt = null): array
70
    {
71
72
        return array_values(array_filter($this->tokens, static function (Token $token) use ($userId, $validAt) {
            $include = true;
73

74
75
76
            if ($validAt) {
                $include = $token->isValidAtTime($validAt);
            }
Jacob Priddy's avatar
Jacob Priddy committed
77

78
79
80
81
82
            if ($userId !== null) {
                $include = $include && $token->hasUserIdOf($userId);
            }

            return $include;
83
84
85
        }));
    }

Jacob Priddy's avatar
Jacob Priddy committed
86
    /** @inheritDoc */
87
    public function findValidToken(?HashedSearchable $hash): ?Token
Jacob Priddy's avatar
Jacob Priddy committed
88
    {
Jacob Priddy's avatar
Jacob Priddy committed
89
        foreach ($this->tokens as $token) {
90
            if ($token->matches($hash) && $token->isValidAtTime(Carbon::now())) {
Jacob Priddy's avatar
Jacob Priddy committed
91
92
                return $token;
            }
Jacob Priddy's avatar
Jacob Priddy committed
93
94
95
96
        }

        return null;
    }
97
98
99
100

    /**
     * @inheritDoc
     */
101
    public function invalidateToken(?HashedSearchable $hash): void
Jacob Priddy's avatar
Jacob Priddy committed
102
    {
103
        $tok = $this->findValidToken($hash);
104
105
106
107

        if ($tok) {
            $tok->setExpiresAt(Carbon::now());
        }
108
    }
Jacob Priddy's avatar
Jacob Priddy committed
109
110
111
112
113
114
115
116
117
118

    /**
     * @inheritDoc
     */
    public static function generateTokenString(): string
    {
        // For now just do what the actual database implementation does
        // We don't need to do anything special
        return DatabaseTokensRepository::generateTokenString();
    }
Jacob Priddy's avatar
Jacob Priddy committed
119
120
121
122
123
124
125
126
127
128
129
130

    /**
     * @inheritDoc
     */
    public function invalidateTokenById(string $tokenId): void
    {
        foreach ($this->tokens as $token) {
            if ($token->hasIdOf($tokenId) && $token->isValid()) {
                $token->setExpiresAt(Carbon::now());
            }
        }
    }
131
132
133
134
135
136
137
138
139
140
141
142
143
144

    /**
     * @inheritDoc
     */
    public function get(string $tokenId): ?Token
    {
        foreach ($this->tokens as $token) {
            if ($token->hasIdOf($tokenId)) {
                return $token;
            }
        }

        return null;
    }
Jacob Priddy's avatar
Jacob Priddy committed
145
}