Issues (199)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/services/redis/JtiService.php (15 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * JtiService.php
4
 *
5
 * PHP version 5.6+
6
 *
7
 * @author Philippe Gaultier <[email protected]>
8
 * @copyright 2010-2017 Philippe Gaultier
9
 * @license http://www.sweelix.net/license license
10
 * @version 1.2.0
11
 * @link http://www.sweelix.net
12
 * @package sweelix\oauth2\server\services\redis
13
 */
14
15
namespace sweelix\oauth2\server\services\redis;
16
17
use sweelix\oauth2\server\exceptions\DuplicateIndexException;
18
use sweelix\oauth2\server\exceptions\DuplicateKeyException;
19
use sweelix\oauth2\server\interfaces\JtiModelInterface;
20
use sweelix\oauth2\server\interfaces\JtiServiceInterface;
21
use yii\db\Exception as DatabaseException;
22
use Yii;
23
24
/**
25
 * This is the jti service for redis
26
 *  database structure
27
 *    * oauth2:jti:<jid> : hash (Jti)
28
 *
29
 * @author Philippe Gaultier <[email protected]>
30
 * @copyright 2010-2017 Philippe Gaultier
31
 * @license http://www.sweelix.net/license license
32
 * @version 1.2.0
33
 * @link http://www.sweelix.net
34
 * @package sweelix\oauth2\server\services\redis
35
 * @since 1.0.0
36
 */
37
class JtiService extends BaseService implements JtiServiceInterface
38
{
39
    /**
40
     * @var string subject namespace (collection for jtis)
41
     */
42
    public $subjectNamespace = '';
43
44
    /**
45
     * @var string client namespace (collection for jtis)
46 4
     */
47
    public $clientNamespace = '';
48 4
49
    /**
50
     * @param string $jid jti ID
51
     * @return string access token Key
52
     * @since 1.0.0
53
     */
54 4
    public function getJtiKey($jid)
55
    {
56 4
        return $this->namespace . ':' . $jid;
57 4
    }
58 4
59 1
    /**
60
     * @param string $sid subject ID
61 4
     * @return string user jtis collection Key
62
     */
63
    public function getSubjectJtisKey($sid)
64
    {
65
        return $this->subjectNamespace . ':' . $sid . ':jtis';
66
    }
67
68
    /**
69
     * @param string $cid client ID
70
     * @return string client jtis collection Key
71
     */
72
    public function getClientJtisKey($cid)
73
    {
74 4
        return $this->clientNamespace . ':' . $cid . ':jtis';
75
    }
76 4
77 4
    /**
78
     * @return string key of all jtis list
79
     */
80 4
    public function getJtiListKey()
81
    {
82 4
        return $this->namespace . ':keys';
83 4
    }
84 2
85
    /**
86
     * @return string key of all subjects list
87 4
     */
88 4
    public function getSubjectListKey()
89 4
    {
90 4
        return $this->subjectNamespace . ':keys';
91
    }
92 4
93 4
    /**
94 4
     * @inheritdoc
95 4
     */
96 4
    public function save(JtiModelInterface $jti, $attributes)
97
    {
98 4
        if ($jti->getIsNewRecord()) {
99 4
            $result = $this->insert($jti, $attributes);
100
        } else {
101 4
            $result = $this->update($jti, $attributes);
102 4
        }
103 4
        return $result;
104
    }
105
106
    /**
107
     * Save Jti
108
     * @param JtiModelInterface $jti
109
     * @param null|array $attributes attributes to save
110 4
     * @return bool
111 4
     * @throws DatabaseException
112 4
     * @throws DuplicateIndexException
113 4
     * @throws DuplicateKeyException
114 4
     * @since 1.0.0
115 4
     */
116
    protected function insert(JtiModelInterface $jti, $attributes)
117
    {
118
        $result = false;
119
        if (!$jti->beforeSave(true)) {
120
            return $result;
121
        }
122
        $jtiId = $jti->getKey();
123
        $jtiKey = $this->getJtiKey($jtiId);
124
        if (empty($jti->subject) === false) {
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
125
            $subjectJtisKey = $this->getSubjectJtisKey($jti->subject);
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
126
        } else {
127
            $subjectJtisKey = null;
128 1
        }
129
        $clientJtisKey = $this->getClientJtisKey($jti->clientId);
0 ignored issues
show
Accessing clientId on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
130 1
        $jtiListKey = $this->getJtiListKey();
131
        $subjectListKey = $this->getSubjectListKey();
132
133
        //check if record exists
134 1
        $entityStatus = (int)$this->db->executeCommand('EXISTS', [$jtiKey]);
135 1
        if ($entityStatus === 1) {
136 1
            throw new DuplicateKeyException('Duplicate key "' . $jtiKey . '"');
137 1
        }
138
139
        $values = $jti->getDirtyAttributes($attributes);
0 ignored issues
show
It seems like $attributes defined by parameter $attributes on line 116 can also be of type array; however, sweelix\oauth2\server\in...e::getDirtyAttributes() does only seem to accept array<integer,string>|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
140 1
        $redisParameters = [$jtiKey];
141 1
        $this->setAttributesDefinitions($jti->attributesDefinition());
142 1
        $expire = null;
143 1
        foreach ($values as $key => $value) {
144 1
            if (($key === 'expires') && ($value > 0)) {
145
                $expire = $value;
146 1
            }
147
            if ($value !== null) {
148 1
                $redisParameters[] = $key;
149
                $redisParameters[] = $this->convertToDatabase($key, $value);
150 1
            }
151 1
        }
152 1
        //TODO: use EXEC/MULTI to avoid errors
153
        $transaction = $this->db->executeCommand('MULTI');
154 1
        if ($transaction === true) {
155 1
            try {
156
                $this->db->executeCommand('HMSET', $redisParameters);
157 1
                if ($expire !== null) {
158 1
                    $this->db->executeCommand('EXPIREAT', [$jtiKey, $expire]);
159 1
                }
160 1
                if ($subjectJtisKey !== null) {
161
                    $this->db->executeCommand('ZADD', [$subjectJtisKey, $expire === false ? -1 : $expire, $jtiId]);
162 1
                }
163
                $this->db->executeCommand('ZADD', [$clientJtisKey, $expire === false ? -1 : $expire, $jtiId]);
164
                $this->db->executeCommand('ZADD', [$jtiListKey, $expire === false ? -1 : $expire, $jtiId]);
165 1
                $this->db->executeCommand('SADD', [$subjectListKey, $jti->subject]);
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
166 1
                $this->db->executeCommand('EXEC');
167
            } catch (DatabaseException $e) {
168 1
                // @codeCoverageIgnoreStart
169 1
                // we have a REDIS exception, we should not discard
170
                Yii::debug('Error while inserting entity', __METHOD__);
171
                throw $e;
172 1
                // @codeCoverageIgnoreEnd
173 1
            }
174 1
        }
175
        $changedAttributes = array_fill_keys(array_keys($values), null);
176 1
        $jti->setOldAttributes($values);
177 1
        $jti->afterSave(true, $changedAttributes);
178
        $result = true;
179
        return $result;
180
    }
181
182
183
    /**
184
     * Update Jti
185 1
     * @param JtiModelInterface $jti
186 1
     * @param null|array $attributes attributes to save
187 1
     * @return bool
188 1
     * @throws DatabaseException
189 1
     * @throws DuplicateIndexException
190 1
     * @throws DuplicateKeyException
191 1
     */
192 1
    protected function update(JtiModelInterface $jti, $attributes)
193
    {
194
        if (!$jti->beforeSave(false)) {
195
            return false;
196
        }
197
198 3
        $values = $jti->getDirtyAttributes($attributes);
0 ignored issues
show
It seems like $attributes defined by parameter $attributes on line 192 can also be of type array; however, sweelix\oauth2\server\in...e::getDirtyAttributes() does only seem to accept array<integer,string>|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
199
        $modelKey = $jti->key();
200 3
        $jtiId = isset($values[$modelKey]) ? $values[$modelKey] : $jti->getKey();
201 3
        $jtiKey = $this->getJtiKey($jtiId);
202 3
        $jtiListKey = $this->getJtiListKey();
203 3
        $subjectListKey = $this->getSubjectListKey();
204 3
205 3
        if (empty($jti->subject) === false) {
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
206
            $subjectJtisKey = $this->getSubjectJtisKey($jti->subject);
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
207 3
        } else {
208 3
            $subjectJtisKey = null;
209 3
        }
210 3
        $clientJtisKey = $this->getClientJtisKey($jti->clientId);
0 ignored issues
show
Accessing clientId on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
211 3
212 3
        if (isset($values[$modelKey]) === true) {
213 3
            $newJtiKey = $this->getJtiKey($values[$modelKey]);
214 3
            $entityStatus = (int)$this->db->executeCommand('EXISTS', [$newJtiKey]);
215
            if ($entityStatus === 1) {
216
                throw new DuplicateKeyException('Duplicate key "' . $newJtiKey . '"');
217
            }
218
        }
219
220
        $this->db->executeCommand('MULTI');
221 3
        try {
222 3
            $reAddKeyInList = false;
223 3
            if (array_key_exists($modelKey, $values) === true) {
224 3
                $oldId = $jti->getOldKey();
225 3
                $oldJtiKey = $this->getJtiKey($oldId);
226 3
227 3
                $this->db->executeCommand('RENAMENX', [$oldJtiKey, $jtiKey]);
228
                if ($subjectJtisKey !== null) {
229
                    $this->db->executeCommand('ZREM', [$subjectJtisKey, $oldJtiKey]);
230
                }
231
                $this->db->executeCommand('ZREM', [$clientJtisKey, $oldJtiKey]);
232
                $this->db->executeCommand('ZREM', [$jtiListKey, $oldJtiKey]);
233 1
                $reAddKeyInList = true;
234
            }
235 1
236 1
            $redisUpdateParameters = [$jtiKey];
237 1
            $redisDeleteParameters = [$jtiKey];
238 1
            $this->setAttributesDefinitions($jti->attributesDefinition());
239 1
            $expire = $jti->expires;
0 ignored issues
show
Accessing expires on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
240
            foreach ($values as $key => $value) {
241 1
                if ($value === null) {
242
                    if ($key === 'expires') {
243 1
                        $expire = false;
244 1
                    }
245 1
                    $redisDeleteParameters[] = $key;
246 1
                } else {
247 1
                    if (($key === 'expires') && ($value > 0)) {
248 1
                        $expire = $value;
249
                    }
250
                    $redisUpdateParameters[] = $key;
251
                    $redisUpdateParameters[] = $this->convertToDatabase($key, $value);
252
                }
253
            }
254
            if (count($redisDeleteParameters) > 1) {
255
                $this->db->executeCommand('HDEL', $redisDeleteParameters);
256
            }
257
            if (count($redisUpdateParameters) > 1) {
258
                $this->db->executeCommand('HMSET', $redisUpdateParameters);
259
            }
260
            if ($expire === false) {
261
                $this->db->executeCommand('PERSIST', [$jtiKey]);
262
            } elseif ($expire > 0) {
263
                $this->db->executeCommand('EXPIREAT', [$jtiKey, $expire]);
264
            }
265
266
            if ($reAddKeyInList === true) {
267
                if ($subjectJtisKey !== null) {
268
                    $this->db->executeCommand('ZADD', [$subjectJtisKey, $expire === false ? -1 : $expire, $jtiKey]);
269
                }
270
                $this->db->executeCommand('ZADD', [$clientJtisKey, $expire === false ? -1 : $expire, $jtiKey]);
271
                $this->db->executeCommand('ZADD', [$jtiListKey, $expire === false ? -1 : $expire, $jtiKey]);
272
            }
273
            $this->db->executeCommand('SADD', [$subjectListKey, $jti->subject]);
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
274
275
            $this->db->executeCommand('EXEC');
276
        } catch (DatabaseException $e) {
277
            // @codeCoverageIgnoreStart
278
            // we have a REDIS exception, we should not discard
279
            Yii::debug('Error while updating entity', __METHOD__);
280
            throw $e;
281
            // @codeCoverageIgnoreEnd
282
        }
283
284
        $changedAttributes = [];
285
        foreach ($values as $name => $value) {
286
            $oldAttributes = $jti->getOldAttributes();
287
            $changedAttributes[$name] = isset($oldAttributes[$name]) ? $oldAttributes[$name] : null;
288
            $jti->setOldAttribute($name, $value);
289
        }
290
        $jti->afterSave(false, $changedAttributes);
291
        return true;
292
    }
293
294
    /**
295
     * @inheritdoc
296
     */
297
    public function findOne($key)
298
    {
299
        $record = null;
300
        $jtiKey = $this->getJtiKey($key);
301
        $jtiExists = (bool)$this->db->executeCommand('EXISTS', [$jtiKey]);
302
        if ($jtiExists === true) {
303
            $jtiData = $this->db->executeCommand('HGETALL', [$jtiKey]);
304
            $record = Yii::createObject('sweelix\oauth2\server\interfaces\JtiModelInterface');
305
            /** @var JtiModelInterface $record */
306
            $properties = $record->attributesDefinition();
307
            $this->setAttributesDefinitions($properties);
308
            $attributes = [];
309
            for ($i = 0; $i < count($jtiData); $i += 2) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
310
                if (isset($properties[$jtiData[$i]]) === true) {
311
                    $jtiData[$i + 1] = $this->convertToModel($jtiData[$i], $jtiData[($i + 1)]);
312
                    $record->setAttribute($jtiData[$i], $jtiData[$i + 1]);
313
                    $attributes[$jtiData[$i]] = $jtiData[$i + 1];
314
                    // @codeCoverageIgnoreStart
315
                } elseif ($record->canSetProperty($jtiData[$i])) {
316
                    // TODO: find a way to test attribute population
317
                    $record->{$jtiData[$i]} = $jtiData[$i + 1];
318
                }
319
                // @codeCoverageIgnoreEnd
320
            }
321
            if (empty($attributes) === false) {
322
                $record->setOldAttributes($attributes);
323
            }
324
            $record->afterFind();
325
        }
326
        return $record;
327
    }
328
329
    /**
330
     * @inheritdoc
331
     */
332
    public function findAllBySubject($subject)
333
    {
334
        $subjectJtisKey = $this->getSubjectJtisKey($subject);
335
        $subjectJtis = $this->db->executeCommand('ZRANGE', [$subjectJtisKey, 0, -1]);
336
        $jtis = [];
337
        if ((is_array($subjectJtis) === true) && (count($subjectJtis) > 0)) {
338
            foreach ($subjectJtis as $subjectJtiId) {
339
                $jtis[] = $this->findOne($subjectJtiId);
340
            }
341
        }
342
        return $jtis;
343
    }
344
345
    /**
346
     * @inheritdoc
347
     */
348
    public function deleteAllBySubject($subject)
349
    {
350
        $subjectJtisKey = $this->getSubjectJtisKey($subject);
351
        $subjectJtis = $this->db->executeCommand('ZRANGE', [$subjectJtisKey, 0, -1]);
352
        foreach ($subjectJtis as $subjectJtiId) {
353
            $subjectJti = $this->findOne($subjectJtiId);
354
            if ($subjectJti instanceof JtiModelInterface) {
355
                $this->delete($subjectJti);
356
            }
357
        }
358
        return true;
359
    }
360
361
    /**
362
     * @inheritdoc
363
     */
364
    public function findAllByClientId($clientId)
365
    {
366
        $clientJtisKey = $this->getClientJtisKey($clientId);
367
        $clientJtis = $this->db->executeCommand('ZRANGE', [$clientJtisKey, 0, -1]);
368
        $jtis = [];
369
        if ((is_array($clientJtis) === true) && (count($clientJtis) > 0)) {
370
            foreach ($clientJtis as $clientJtiId) {
371
                $jtis[] = $this->findOne($clientJtiId);
372
            }
373
        }
374
        return $jtis;
375
    }
376
377
    /**
378
     * @inheritdoc
379
     */
380
    public function deleteAllByClientId($clientId)
381
    {
382
        $clientJtisKey = $this->getClientJtisKey($clientId);
383
        $clientJtis = $this->db->executeCommand('ZRANGE', [$clientJtisKey, 0, -1]);
384
        foreach ($clientJtis as $clientJtiId) {
385
            $clientJti = $this->findOne($clientJtiId);
386
            if ($clientJti instanceof JtiModelInterface) {
387
                $this->delete($clientJti);
388
            }
389
        }
390
        return true;
391
    }
392
393
    /**
394
     * @inheritdoc
395
     */
396
    public function delete(JtiModelInterface $jti)
397
    {
398
        $result = false;
399
        if ($jti->beforeDelete()) {
400
            if (empty($jti->subject) === false) {
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
401
                $subjectJtisKey = $this->getSubjectJtisKey($jti->subject);
0 ignored issues
show
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
402
            } else {
403
                $subjectJtisKey = null;
404
            }
405
            $clientJtisKey = $this->getClientJtisKey($jti->clientId);
0 ignored issues
show
Accessing clientId on the interface sweelix\oauth2\server\interfaces\JtiModelInterface 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...
406
            $jtiListKey = $this->getJtiListKey();
407
408
            $this->db->executeCommand('MULTI');
409
            $id = $jti->getOldKey();
410
            $jtiKey = $this->getJtiKey($id);
411
412
            $this->db->executeCommand('DEL', [$jtiKey]);
413
            if ($subjectJtisKey !== null) {
414
                $this->db->executeCommand('ZREM', [$subjectJtisKey, $id]);
415
            }
416
            $this->db->executeCommand('ZREM', [$clientJtisKey, $id]);
417
            $this->db->executeCommand('ZREM', [$jtiListKey, $id]);
418
            //TODO: check results to return correct information
419
            $this->db->executeCommand('EXEC');
420
            $jti->setIsNewRecord(true);
421
            $jti->afterDelete();
422
            $result = true;
423
        }
424
        return $result;
425
    }
426
427
    /**
428
     * @inheritdoc
429
     */
430
    public function deleteAllExpired()
431
    {
432
        $date = time();
433
        $jtiListKey = $this->getJtiListKey();
434
        $this->db->executeCommand('ZREMRANGEBYSCORE', [$jtiListKey, -1, $date]);
435
436
        $client = Yii::createObject('sweelix\oauth2\server\interfaces\ClientModelInterface');
437
        $clientClass = get_class($client);
438
        /* @var \sweelix\oauth2\server\interfaces\ClientModelInterface[] $clientList */
439
        $clientList = $clientClass::findAll();
440
        foreach ($clientList as $client) {
441
            $clientJtisKey = $this->getClientJtisKey($client->getKey());
442
            $this->db->executeCommand('ZREMRANGEBYSCORE', [$clientJtisKey, -1, $date]);
443
        }
444
445
        $subjectListKey = $this->getSubjectListKey();
446
        $subjects = $this->db->executeCommand('SMEMBERS', [$subjectListKey]);
447
        foreach ($subjects as $subject) {
448
            $subjectJtisKey = $this->getSubjectJtisKey($subject);
449
            $this->db->executeCommand('ZREMRANGEBYSCORE', [$subjectJtisKey, '-inf', $date]);
450
        }
451
        return true;
452
    }
453
454
    /**
455
     * @inheritdoc
456
     */
457
    public function findAll()
458
    {
459
        $jtiListKey = $this->getJtiListKey();
460
        $jtiList = $this->db->executeCommand('ZRANGE', [$jtiListKey, 0, -1]);
461
        $jtis = [];
462
        if ((is_array($jtiList) === true) && (count($jtiList) > 0)) {
463
            foreach ($jtiList as $jtiId) {
464
                $jtis[] = $this->findOne($jtiId);
465
            }
466
        }
467
        return $jtis;
468
    }
469
}
470