PassportProxy   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
eloc 53
c 6
b 1
f 0
dl 0
loc 139
rs 10
wmc 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A attemptRefresh() 0 4 1
A getAccessToken() 0 3 1
A proxy() 0 23 2
A getClientCredentials() 0 16 2
A attemptLogout() 0 17 2
A attemptLogin() 0 26 2
1
<?php
2
3
namespace Signifly\Janitor;
4
5
use GuzzleHttp\Client as HttpClient;
6
use Illuminate\Auth\Events\Attempting;
7
use Illuminate\Auth\Events\Authenticated;
8
use Illuminate\Auth\Events\Failed;
9
use Illuminate\Auth\Events\Login;
10
use Illuminate\Auth\Events\Logout;
11
use Illuminate\Http\Response;
12
use Illuminate\Support\Arr;
13
use Illuminate\Support\Facades\Auth;
14
use Illuminate\Support\Facades\DB;
15
use Laravel\Passport\Passport;
16
use Signifly\Janitor\Exceptions\InvalidClientCredentialsException;
17
use Signifly\Janitor\Exceptions\InvalidCredentialsException;
18
use Symfony\Component\HttpKernel\Exception\HttpException;
19
20
class PassportProxy extends AbstractProxy
21
{
22
    /**
23
     * Attempt to log the user in by username and password.
24
     *
25
     * @param  string $username
26
     * @param  mixed $password
27
     * @return array
28
     */
29
    public function attemptLogin($username, $password): array
30
    {
31
        $credentials = [
32
            $this->getUsernameField() => $username,
33
            'password' => $password,
34
        ];
35
36
        event(new Attempting($this->getGuard(), $credentials, false));
37
38
        $user = $this->getUserProvider()
39
            ->retrieveByCredentials($credentials);
40
41
        if (is_null($user)) {
42
            event(new Failed($this->getGuard(), $user, $credentials));
43
            throw InvalidCredentialsException::forUsername($username);
44
        }
45
46
        $response = $this->proxy('password', [
47
            'username' => $username,
48
            'password' => $password,
49
        ], $user);
50
51
        event(new Authenticated($this->getGuard(), $user));
52
        event(new Login($this->getGuard(), $user, false));
53
54
        return $response;
55
    }
56
57
    /**
58
     * Attempt refreshing the token.
59
     *
60
     * @param  string|null $refreshToken
61
     * @return array
62
     */
63
    public function attemptRefresh($refreshToken = null): array
64
    {
65
        return $this->proxy('refresh_token', [
66
            'refresh_token' => $refreshToken,
67
        ]);
68
    }
69
70
    /**
71
     * Attempt to log the user out.
72
     *
73
     * @return void
74
     */
75
    public function attemptLogout(): void
76
    {
77
        $user = Auth::user();
78
79
        $accessToken = $this->getAccessToken();
80
81
        DB::table('oauth_refresh_tokens')
82
            ->where('access_token_id', $accessToken->id)
83
            ->update([
84
                'revoked' => true,
85
            ]);
86
87
        if (! $accessToken->revoke()) {
88
            throw new HttpException(409, 'Could not revoke access token.');
89
        }
90
91
        event(new Logout($this->getGuard(), $user));
92
    }
93
94
    /**
95
     * Proxy request to passport.
96
     *
97
     * @param  string $grantType
98
     * @param  array  $data
99
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null $user
100
     * @return array
101
     */
102
    public function proxy($grantType, array $data = [], $user = null): array
103
    {
104
        $data = array_merge($data, $this->getClientCredentials(), [
105
            'grant_type' => $grantType,
106
        ]);
107
108
        $client = new HttpClient(['http_errors' => false]);
109
        $response = $client->post($this->config['oauth_token_url'], [
110
            'form_params' => $data,
111
        ]);
112
113
        if ($response->getStatusCode() !== Response::HTTP_OK) {
114
            event(new Failed($this->getGuard(), $user, $data));
115
            throw InvalidCredentialsException::withDefaultMessage();
116
        }
117
118
        $data = json_decode((string) $response->getBody(), true);
119
120
        return Arr::only($data, [
121
            'access_token',
122
            'expires_in',
123
            'refresh_token',
124
            'token_type',
125
        ]);
126
    }
127
128
    /**
129
     * Get access token.
130
     *
131
     * @return object
132
     */
133
    protected function getAccessToken()
134
    {
135
        return Auth::user()->token();
0 ignored issues
show
Bug introduced by
The method token() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of Illuminate\Contracts\Auth\Authenticatable such as Illuminate\Foundation\Auth\User. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
        return Auth::user()->/** @scrutinizer ignore-call */ token();
Loading history...
136
    }
137
138
    /**
139
     * Get the client credentials.
140
     *
141
     * @return array
142
     */
143
    protected function getClientCredentials(): array
144
    {
145
        $clientModel = $this->config['client_model'] ?? Passport::clientModel();
146
147
        $client = $clientModel::where('password_client', true)
148
            ->where('revoked', false)
149
            ->first();
150
151
        if (! $client) {
152
            throw InvalidClientCredentialsException::withDefaultMessage();
153
        }
154
155
        return [
156
            'client_id'     => $client->id,
157
            'client_secret' => $client->secret,
158
            'scope'         => '',
159
        ];
160
    }
161
}
162