Completed
Push — master ( edb43e...425779 )
by Abdelrahman
10:35
created

PasswordResetBroker::getRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Fort Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Fort Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
declare(strict_types=1);
17
18
namespace Rinvex\Fort\Services;
19
20
use Closure;
21
use Illuminate\Support\Arr;
22
use UnexpectedValueException;
23
use Illuminate\Contracts\Auth\UserProvider;
24
use Rinvex\Fort\Contracts\CanResetPasswordContract;
25
use Rinvex\Fort\Contracts\PasswordResetTokenRepositoryContract;
26
use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
27
28
class PasswordResetBroker implements PasswordBrokerContract
29
{
30
    /**
31
     * The password token repository.
32
     *
33
     * @var \Illuminate\Auth\Passwords\TokenRepositoryInterface
34
     */
35
    protected $tokens;
36
37
    /**
38
     * The user provider implementation.
39
     *
40
     * @var \Illuminate\Contracts\Auth\UserProvider
41
     */
42
    protected $users;
43
44
    /**
45
     * The custom password validator callback.
46
     *
47
     * @var \Closure
48
     */
49
    protected $passwordValidator;
50
51
    /**
52
     * Create a new password broker instance.
53
     *
54
     * @param \Rinvex\Fort\Contracts\PasswordResetTokenRepositoryContract $tokens
55
     * @param \Illuminate\Contracts\Auth\UserProvider                     $users
56
     */
57
    public function __construct(PasswordResetTokenRepositoryContract $tokens, UserProvider $users)
58
    {
59
        $this->users = $users;
60
        $this->tokens = $tokens;
0 ignored issues
show
Documentation Bug introduced by
It seems like $tokens of type object<Rinvex\Fort\Contr...okenRepositoryContract> is incompatible with the declared type object<Illuminate\Auth\P...kenRepositoryInterface> of property $tokens.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
61
    }
62
63
    /**
64
     * Send a password reset link to a user.
65
     *
66
     * @param array $credentials
67
     *
68
     * @return string
69
     */
70
    public function sendResetLink(array $credentials)
71
    {
72
        // First we will check to see if we found a user at the given credentials and
73
        // if we did not we will redirect back to this current URI with a piece of
74
        // "flash" data in the session to indicate to the developers the errors.
75
        $user = $this->getUser($credentials);
76
77
        if (is_null($user)) {
78
            return static::INVALID_USER;
79
        }
80
81
        // Once we have the reset password token, we are ready to send the message out
82
        // to this user with a link for password. We will then redirect back to the
83
        // current URI having nothing set in the session to indicate errors.
84
        $data = $this->tokens->getData($user, $token = $this->tokens->create($user));
0 ignored issues
show
Documentation introduced by
$user is of type object<Illuminate\Contracts\Auth\Authenticatable>, but the function expects a object<Illuminate\Contra...\Auth\CanResetPassword>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
The method getData() does not seem to exist on object<Illuminate\Auth\P...kenRepositoryInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
85
        $expiration = $this->tokens->getExpiration();
0 ignored issues
show
Bug introduced by
The method getExpiration() does not seem to exist on object<Illuminate\Auth\P...kenRepositoryInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
86
87
        // Returned token is hashed, and we need the
88
        // public token to be sent to the user
89
        $data['token'] = $token;
90
91
        $user->sendPasswordResetNotification($data, $expiration);
92
93
        return static::RESET_LINK_SENT;
94
    }
95
96
    /**
97
     * Reset the password for the given token.
98
     *
99
     * @param array    $credentials
100
     * @param \Closure $callback
101
     *
102
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string|\Illuminate\Contracts\Auth\Authenticatable.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
103
     */
104
    public function reset(array $credentials, Closure $callback)
105
    {
106
        // If the responses from the validate method is not a user instance, we will
107
        // assume that it is a redirect and simply return it from this method and
108
        // the user is properly redirected having an error message on the post.
109
        $user = $this->validateReset($credentials);
110
111
        if (! $user instanceof CanResetPasswordContract) {
112
            return $user;
113
        }
114
115
        $password = $credentials['password'];
116
117
        // Once the reset has been validated, we'll call the given callback with the
118
        // new password. This gives the user an opportunity to store the password
119
        // in their persistent storage. Then we'll delete the token and return.
120
        $callback($user, $password);
121
122
        $this->tokens->delete($user);
123
124
        return static::PASSWORD_RESET;
125
    }
126
127
    /**
128
     * Set a custom password validator.
129
     *
130
     * @param \Closure $callback
131
     *
132
     * @return void
133
     */
134
    public function validator(Closure $callback)
135
    {
136
        $this->passwordValidator = $callback;
137
    }
138
139
    /**
140
     * Determine if the passwords match for the request.
141
     *
142
     * @param array $credentials
143
     *
144
     * @return bool
145
     */
146
    public function validateNewPassword(array $credentials)
147
    {
148
        if (isset($this->passwordValidator)) {
149
            list($password, $confirm) = [
150
                $credentials['password'],
151
                $credentials['password_confirmation'],
152
            ];
153
154
            return call_user_func(
155
                $this->passwordValidator, $credentials
156
            ) && $password === $confirm;
157
        }
158
159
        return $this->validatePasswordWithDefaults($credentials);
160
    }
161
162
    /**
163
     * Determine if the passwords are valid for the request.
164
     *
165
     * @param array $credentials
166
     *
167
     * @return bool
168
     */
169
    protected function validatePasswordWithDefaults(array $credentials)
170
    {
171
        list($password, $confirm) = [
172
            $credentials['password'],
173
            $credentials['password_confirmation'],
174
        ];
175
176
        return $password === $confirm && mb_strlen($password) >= 6;
177
    }
178
179
    /**
180
     * Get the user for the given credentials.
181
     *
182
     * @param array $credentials
183
     *
184
     * @throws \UnexpectedValueException
185
     *
186
     * @return \Rinvex\Fort\Contracts\CanResetPasswordContract
0 ignored issues
show
Documentation introduced by
Should the return type not be \Illuminate\Contracts\Auth\Authenticatable|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
187
     */
188
    public function getUser(array $credentials)
189
    {
190
        $credentials = Arr::except($credentials, ['token']);
191
192
        $user = $this->users->retrieveByCredentials($credentials);
193
194
        if ($user && ! $user instanceof CanResetPasswordContract) {
195
            throw new UnexpectedValueException('User must implement CanResetPassword interface.');
196
        }
197
198
        return $user;
199
    }
200
201
    /**
202
     * Create a new password reset token for the given user.
203
     *
204
     * @param CanResetPasswordContract $user
205
     *
206
     * @return string
207
     */
208
    public function createToken(CanResetPasswordContract $user)
209
    {
210
        return $this->tokens->create($user);
0 ignored issues
show
Documentation introduced by
$user is of type object<Rinvex\Fort\Contr...nResetPasswordContract>, but the function expects a object<Illuminate\Contra...\Auth\CanResetPassword>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
211
    }
212
213
    /**
214
     * Delete password reset tokens of the given user.
215
     *
216
     * @param \Illuminate\Contracts\Auth\CanResetPassword $user
0 ignored issues
show
Documentation introduced by
Should the type for parameter $user not be CanResetPasswordContract?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
217
     *
218
     * @return void
219
     */
220
    public function deleteToken(CanResetPasswordContract $user)
221
    {
222
        $this->tokens->delete($user);
0 ignored issues
show
Documentation introduced by
$user is of type object<Rinvex\Fort\Contr...nResetPasswordContract>, but the function expects a object<Illuminate\Contra...\Auth\CanResetPassword>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
223
    }
224
225
    /**
226
     * Validate the given password reset token.
227
     *
228
     * @param \Rinvex\Fort\Contracts\CanResetPasswordContract $user
229
     * @param string                                          $token
230
     *
231
     * @return bool
232
     */
233
    public function tokenExists(CanResetPasswordContract $user, $token)
234
    {
235
        return $this->tokens->exists($user, $token);
0 ignored issues
show
Documentation introduced by
$user is of type object<Rinvex\Fort\Contr...nResetPasswordContract>, but the function expects a object<Illuminate\Contra...\Auth\CanResetPassword>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
236
    }
237
238
    /**
239
     * Get the password reset token repository implementation.
240
     *
241
     * @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
242
     */
243
    public function getRepository()
244
    {
245
        return $this->tokens;
246
    }
247
248
    /**
249
     * Validate a password reset for the given credentials.
250
     *
251
     * @param array $credentials
252
     *
253
     * @return \Illuminate\Contracts\Auth\CanResetPassword|string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|\Illuminate\Contracts\Auth\Authenticatable?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
254
     */
255
    protected function validateReset(array $credentials)
256
    {
257
        if (is_null($user = $this->getUser($credentials))) {
258
            return static::INVALID_USER;
259
        }
260
261
        if (! $this->validateNewPassword($credentials)) {
262
            return static::INVALID_PASSWORD;
263
        }
264
265
        if (! $this->tokens->exists($user, $credentials['token'])) {
0 ignored issues
show
Documentation introduced by
$user is of type object<Illuminate\Contracts\Auth\Authenticatable>, but the function expects a object<Illuminate\Contra...\Auth\CanResetPassword>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
266
            return static::INVALID_TOKEN;
267
        }
268
269
        return $user;
270
    }
271
}
272