Api::getToken()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 1
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @package API
5
 * @author Iurii Makukh <[email protected]>
6
 * @copyright Copyright (c) 2018, Iurii Makukh
7
 * @license https://www.gnu.org/licenses/gpl.html GNU/GPLv3
8
 */
9
10
namespace gplcart\modules\api\models;
11
12
use gplcart\core\helpers\Server;
13
use gplcart\core\Module;
14
use gplcart\modules\oauth\helpers\Jwt;
15
use InvalidArgumentException;
16
use UnexpectedValueException;
17
18
/**
19
 * Manages basic behaviors and data related to API module
20
 */
21
class Api
22
{
23
24
    /**
25
     * JWT helper class instance
26
     * @var \gplcart\modules\oauth\helpers\Jwt $jwt
27
     */
28
    protected $jwt;
29
30
    /**
31
     * User model class instance
32
     * @var \gplcart\modules\api\models\User $user
33
     */
34
    protected $user;
35
36
    /**
37
     * Server helper class instance
38
     * @var \gplcart\core\helpers\Server $server
39
     */
40
    protected $server;
41
42
    /**
43
     * Module class instance
44
     * @var \gplcart\core\Module $module
45
     */
46
    protected $module;
47
48
    /**
49
     * @param Module $module
50
     * @param Server $server
51
     * @param User $user
52
     * @param Jwt $jwt
53
     */
54
    public function __construct(Module $module, Server $server, User $user, Jwt $jwt)
55
    {
56
        $this->jwt = $jwt;
57
        $this->user = $user;
58
        $this->module = $module;
59
        $this->server = $server;
60
    }
61
62
    /**
63
     * Returns encoded JWT token
64
     * @param int $user_id
65
     * @return array
66
     */
67
    public function getToken($user_id)
68
    {
69
        $time = time();
70
        $lifetime = $this->getLifetime();
71
        $host = $this->server->httpHost();
72
73
        $data = array(
74
            'iss' => $host,
75
            'iat' => $time,
76
            'aud' => $host,
77
            'sub' => $user_id,
78
            'exp' => $time + $lifetime
79
        );
80
81
        return array(
82
            'token_type' => 'bearer',
83
            'expires_in' => $lifetime,
84
            'access_token' => $this->jwt->encode($data, $this->getSecret(), $this->getAlg())
85
        );
86
    }
87
88
    /**
89
     * Returns an array of user data from the token
90
     * @param string $token
91
     * @return array
92
     * @throws UnexpectedValueException
93
     * @throws InvalidArgumentException
94
     */
95
    public function getUserFromToken($token)
96
    {
97
        $payload = $this->jwt->decode($token, $this->getSecret());
98
99
        if (empty($payload->sub) || !is_numeric($payload->sub)) {
100
            throw new UnexpectedValueException('Payload "sub" key must contain a valid user ID');
101
        }
102
103
        $user = $this->user->get($payload->sub);
104
105
        if (empty($user['status'])) {
106
            throw new UnexpectedValueException('Invalid or disabled API user');
107
        }
108
109
        return $user;
110
    }
111
112
    /**
113
     * Returns the secret key from the module settings
114
     * @return string
115
     * @throws InvalidArgumentException
116
     */
117
    public function getSecret()
118
    {
119
        $value = $this->module->getSettings('api', 'secret');
120
121
        if (empty($value)) {
122
            throw new InvalidArgumentException('Empty "secret" key in the module settings');
123
        }
124
125
        return $value;
126
    }
127
128
    /**
129
     * Returns the hashing algorithm from the module settings
130
     * @return string
131
     * @throws InvalidArgumentException
132
     */
133
    public function getAlg()
134
    {
135
        $value = $this->module->getSettings('api', 'jwt_alg');
136
137
        if (empty($value)) {
138
            throw new InvalidArgumentException('Empty "jwt_alg" key in the module settings');
139
        }
140
141
        return $value;
142
    }
143
144
    /**
145
     * Returns the token lifetime
146
     * @return int
147
     */
148
    public function getLifetime()
149
    {
150
        return (int) $this->module->getSettings('api', 'jwt_lifetime');
151
    }
152
153
    /**
154
     * Whether API access is allowed
155
     * @return bool
156
     */
157
    public function getStatus()
158
    {
159
        return (bool) $this->module->getSettings('api', 'status');
160
    }
161
}
162