Completed
Push — master ( 580028...d7e9e8 )
by Charles
02:19
created

TokenKeyPair::generate()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 24
rs 8.9713
cc 3
eloc 16
nc 4
nop 1
1
<?php
2
3
namespace yrc\api\models;
4
5
use Sodium;
6
use Yii;
7
8
final class TokenKeyPair extends \yrc\redis\ActiveRecord
9
{
10
    /**
11
     * The default token type to create
12
     * @const DEFAULT_TYPE
13
     */
14
    const DEFAULT_TYPE = 1;
15
16
    /**
17
     * One time token types
18
     * @const DEFAULT_TYPE
19
     */
20
    const OTK_TYPE = 2;
21
22
    /**
23
     * The default expiration time for crypted tokens
24
     * @const DEFAULT_EXPIRATION_TIME
25
     */
26
    const DEFAULT_EXPIRATION_TIME = '+15 minutes';
27
28
    /**
29
     * One time tokens have an expiration time of 5 minutes. On consumption are destroyed
30
     * @const OKT_EXPIRATION_TIME
31
     */
32
    const OTK_EXPIRATION_TIME = '+5 minutes';
33
34
    /**
35
     * @inheritdoc
36
     */
37
    public function attributes()
38
    {
39
        return [
40
            'id',
41
            'secret_box_kp',
42
            'secret_sign_kp',
43
            'type',
44
            'hash',
45
            'expires_at'
46
        ];
47
    }
48
49
    /**
50
     * @return \Sodium\crypto_box_publickey
51
     */
52
    public function getBoxPublicKey()
53
    {
54
        return \Sodium\crypto_box_publickey($this->getBoxKeyPair());
55
    }
56
57
    /**
58
     * @return \Sodium\crypto_sign_publickey
59
     */
60
    public function getSignPublicKey()
61
    {
62
        return \Sodium\crypto_sign_publickey($this->getSignKeyPair());
63
    }
64
65
    /**
66
     * @return \Sodium\crypto_box_keypair
67
     */
68
    public function getBoxKeyPair()
69
    {
70
        $secret = \base64_decode($this->secret_box_kp);
71
        $public = \Sodium\crypto_box_publickey_from_secretkey($secret);
72
        return \Sodium\crypto_box_keypair_from_secretkey_and_publickey($secret, $public);
73
    }
74
    
75
    /**
76
     * @return \Sodium\crypto_sign_keypair
77
     */
78
    public function getSignKeyPair()
79
    {
80
        $secret = \base64_decode($this->secret_sign_kp);
81
        $public = \Sodium\crypto_sign_publickey_from_secretkey($secret);
82
        return \Sodium\crypto_sign_keypair_from_secretkey_and_publickey($secret, $public);
83
    }
84
85
    /**
86
     * Generates a new crypt token
87
     * @param int $type
88
     * @return $array
0 ignored issues
show
Documentation introduced by
The doc-type $array could not be parsed: Unknown type name "$array" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
89
     */
90
    public static function generate($type = TokenKeyPair::DEFAULT_TYPE)
91
    {
92
        if ($type === self::OTK_TYPE) {
93
            $expires_at = \strtotime(static::OTK_EXPIRATION_TIME);
94
        } else {
95
            $expires_at = \strtotime(static::DEFAULT_EXPIRATION_TIME);
96
        }
97
98
        $boxKp = \Sodium\crypto_box_keypair();
99
        $signKp = \Sodium\crypto_sign_keypair();
100
101
        $token = new static;
102
        $token->type = $type;
103
        $token->secret_box_kp = \base64_encode(\Sodium\crypto_box_secretkey($boxKp));
104
        $token->secret_sign_kp = \base64_encode(\Sodium\crypto_sign_secretkey($signKp));
105
        $token->expires_at = $expires_at;
106
        $token->hash = \hash('sha256', uniqid('__TokenKeyPairHash', true));
107
108
        if ($token->save()) {
109
            return $token;
110
        }
111
112
        throw new \yii\base\Exception(Yii::t('yrc', 'Failed to generate secure tokens'));
113
    }
114
}