ResetsPasswords::postEmail()   B
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 24
ccs 0
cts 18
cp 0
rs 8.6846
cc 4
eloc 14
nc 6
nop 1
crap 20
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: Claudio Cardinale <[email protected]>
5
 * Date: 18/11/15
6
 * Time: 16.35
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
 */
19
20
namespace Tymon\JWTAuth\Support\auth;
21
22
23
use Illuminate\Http\JsonResponse;
24
use Illuminate\Http\Request;
25
use Illuminate\Mail\Message;
26
use Illuminate\Support\Facades\Password;
27
use Tymon\JWTAuth\Facades\JWTAuth;
28
29
/**
30
 * Class ResetsPasswords
31
 * @package Tymon\JWTAuth\Support\auth
32
 * @author Claudio Cardinale <[email protected]>
33
 * @copyright 2015 Claudio Cardinale
34
 * @version 1.0.0
35
 */
36
trait ResetsPasswords
37
{
38
39
    /**
40
     * Send a reset link to the given user.
41
     *
42
     * @param  \Illuminate\Http\Request  $request
43
     * @return \Illuminate\Http\Response
44
     */
45
    public function postEmail(Request $request)
46
    {
47
        $this->validate($request, $this->validator());
0 ignored issues
show
Bug introduced by
It seems like validate() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
48
49
50
        $usernames = $this->loginUsername();
51
        if(!is_array($usernames)) {
52
            $usernames = [$usernames];
53
        }
54
55
        $response = Password::sendResetLink($request->only($usernames), function (Message $message) {
56
            $message->subject($this->getEmailSubject());
57
        });
58
59
        switch ($response) {
60
            case Password::RESET_LINK_SENT:
61
                return new JsonResponse([], 200);
62
63
            case Password::INVALID_USER:
64
                return new JsonResponse(['error' => trans($response)],422);
65
            default:
66
                return new JsonResponse(['error' => trans($response)],422);
67
        }
68
    }
69
70
    /**
71
     * Array for validator
72
     *
73
     * @return array
74
     */
75
    protected function validator()
76
    {
77
        return ['email' => 'required|email'];
78
    }
79
80
    /**
81
     * Get the e-mail subject line to be used for the reset link email.
82
     *
83
     * @return string
84
     */
85
    protected function getEmailSubject()
86
    {
87
        return property_exists($this, 'subject') ? $this->subject : 'Your Password Reset Link';
0 ignored issues
show
Bug introduced by
The property subject does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
88
    }
89
90
91
    /**
92
     * Reset the given user's password.
93
     *
94
     * @param  \Illuminate\Http\Request  $request
95
     * @return \Illuminate\Http\Response
96
     */
97
    public function postReset(Request $request)
98
    {
99
        $this->validate($request, array_merge($this->validator(), [
0 ignored issues
show
Bug introduced by
It seems like validate() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
100
            'token' => 'required',
101
            'password' => 'required|confirmed|min:6',
102
        ]));
103
104
        $usernames = $this->loginUsername();
105
        if(!is_array($usernames)) {
106
            $usernames = [$usernames];
107
        }
108
109
        $credentials = $request->only(
110
            array_merge($usernames , ['password', 'password_confirmation', 'token'])
111
        );
112
113
        $token = '';
114
        $response = Password::reset($credentials, function ($user, $password) use(&$token) {
115
            $token = $this->resetPassword($user, $password);
116
        });
117
118
        switch ($response) {
119
            case Password::PASSWORD_RESET:
120
                $response = new JsonResponse(['token' => $token], 200);
121
                $response->header('Authorization', 'Bearer ' . $token);
122
                return $response;
123
            default:
124
                return new JsonResponse(['error' => trans($response)],422);
125
        }
126
    }
127
128
    /**
129
     * Reset the given user's password.
130
     *
131
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
132
     * @param  string  $password
133
     * @return sttring
134
     */
135
    protected function resetPassword($user, $password)
136
    {
137
        $user->password = bcrypt($password);
0 ignored issues
show
Bug introduced by
Accessing password on the interface Illuminate\Contracts\Auth\CanResetPassword suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
138
139
        $user->save();
0 ignored issues
show
Bug introduced by
The method save() does not seem to exist on object<Illuminate\Contra...\Auth\CanResetPassword>.

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...
140
141
        $token = JWTAuth::fromUser($user, $this->customClaims());
142
143
        return $token;
144
145
    }
146
147
    /**
148
     * Get the custom claims
149
     *
150
     * @return string
151
     */
152
    protected function customClaims()
153
    {
154
        return property_exists($this, 'custom') ? $this->custom : [];
0 ignored issues
show
Bug introduced by
The property custom does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
155
    }
156
157
    /**
158
     * Get the login username to be used by the controller.
159
     * it can be an array for multiple username (for example email and phone number)
160
     *
161
     * @return string|array
162
     */
163
    public function loginUsername()
164
    {
165
        return property_exists($this, 'username') ? $this->username : 'email';
0 ignored issues
show
Bug introduced by
The property username does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
166
    }
167
}