Profile   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 66
c 0
b 0
f 0
dl 0
loc 241
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A updateProfile() 0 7 1
A updateUserPreferences() 0 6 1
A getUserPreferences() 0 6 1
A getProfileGrants() 0 12 2
A getProfileLogins() 0 7 1
A getProfileLogin() 0 7 1
A tfaEnable() 0 7 1
A __construct() 0 9 1
A tfaDisable() 0 3 1
A tfaConfirm() 0 11 1
A __get() 0 9 1
1
<?php
2
3
// ---------------------------------------------------------------------
4
//
5
//  Copyright (C) 2018-2024 Artem Rodygin
6
//
7
//  You should have received a copy of the MIT License along with
8
//  this file. If not, see <https://opensource.org/licenses/MIT>.
9
//
10
// ---------------------------------------------------------------------
11
12
namespace Linode\Profile;
13
14
use Linode\Account\GrantsResponse;
15
use Linode\Account\Login;
16
use Linode\Entity;
17
use Linode\Exception\LinodeException;
18
use Linode\LinodeClient;
19
use Linode\Profile\Repository\AuthorizedAppRepository;
20
use Linode\Profile\Repository\PersonalAccessTokenRepository;
21
use Linode\Profile\Repository\SSHKeyRepository;
22
use Linode\Profile\Repository\TrustedDeviceRepository;
23
24
/**
25
 * A Profile represents your User in our system. This is where you can change
26
 * information about your User. This information is available to any OAuth Client
27
 * regardless of requested scopes, and can be used to populate User information in
28
 * third-party applications.
29
 *
30
 * @property int                                    $uid                   Your unique ID in our system. This value will never change, and can safely be used
31
 *                                                                         to identify your User.
32
 * @property string                                 $username              Your username, used for logging in to our system.
33
 * @property string                                 $email                 Your email address. This address will be used for communication with Linode as
34
 *                                                                         necessary.
35
 * @property bool                                   $restricted            If true, your User has restrictions on what can be accessed on your Account. To
36
 *                                                                         get details on what entities/actions you can access/perform, see /profile/grants.
37
 * @property bool                                   $two_factor_auth       If true, logins from untrusted computers will require Two Factor Authentication.
38
 *                                                                         See /profile/tfa-enable to enable Two Factor Authentication.
39
 * @property string                                 $timezone              The timezone you prefer to see times in. This is not used by the API directly. It
40
 *                                                                         is provided for the benefit of clients such as the Linode Cloud Manager and other
41
 *                                                                         clients built on the API. All times returned by the API are in UTC.
42
 * @property bool                                   $email_notifications   If true, you will receive email notifications about account activity. If false,
43
 *                                                                         you may still receive business-critical communications through email.
44
 * @property bool                                   $ip_whitelist_enabled  If true, logins for your User will only be allowed from whitelisted IPs. This
45
 *                                                                         setting is currently deprecated, and cannot be enabled.
46
 *                                                                         If you disable this setting, you will not be able to re-enable it.
47
 * @property string                                 $lish_auth_method      The authentication methods that are allowed when connecting to the Linode Shell
48
 *                                                                         (Lish).
49
 *                                                                         * `keys_only` is the most secure if you intend to use Lish.
50
 *                                                                         * `disabled` is recommended if you do not intend to use Lish at all.
51
 *                                                                         * If this account's Cloud Manager authentication type is set to a Third-Party
52
 *                                                                         Authentication method, `password_keys` cannot be used as your Lish authentication
53
 *                                                                         method. To view this account's Cloud Manager `authentication_type` field, send a
54
 *                                                                         request to the View Profile endpoint.
55
 * @property null|string[]                          $authorized_keys       The list of SSH Keys authorized to use Lish for your User. This value is ignored
56
 *                                                                         if `lish_auth_method` is "disabled."
57
 * @property Referrals                              $referrals             Information about your status in our referral program.
58
 *                                                                         This information becomes accessible after this Profile's Account has established
59
 *                                                                         at least $25.00 USD of total payments.
60
 * @property null|string                            $verified_phone_number The phone number verified for this Profile with the **Phone Number Verify** (POST
61
 *                                                                         /profile/phone-number/verify) command.
62
 *                                                                         `null` if this Profile has no verified phone number.
63
 * @property string                                 $authentication_type   This account's Cloud Manager authentication type. Authentication types are chosen
64
 *                                                                         through
65
 *                                                                         Cloud Manager and authorized when logging into your account. These authentication
66
 *                                                                         types are either
67
 *                                                                         the user's password (in conjunction with their username), or the name of their
68
 *                                                                         indentity provider such as GitHub. For example, if a user:
69
 *                                                                         - Has never used Third-Party Authentication, their authentication type will be
70
 *                                                                         `password`.
71
 *                                                                         - Is using Third-Party Authentication, their authentication type will be the name
72
 *                                                                         of their Identity Provider (eg. `github`).
73
 *                                                                         - Has used Third-Party Authentication and has since revoked it, their
74
 *                                                                         authentication type will be `password`.
75
 *                                                                         **Note:** This functionality may not yet be available in Cloud Manager.
76
 *                                                                         See the Cloud Manager Changelog for the latest updates.
77
 * @property AuthorizedAppRepositoryInterface       $authorizedApps        List of OAuth apps that you've given access to your Account, and includes the
78
 *                                                                         level of access granted.
79
 * @property PersonalAccessTokenRepositoryInterface $personalAccessTokens  List of Personal Access Tokens currently active for your User.
80
 * @property SSHKeyRepositoryInterface              $sshKeys               List of SSH Keys you've added to your Profile.
81
 * @property TrustedDeviceRepositoryInterface       $trustedDevices        List of active TrustedDevices for your User. Browsers with an active Remember Me
82
 *                                                                         Session are logged into your account until the session expires or is revoked.
83
 *
84
 * @codeCoverageIgnore This class was autogenerated.
85
 */
