Passed
Pull Request — master (#18)
by
unknown
02:58
created

LaravelSSOServer::checkBrokerUserAuthentication()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 0
1
<?php
2
3
namespace Zefy\LaravelSSO;
4
5
use Illuminate\Database\Eloquent\ModelNotFoundException;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Facades\Cache;
8
use Illuminate\Support\Facades\Session;
9
use Zefy\SimpleSSO\SSOServer;
10
use Zefy\LaravelSSO\Resources\UserResource;
11
12
class LaravelSSOServer extends SSOServer
13
{
14
    /**
15
     * Redirect to provided URL with query string.
16
     *
17
     * If $url is null, redirect to url which given in 'return_url'.
18
     *
19
     * @param string|null $url URL to be redirected.
20
     * @param array $parameters HTTP query string.
21
     * @param int $httpResponseCode HTTP response code for redirection.
22
     *
23
     * @return void
24
     */
25
    protected function redirect(?string $url = null, array $parameters = [], int $httpResponseCode = 307)
26
    {
27
        if (!$url) {
28
            $url = urldecode(request()->get('return_url', null));
29
        }
30
31
        $query = '';
32
        // Making URL query string if parameters given.
33
        if (!empty($parameters)) {
34
            $query = '?';
35
36
            if (parse_url($url, PHP_URL_QUERY)) {
37
                $query = '&';
38
            }
39
40
            $query .= http_build_query($parameters);
41
        }
42
43
        app()->abort($httpResponseCode, '', ['Location' => $url . $query]);
0 ignored issues
show
introduced by
The method abort() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

43
        app()->/** @scrutinizer ignore-call */ abort($httpResponseCode, '', ['Location' => $url . $query]);
Loading history...
44
    }
45
46
    /**
47
     * Returning json response for the broker.
48
     *
49
     * @param null|array $response Response array which will be encoded to json.
50
     * @param int $httpResponseCode HTTP response code.
51
     *
52
     * @return string
53
     */
54
    protected function returnJson(?array $response = null, int $httpResponseCode = 200)
55
    {
56
        return response()->json($response, $httpResponseCode);
57
    }
58
59
    /**
60
     * Authenticate using user credentials
61
     *
62
     * @param string $username
63
     * @param string $password
64
     *
65
     * @return bool
66
     */
67
    protected function authenticate(string $username, string $password)
68
    {
69
        if (!Auth::attempt(['email' => $username, 'password' => $password])) {
70
            return false;
71
        }
72
73
        // After authentication Laravel will change session id, but we need to keep
74
        // this the same because this session id can be already attached to other brokers.
75
        $sessionId = $this->getBrokerSessionId();
76
        $savedSessionId = $this->getBrokerSessionData($sessionId);
0 ignored issues
show
Bug introduced by
It seems like $sessionId can also be of type null; however, parameter $brokerSessionId of Zefy\LaravelSSO\LaravelS...:getBrokerSessionData() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

76
        $savedSessionId = $this->getBrokerSessionData(/** @scrutinizer ignore-type */ $sessionId);
Loading history...
77
        $this->startSession($savedSessionId);
0 ignored issues
show
Bug introduced by
It seems like $savedSessionId can also be of type null; however, parameter $sessionId of Zefy\LaravelSSO\LaravelSSOServer::startSession() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

77
        $this->startSession(/** @scrutinizer ignore-type */ $savedSessionId);
Loading history...
78
79
        return true;
80
    }
81
82
    /**
83
     * Get the secret key and other info of a broker
84
     *
85
     * @param string $brokerId
86
     *
87
     * @return null|array
88
     */
89
    protected function getBrokerInfo(string $brokerId)
90
    {
91
        try {
92
            $broker = config('laravel-sso.brokersModel')::where('name', $brokerId)->firstOrFail();
93
        } catch (ModelNotFoundException $e) {
94
            return null;
95
        }
96
97
        return $broker;
98
    }
99
100
    /**
101
     * Check for User Auth with Broker Application.
102
     *
103
     * @return boolean
104
     */
105
    protected function checkBrokerUserAuthentication()
106
    {
107
        $userInfo = $this->userInfo();
108
        $broker = $this->getBrokerDetail();
0 ignored issues
show
Bug introduced by
The method getBrokerDetail() does not exist on Zefy\LaravelSSO\LaravelSSOServer. Did you maybe mean getBrokerSessionData()? ( Ignorable by Annotation )

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

108
        /** @scrutinizer ignore-call */ 
109
        $broker = $this->getBrokerDetail();

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...
109
        if(!empty($userInfo->id) && !empty($broker)) {
0 ignored issues
show
Bug introduced by
The property id does not exist on string.
Loading history...
110
            $brokerUser = config('laravel-sso.brokersUserModel')::where('user_id', $userInfo->id)->where('broker_id', $broker->id)->first();
111
            if(empty($brokerUser)) {
112
                return false;
113
            }
114
        }
115
        return true;
116
    }
117
118
    /**
119
     * Get the information about a user
120
     *
121
     * @param string $username
122
     *
123
     * @return array|object|null
124
     */
125
    protected function getUserInfo(string $username)
126
    {
127
        try {
128
            $user = config('laravel-sso.usersModel')::where('email', $username)->firstOrFail();
129
        } catch (ModelNotFoundException $e) {
130
            return null;
131
        }
132
133
        return $user;
134
    }
135
136
    /**
137
     * Returning user info for broker. Should return json or something like that.
138
     *
139
     * @param array|object $user Can be user object or array.
140
     *
141
     * @return array|object|UserResource
142
     */
143
    protected function returnUserInfo($user)
144
    {
145
        return new UserResource($user);
146
    }
147
148
    /**
149
     * Return session id sent from broker.
150
     *
151
     * @return null|string
152
     */
153
    protected function getBrokerSessionId()
154
    {
155
        $authorization = request()->header('Authorization', null);
156
        if ($authorization &&  strpos($authorization, 'Bearer') === 0) {
0 ignored issues
show
Bug introduced by
It seems like $authorization can also be of type array; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

156
        if ($authorization &&  strpos(/** @scrutinizer ignore-type */ $authorization, 'Bearer') === 0) {
Loading history...
157
            return substr($authorization, 7);
0 ignored issues
show
Bug introduced by
It seems like $authorization can also be of type array; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

157
            return substr(/** @scrutinizer ignore-type */ $authorization, 7);
Loading history...
158
        }
159
160
        return null;
161
    }
162
163
    /**
164
     * Start new session when user visits server.
165
     *
166
     * @return void
167
     */
168
    protected function startUserSession()
169
    {
170
        // Session must be started by middleware.
171
    }
172
173
    /**
174
     * Set session data
175
     *
176
     * @param string $key
177
     * @param null|string $value
178
     *
179
     * @return void
180
     */
181
    protected function setSessionData(string $key, ?string $value = null)
182
    {
183
        if (!$value) {
184
            Session::forget($key);
185
            return;
186
        }
187
188
        Session::put($key, $value);
189
    }
190
191
    /**
192
     * Get data saved in session.
193
     *
194
     * @param string $key
195
     *
196
     * @return string
197
     */
198
    protected function getSessionData(string $key)
199
    {
200
        if ($key === 'id') {
201
            return Session::getId();
202
        }
203
204
        return Session::get($key, null);
205
    }
206
207
    /**
208
     * Start new session with specific session id.
209
     *
210
     * @param $sessionId
211
     *
212
     * @return void
213
     */
214
    protected function startSession(string $sessionId)
215
    {
216
        Session::setId($sessionId);
217
        Session::start();
218
    }
219
220
    /**
221
     * Save broker session data to cache.
222
     *
223
     * @param string $brokerSessionId
224
     * @param string $sessionData
225
     *
226
     * @return void
227
     */
228
    protected function saveBrokerSessionData(string $brokerSessionId, string $sessionData)
229
    {
230
        Cache::put('broker_session:' . $brokerSessionId, $sessionData, now()->addHour());
231
    }
232
233
    /**
234
     * Get broker session data from cache.
235
     *
236
     * @param string $brokerSessionId
237
     *
238
     * @return null|string
239
     */
240
    protected function getBrokerSessionData(string $brokerSessionId)
241
    {
242
        return Cache::get('broker_session:' . $brokerSessionId);
243
    }
244
}
245