Token::attributes()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace yrc\models\redis;
4
5
use Base32\Base32;
6
use ncryptf\Token as NcryptfToken;
7
use yrc\redis\ActiveRecord;
8
use Yii;
9
10
/**
11
 * Abstract class for generating and storing tokens
12
 * @property integer $id
13
 * @property integer $user_id
14
 * @property string $access_token
15
 * @property string $refresh_token
16
 * @property string $ikm
17
 * @property string $secret_sign_key
18
 * @property integer $expires_at
19
 */
20
abstract class Token extends ActiveRecord
21
{
22
    /**
23
     * This is our default token lifespan
24
     * @const TOKEN_EXPIRATION_TIME
25
     */
26
    const TOKEN_EXPIRATION_TIME = '+15 minutes';
27
28
    /**
29
     * The refresh token class
30
     */
31
    const REFRESH_TOKEN_CLASS = '\app\models\RefreshToken';
32
33
    /**
34
     * @inheritdoc
35
     */
36
    public function attributes()
37
    {
38
        return [
39
            'id',
40
            'user_id',
41
            'access_token',
42
            'refresh_token',
43
            'ikm',
44
            'secret_sign_kp',
45
            'expires_at'
46
        ];
47
    }
48
49
    /**
50
     * @return sodium_crypto_sign_keypair
0 ignored issues
show
Bug introduced by
The type yrc\models\redis\sodium_crypto_sign_keypair was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
51
     */
52
    public function getSignKeyPair()
53
    {
54
        $secret = \base64_decode($this->secret_sign_kp);
0 ignored issues
show
Bug Best Practice introduced by
The property secret_sign_kp does not exist on yrc\models\redis\Token. Since you implemented __get, consider adding a @property annotation.
Loading history...
55
        $public = sodium_crypto_sign_publickey_from_secretkey($secret);
56
        return sodium_crypto_sign_keypair_from_secretkey_and_publickey($secret, $public);
0 ignored issues
show
Bug Best Practice introduced by
The expression return sodium_crypto_sig...ickey($secret, $public) returns the type string which is incompatible with the documented return type yrc\models\redis\sodium_crypto_sign_keypair.
Loading history...
57
    }
58
59
    /**
60
     * @return sodium_crypto_sign_publickey
0 ignored issues
show
Bug introduced by
The type yrc\models\redis\sodium_crypto_sign_publickey was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
61
     */
62
    public function getSignPublicKey()
63
    {
64
        return sodium_crypto_sign_publickey($this->getSignKeyPair());
0 ignored issues
show
Bug Best Practice introduced by
The expression return sodium_crypto_sig...this->getSignKeyPair()) returns the type string which is incompatible with the documented return type yrc\models\redis\sodium_crypto_sign_publickey.
Loading history...
65
    }
66
67
    /**
68
     * Generates a new auth and refresh token pair
69
     * @param int $userId
70
     * @return array
71
     */
72
    public static function generate($userId = null)
73
    {
74
        $model = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $model is dead and can be removed.
Loading history...
75
        $signKp = sodium_crypto_sign_keypair();
76
77
        $user = Yii::$app->user->identityClass::findOne(['id' => $userId]);
78
        if ($user === null) {
79
            throw new \yii\base\Exception('Invalid user');
80
        }
81
       
82
        $token = new static;
83
        $token->setAttributes([
84
            'user_id' => $user->id,
85
            'access_token' => \str_replace('=', '', Base32::encode(\random_bytes(32))),
86
            'refresh_token' => (static::REFRESH_TOKEN_CLASS)::create($user),
87
            'ikm' => \base64_encode(\random_bytes(32)),
88
            'secret_sign_kp' => \base64_encode(sodium_crypto_sign_secretkey($signKp)),
89
            'expires_at' => \strtotime(static::TOKEN_EXPIRATION_TIME)
90
        ], false);
91
92
        if ($token->save()) {
93
            return $token;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $token returns the type yrc\models\redis\Token which is incompatible with the documented return type array.
Loading history...
94
        }
95
            
96
        throw new \yii\base\Exception(Yii::t('yrc', 'Token failed to save'));
97
    }
98
99
    /**
100
     * Returns an ncryptf compatible token
101
     *
102
     * @return \ncryptf\Token
103
     */
104
    public function getNcryptfToken()
105
    {
106
        $attributes = $this->getAuthResponse();
107
        return new NcryptfToken(
108
            $attributes['access_token'],
109
            $attributes['refresh_token'],
110
            \base64_decode($attributes['ikm']),
111
            \base64_decode($attributes['signing']),
112
            $attributes['expires_at']
113
        );
114
    }
115
116
    /**
117
     * Helper method to get the auth response data
118
     * @return array
119
     */
120
    public function getAuthResponse()
121
    {
122
        $attributes = $this->getAttributes();
123
        unset($attributes['id']);
124
125
        $attributes['signing'] = $attributes['secret_sign_kp'];
126
        unset($attributes['secret_sign_kp']);
127
        return $attributes;
128
    }
129
}
130