86
class Profile extends Entity
87
{
88
    // Available fields.
89
    public const FIELD_UID                   = 'uid';
90
    public const FIELD_USERNAME              = 'username';
91
    public const FIELD_EMAIL                 = 'email';
92
    public const FIELD_RESTRICTED            = 'restricted';
93
    public const FIELD_TWO_FACTOR_AUTH       = 'two_factor_auth';
94
    public const FIELD_TIMEZONE              = 'timezone';
95
    public const FIELD_EMAIL_NOTIFICATIONS   = 'email_notifications';
96
    public const FIELD_IP_WHITELIST_ENABLED  = 'ip_whitelist_enabled';
97
    public const FIELD_LISH_AUTH_METHOD      = 'lish_auth_method';
98
    public const FIELD_AUTHORIZED_KEYS       = 'authorized_keys';
99
    public const FIELD_REFERRALS             = 'referrals';
100
    public const FIELD_VERIFIED_PHONE_NUMBER = 'verified_phone_number';
101
    public const FIELD_AUTHENTICATION_TYPE   = 'authentication_type';
102
103
    // `FIELD_LISH_AUTH_METHOD` values.
104
    public const LISH_AUTH_METHOD_PASSWORD_KEYS = 'password_keys';
105
    public const LISH_AUTH_METHOD_KEYS_ONLY     = 'keys_only';
106
    public const LISH_AUTH_METHOD_DISABLED      = 'disabled';
107
108
    // `FIELD_AUTHENTICATION_TYPE` values.
109
    public const AUTHENTICATION_TYPE_PASSWORD = 'password';
110
    public const AUTHENTICATION_TYPE_GITHUB   = 'github';
111
112
    /**
113
     * Returns information about the current User. This can be used to see who is acting
114
     * in applications where more than one token is managed. For example, in third-party
115
     * OAuth applications.
116
     *
117
     * This endpoint is always accessible, no matter what OAuth scopes the acting token
118
     * has.
119
     *
120
     * @throws LinodeException
121
     */
122
    public function __construct(LinodeClient $client)
123
    {
124
        parent::__construct($client);
125
126
        $response = $this->client->get('/profile');
127
        $contents = $response->getBody()->getContents();
128
        $json     = json_decode($contents, true);
129
130
        $this->data = $json;
131
    }
132
133
    /**
134
     * @codeCoverageIgnore This method was autogenerated.
135
     */
136
    public function __get(string $name): mixed
137
    {
138
        return match ($name) {
139
            self::FIELD_REFERRALS  => new Referrals($this->client, $this->data[$name]),
140
            'authorizedApps'       => new AuthorizedAppRepository($this->client),
141
            'personalAccessTokens' => new PersonalAccessTokenRepository($this->client),
142
            'sshKeys'              => new SSHKeyRepository($this->client),
143
            'trustedDevices'       => new TrustedDeviceRepository($this->client),
144
            default                => parent::__get($name),
145
        };
146
    }
147
148
    /**
149
     * Update information in your Profile. This endpoint requires the
150
     * "account:read_write" OAuth Scope.
151
     *
152
     * @param array $parameters The fields to update.
153
     *
154
     * @throws LinodeException
155
     */
156
    public function updateProfile(array $parameters = []): self
157
    {
158
        $response   = $this->client->put('/profile', $parameters);
159
        $contents   = $response->getBody()->getContents();
160
        $this->data = json_decode($contents, true);
161
162
        return $this;
163
    }
164
165
    /**
166
     * This returns a GrantsResponse describing what the acting User has been granted
167
     * access to. For unrestricted users, this will return a  204 and no body because
168
     * unrestricted users have access to everything without grants. This will not return
169
     * information about entities you do not have access to. This endpoint is useful when
170
     * writing third-party OAuth applications to see what options you should present to
171
     * the acting User.
172
     *
173
     * For example, if they do not have `global.add_linodes`, you might not display a
174
     * button to deploy a new Linode.
175
     *
176
     * Any client may access this endpoint; no OAuth scopes are required.
177
     *
178
     * @throws LinodeException
179
     */
180
    public function getProfileGrants(): ?GrantsResponse
181
    {
182
        $response = $this->client->get('/profile/grants');
183
184
        if (LinodeClient::SUCCESS_NO_CONTENT === $response->getStatusCode()) {
185
            return null;
186
        }
187
188
        $contents = $response->getBody()->getContents();
189
        $json     = json_decode($contents, true);
190
191
        return new GrantsResponse($this->client, $json);
192
    }
193
194
    /**
195
     * Returns a collection of successful account logins from this user during the last
196
     * 90 days.
197
     *
198
     * @return Login[] An array of successful account logins from this user during the last 90 days.
199
     *
200
     * @throws LinodeException
201
     */
202
    public function getProfileLogins(): array
203
    {
204
        $response = $this->client->get('/profile/logins');
205
        $contents = $response->getBody()->getContents();
206
        $json     = json_decode($contents, true);
207
208
        return array_map(fn ($data) => new Login($this->client, $data), $json['data']);
209
    }
210
211
    /**
212
     * Returns a login object displaying information about a successful account login
213
     * from this user.
214
     *
215
     * @param int $loginId The ID of the login object to access.
216
     *
217
     * @throws LinodeException
218
     */
219
    public function getProfileLogin(int $loginId): Login
220
    {
221
        $response = $this->client->get("/profile/logins/{$loginId}");
222
        $contents = $response->getBody()->getContents();
223
        $json     = json_decode($contents, true);
224
225
        return new Login($this->client, $json);
226
    }
227
228
    /**
229
     * View a list of user preferences tied to the OAuth client that generated
230
     * the token making the request. The user preferences endpoints allow
231
     * consumers of the API to store arbitrary JSON data, such as a user's font
232
     * size preference or preferred display name. User preferences are available
233
     * for each OAuth client registered to your account, and as such an account can
234
     * have multiple user preferences.
235
     *
236
     * @throws LinodeException
237
     */
238
    public function getUserPreferences(): array
239
    {
240
        $response = $this->client->get('/profile/preferences');
241
        $contents = $response->getBody()->getContents();
242
243
        return json_decode($contents, true);
244
    }
245
246
    /**
247
     * Updates a user's preferences. These preferences are tied to the OAuth client that
248
     * generated the token making the request. The user preferences endpoints allow
249
     * consumers of the API to store arbitrary JSON data, such as a user's font size
250
     * preference or preferred display name. An account may have multiple preferences.
251
     * Preferences, and the pertaining request body, may contain any arbitrary JSON data
252
     * that the user would like to store.
253
     *
254
     * @param array $parameters The user preferences to update or store.
255
     *
256
     * @throws LinodeException
257
     */
258
    public function updateUserPreferences(array $parameters = []): array
259
    {
260
        $response = $this->client->put('/profile/preferences', $parameters);
261
        $contents = $response->getBody()->getContents();
262
263
        return json_decode($contents, true);
264
    }
265
266
    /**
267
     * Disables Two Factor Authentication for your User. Once successful, login attempts
268
     * from untrusted computers will only require a password before being successful.
269
     * This is less secure, and is discouraged.
270
     *
271
     * @throws LinodeException
272
     */
273
    public function tfaDisable(): void
274
    {
275
        $this->client->post('/profile/tfa-disable');
276
    }
277
278
    /**
279
     * Generates a Two Factor secret for your User. To enable TFA for your User, enter
280
     * the secret obtained from this command with the **Two Factor Authentication
281
     * Confirm/Enable** (POST /profile/tfa-enable-confirm) command.
282
     * Once enabled, logins from untrusted computers are required to provide
283
     * a TFA code before they are successful.
284
     *
285
     * **Note**: Before you can enable TFA, security questions must be answered for your
286
     * User by accessing the **Security Questions Answer** (POST
287
     * /profile/security-questions) command.
288
     *
289
     * @return TwoFactorSecret Two Factor secret generated.
290
     *
291
     * @throws LinodeException
292
     */
293
    public function tfaEnable(): TwoFactorSecret
294
    {
295
        $response = $this->client->post('/profile/tfa-enable');
296
        $contents = $response->getBody()->getContents();
297
        $json     = json_decode($contents, true);
298
299
        return new TwoFactorSecret($this->client, $json);
300
    }
301
302
    /**
303
     * Confirms that you can successfully generate Two Factor codes and enables TFA on
304
     * your Account. Once this is complete, login attempts from untrusted computers will
305
     * be required to provide a Two Factor code before they are successful.
306
     *
307
     * @param string $tfa_code The Two Factor code you generated with your Two Factor secret. These codes are
308
     *                         time-based, so be sure it is current.
309
     *
310
     * @return string A one-use code that can be used in place of your Two Factor code, in case you are
311
     *                unable to generate one. Keep this in a safe place to avoid being locked out of
312
     *                your Account.
313
     *
314
     * @throws LinodeException
315
     */
316
    public function tfaConfirm(string $tfa_code): string
317
    {
318
        $parameters = [
319
            'tfa_code' => $tfa_code,
320
        ];
321
322
        $response = $this->client->post('/profile/tfa-enable-confirm', $parameters);
323
        $contents = $response->getBody()->getContents();
324
        $json     = json_decode($contents, true);
325
326
        return $json['scratch'];
327
    }
328
}
329