CacheProvider   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 38
c 1
b 0
f 0
dl 0
loc 140
rs 10
wmc 18

10 Methods

Rating   Name   Duplication   Size   Complexity  
A retrieveById() 0 3 1
A retrieveByToken() 0 3 1
A getGenericUser() 0 3 1
A buildUserTokenCacheKey() 0 3 1
A validateCredentials() 0 3 1
A store() 0 4 3
A buildCacheKey() 0 3 1
B retrieveByCredentials() 0 21 7
A __construct() 0 12 1
A updateRememberToken() 0 12 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: hugh.li
5
 * Date: 2021/8/23
6
 * Time: 14:33
7
 */
8
9
namespace HughCube\Laravel\Auth;
10
11
use BadMethodCallException;
12
use Carbon\Carbon;
13
use Illuminate\Auth\GenericUser;
14
use Illuminate\Cache\TaggableStore;
15
use Illuminate\Contracts\Auth\Authenticatable;
16
use Illuminate\Contracts\Auth\UserProvider;
17
use Illuminate\Contracts\Cache\Repository;
18
use Illuminate\Contracts\Hashing\Hasher;
19
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
20
use Illuminate\Support\Facades\Cache;
21
use Illuminate\Support\Str;
22
use Psr\SimpleCache\InvalidArgumentException;
23
24
class CacheProvider implements UserProvider
25
{
26
    /**
27
     * @var string
28
     */
29
    protected $cacheKeyPrefix;
30
31
    /**
32
     * @var int
33
     */
34
    protected $expiresInSeconds;
35
36
    /**
37
     * @var array
38
     */
39
    protected $cacheTags;
40
41
    /**
42
     * @var string|Repository
43
     */
44
    protected $cache;
45
46
    /**
47
     * The hasher implementation.
48
     *
49
     * @var Hasher
50
     */
51
    protected $hasher;
52
53
    /**
54
     * @param  HasherContract  $hasher
55
     * @param  string|Repository  $cache
56
     * @param  int  $expiresInSeconds
57
     * @param  string  $cacheKeyPrefix
58
     * @param  array  $cacheTags
59
     */
60
    public function __construct(
61
        HasherContract $hasher,
62
        $cache,
63
        int $expiresInSeconds,
64
        string $cacheKeyPrefix,
65
        array $cacheTags
66
    ) {
67
        $this->hasher = $hasher;
68
        $this->cache = $cache;
69
        $this->expiresInSeconds = $expiresInSeconds;
70
        $this->cacheKeyPrefix = $cacheKeyPrefix;
71
        $this->cacheTags = $cacheTags;
72
    }
73
74
    /**
75
     * @throws BadMethodCallException
76
     */
77
    public function retrieveById($identifier)
78
    {
79
        throw new BadMethodCallException('Do not implement!');
80
    }
81
82
    /**
83
     * @throws BadMethodCallException
84
     */
85
    public function retrieveByToken($identifier, $token)
86
    {
87
        throw new BadMethodCallException('Do not implement!');
88
    }
89
90
    /**
91
     * @throws InvalidArgumentException
92
     */
93
    public function updateRememberToken(Authenticatable $user, $token)
94
    {
95
        $cacheKey = $this->buildUserTokenCacheKey($token);
96
97
        $this->store()->set(
98
            $cacheKey,
99
            $this->getGenericUser([
100
                $user->getAuthIdentifierName() => $user->getAuthIdentifier(),
101
                $user->getRememberTokenName() => $token,
102
                'password' => $user->getAuthPassword(),
103
            ]),
104
            Carbon::now()->addSeconds($this->expiresInSeconds)
105
        );
106
    }
107
108
    /**
109
     * @param  array  $credentials
110
     * @return Authenticatable|null
111
     * @throws InvalidArgumentException
112
     */
113
    public function retrieveByCredentials(array $credentials)
114
    {
115
        $user = null;
116
        foreach ($credentials as $key => $value) {
117
            if (Str::contains($key, 'password')) {
118
                continue;
119
            }
120
121
            $user = $this->store()->get($this->buildUserTokenCacheKey($value));
122
            break;
123
        }
124
125
        $user = $user instanceof Authenticatable ? $user : null;
126
127
        if (!empty($credentials['password']) && $user instanceof Authenticatable) {
128
            if (!$this->validateCredentials($user, $credentials)) {
129
                return null;
130
            }
131
        }
132
133
        return $user;
134
    }
135
136
    public function validateCredentials(Authenticatable $user, array $credentials): bool
137
    {
138
        return $this->hasher->check($credentials['password'], $user->getAuthPassword());
139
    }
140
141
    protected function store(): Repository
142
    {
143
        $store = $this->cache instanceof Repository ? $this->cache : Cache::store($this->cache);
144
        return $store instanceof TaggableStore ? $store->tags($this->cacheTags) : $store;
145
    }
146
147
    protected function buildUserTokenCacheKey(string $token): string
148
    {
149
        return $this->buildCacheKey(sprintf('%s:%s', 'auth:token', $token));
150
    }
151
152
    protected function buildCacheKey(string $key): string
153
    {
154
        return sprintf('%s:%s', $this->cacheKeyPrefix, $key);
155
    }
156
157
    /**
158
     * @param  array  $user
159
     * @return GenericUser
160
     */
161
    public function getGenericUser(array $user): GenericUser
162
    {
163
        return new GenericUser($user);
164
    }
165
}
166