Issues (195)

includes/DataObjects/OAuthIdentity.php (1 issue)

Labels
Severity
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\DataObjects;
10
11
use DateTimeImmutable;
12
use Exception;
13
use stdClass;
14
use Waca\DataObject;
15
use Waca\Exceptions\OptimisticLockFailedException;
16
17
class OAuthIdentity extends DataObject
18
{
19
    #region Fields
20
    /** @var int */
21
    private $user;
22
    /** @var string */
23
    private $iss;
24
    /** @var int */
25
    private $sub;
26
    /** @var string */
27
    private $aud;
28
    /** @var int */
29
    private $exp;
30
    /** @var int */
31
    private $iat;
32
    /** @var string */
33
    private $username;
34
    /** @var int */
35
    private $editcount;
36
    /** @var int */
37
    private $confirmed_email;
38
    /** @var int */
39
    private $blocked;
40
    /** @var string */
41
    private $registered;
42
    /** @var int */
43
    private $checkuser;
44
    /** @var int */
45
    private $grantbasic;
46
    /** @var int */
47
    private $grantcreateaccount;
48
    /** @var int */
49
    private $granthighvolume;
50
    /** @var int */
51
    private $grantcreateeditmovepage;
52
    #endregion
53
54
    /**
55
     * Saves a data object to the database, either updating or inserting a record.
56
     * @return void
57
     * @throws Exception
58
     * @throws OptimisticLockFailedException
59
     */
60
    public function save()
61
    {
62
        if ($this->isNew()) {
63
            $statement = $this->dbObject->prepare(<<<SQL
64
                INSERT INTO oauthidentity (
65
                    user, iss, sub, aud, exp, iat, username, editcount, confirmed_email, blocked, registered, checkuser, 
66
                    grantbasic, grantcreateaccount, granthighvolume, grantcreateeditmovepage
67
                ) VALUES (
68
                    :user, :iss, :sub, :aud, :exp, :iat, :username, :editcount, :confirmed_email, :blocked, :registered,
69
                    :checkuser, :grantbasic, :grantcreateaccount, :granthighvolume, :grantcreateeditmovepage
70
                )
71
SQL
72
            );
73
74
            $statement->bindValue(':user', $this->user);
75
            $statement->bindValue(':iss', $this->iss);
76
            $statement->bindValue(':sub', $this->sub);
77
            $statement->bindValue(':aud', $this->aud);
78
            $statement->bindValue(':exp', $this->exp);
79
            $statement->bindValue(':iat', $this->iat);
80
            $statement->bindValue(':username', $this->username);
81
            $statement->bindValue(':editcount', $this->editcount);
82
            $statement->bindValue(':confirmed_email', $this->confirmed_email);
83
            $statement->bindValue(':blocked', $this->blocked);
84
            $statement->bindValue(':registered', $this->registered);
85
            $statement->bindValue(':checkuser', $this->checkuser);
86
            $statement->bindValue(':grantbasic', $this->grantbasic);
87
            $statement->bindValue(':grantcreateaccount', $this->grantcreateaccount);
88
            $statement->bindValue(':granthighvolume', $this->granthighvolume);
89
            $statement->bindValue(':grantcreateeditmovepage', $this->grantcreateeditmovepage);
90
91
            if ($statement->execute()) {
92
                $this->id = (int)$this->dbObject->lastInsertId();
93
            }
94
            else {
95
                throw new Exception($statement->errorInfo());
0 ignored issues
show
$statement->errorInfo() of type array is incompatible with the type string expected by parameter $message of Exception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
                throw new Exception(/** @scrutinizer ignore-type */ $statement->errorInfo());
Loading history...
96
            }
97
        }
98
        else {
99
            $statement = $this->dbObject->prepare(<<<SQL
100
                UPDATE oauthidentity SET
101
                      iss                     = :iss
102
                    , sub                     = :sub
103
                    , aud                     = :aud
104
                    , exp                     = :exp
105
                    , iat                     = :iat
106
                    , username                = :username
107
                    , editcount               = :editcount
108
                    , confirmed_email         = :confirmed_email
109
                    , blocked                 = :blocked
110
                    , registered              = :registered
111
                    , checkuser               = :checkuser
112
                    , grantbasic              = :grantbasic
113
                    , grantcreateaccount      = :grantcreateaccount
114
                    , granthighvolume         = :granthighvolume
115
                    , grantcreateeditmovepage = :grantcreateeditmovepage
116
                    , updateversion           = updateversion + 1
117
                WHERE  id = :id AND updateversion = :updateversion
118
SQL
119
            );
120
121
            $statement->bindValue(':iss', $this->iss);
122
            $statement->bindValue(':sub', $this->sub);
123
            $statement->bindValue(':aud', $this->aud);
124
            $statement->bindValue(':exp', $this->exp);
125
            $statement->bindValue(':iat', $this->iat);
126
            $statement->bindValue(':username', $this->username);
127
            $statement->bindValue(':editcount', $this->editcount);
128
            $statement->bindValue(':confirmed_email', $this->confirmed_email);
129
            $statement->bindValue(':blocked', $this->blocked);
130
            $statement->bindValue(':registered', $this->registered);
131
            $statement->bindValue(':checkuser', $this->checkuser);
132
            $statement->bindValue(':grantbasic', $this->grantbasic);
133
            $statement->bindValue(':grantcreateaccount', $this->grantcreateaccount);
134
            $statement->bindValue(':granthighvolume', $this->granthighvolume);
135
            $statement->bindValue(':grantcreateeditmovepage', $this->grantcreateeditmovepage);
136
137
            $statement->bindValue(':id', $this->id);
138
            $statement->bindValue(':updateversion', $this->updateversion);
139
140
            if (!$statement->execute()) {
141
                throw new Exception($statement->errorInfo());
142
            }
143
144
            if ($statement->rowCount() !== 1) {
145
                throw new OptimisticLockFailedException();
146
            }
147
148
            $this->updateversion++;
149
        }
150
    }
151
152
    #region Properties
153
154
    /**
155
     * @return int
156
     */
157
    public function getUserId()
158
    {
159
        return $this->user;
160
    }
161
162
    /**
163
     * @param int $user
164
     */
165
    public function setUserId($user)
166
    {
167
        $this->user = $user;
168
    }
169
170
    /**
171
     * @return string
172
     */
173
    public function getIssuer()
174
    {
175
        return $this->iss;
176
    }
177
178
    /**
179
     * @return int
180
     */
181
    public function getSubject()
182
    {
183
        return $this->sub;
184
    }
185
186
    /**
187
     * @return string
188
     */
189
    public function getAudience()
190
    {
191
        return $this->aud;
192
    }
193
194
    /**
195
     * @return int
196
     */
197
    public function getExpirationTime()
198
    {
199
        return $this->exp;
200
    }
201
202
    /**
203
     * @return int
204
     */
205
    public function getIssuedAtTime()
206
    {
207
        return $this->iat;
208
    }
209
210
    /**
211
     * @return string
212
     */
213
    public function getUsername()
214
    {
215
        return $this->username;
216
    }
217
218
    /**
219
     * @return int
220
     */
221
    public function getEditCount()
222
    {
223
        return $this->editcount;
224
    }
225
226
    /**
227
     * @return bool
228
     */
229
    public function getConfirmedEmail()
230
    {
231
        return $this->confirmed_email == 1;
232
    }
233
234
    /**
235
     * @return bool
236
     */
237
    public function getBlocked()
238
    {
239
        return $this->blocked == 1;
240
    }
241
242
    /**
243
     * @return string
244
     */
245
    public function getRegistered()
246
    {
247
        return $this->registered;
248
    }
249
250
    public function getRegistrationDate()
251
    {
252
        return DateTimeImmutable::createFromFormat('YmdHis', $this->registered)->format('r');
253
    }
254
255
    public function getAccountAge()
256
    {
257
        $regDate = DateTimeImmutable::createFromFormat('YmdHis', $this->registered);
258
        $interval = $regDate->diff(new DateTimeImmutable(), true);
259
260
        return $interval->days;
261
    }
262
263
    /**
264
     * @return bool
265
     */
266
    public function getCheckuser()
267
    {
268
        return $this->checkuser == 1;
269
    }
270
271
    /**
272
     * @return bool
273
     */
274
    public function getGrantBasic()
275
    {
276
        return $this->grantbasic == 1;
277
    }
278
279
    /**
280
     * @return bool
281
     */
282
    public function getGrantCreateAccount()
283
    {
284
        return $this->grantcreateaccount == 1;
285
    }
286
287
    /**
288
     * @return bool
289
     */
290
    public function getGrantHighVolume()
291
    {
292
        return $this->granthighvolume == 1;
293
    }
294
295
    /**
296
     * @return bool
297
     */
298
    public function getGrantCreateEditMovePage()
299
    {
300
        return $this->grantcreateeditmovepage == 1;
301
    }
302
303
    #endregion Properties
304
305
    /**
306
     * Populates the fields of this instance from a provided JSON Web Token
307
     *
308
     * @param stdClass $jwt
309
     */
310
    public function populate($jwt)
311
    {
312
        $this->iss = $jwt->iss;
313
        $this->sub = $jwt->sub;
314
        $this->aud = $jwt->aud;
315
        $this->exp = $jwt->exp;
316
        $this->iat = $jwt->iat;
317
        $this->username = $jwt->username;
318
        $this->editcount = $jwt->editcount;
319
        $this->confirmed_email = $jwt->confirmed_email ? 1 : 0;
320
        $this->blocked = $jwt->blocked ? 1 : 0;
321
        $this->registered = $jwt->registered;
322
323
        /*
324
         * Rights we need:
325
         *  Account creation
326
         *      createaccount      => createaccount
327
         *  Flagged users:
328
         *      tboverride-account => createaccount
329
         *      override-antispoof => N/A
330
         *  Welcome bot:
331
         *      createtalk         => createeditmovepage
332
         *      edit               => editpage/editprotected/editmycssjs/editinterface/createmoveeditpage/delete/protect
333
         *  Would be nice:
334
         *      apihighlimits      => highvolume
335
         *      noratelimit        => highvolume
336
         *
337
         * Hence, we're requesting these grants:
338
         *      useoauth (required)
339
         *      createaccount
340
         *      createeditmovepage
341
         *
342
         * Any antispoof conflicts will still have to be resolved manually using the normal creation form.
343
         */
344
345
        $this->grantbasic = in_array('basic', $jwt->grants) ? 1 : 0;
346
        $this->grantcreateaccount = in_array('createaccount', $jwt->grants) ? 1 : 0;
347
        $this->grantcreateeditmovepage = in_array('createeditmovepage', $jwt->grants) ? 1 : 0;
348
        $this->granthighvolume = in_array('highvolume', $jwt->grants) ? 1 : 0;
349
350
        $this->checkuser = in_array('checkuser-log', $jwt->rights) ? 1 : 0;
351
    }
352
}
353