Passed
Push — master ( 562ec1...c64a31 )
by Terrence
15:08
created

src/Service/DBService.php (7 issues)

Labels
Severity
1
<?php
2
3
namespace CILogon\Service;
4
5
use CILogon\Service\Util;
6
7
/**
8
 * DBService
9
 *
10
 * This class is a wrapper for the dbService servlet.  The dbService
11
 * servlet acts as a frontend to the database that stores info on users,
12
 * portal parameters, and IdPs. This was created to allow for fast
13
 * access to the database by keeping a connection open.  This class is a
14
 * rework of the old store.php class.
15
 *
16
 * Example usage:
17
 *     // For authentication, we have a bunch of attributes from an
18
 *     // identity provider. Thus get the database uid for the user
19
 *     // by using the multi-parameter version of getUser().
20
 *     $uid = '';
21
 *     $dbservice = new DBService();
22
 *     $dbservice->getUser('[email protected]',
23
 *                         'urn:mace:incommon:uiuc.edu',
24
 *                         'University of Illinois at Urbana-Champaign',
25
 *                         'John','Smith','John Smith,
26
 *                          '[email protected]');
27
 *     if (!($dbservice->status & 1)) { // OK status codes are even
28
 *         $uid = $dbservice->user_uid;
29
 *     }
30
 *
31
 *     // Later in the code, re-fetch the user using this uid
32
 *     // and print out the stored attributes.
33
 *     if (strlen($uid) > 0) {
34
 *         $dbservice->getUser($uid);
35
 *         echo 'Name = ' . $dbservice->first_name . ' ' .
36
 *                          $dbservice->last_name  . "\n";
37
 *         echo 'DN = '   . $dbservice->distinguished_name . "\n";
38
 *     }
39
 *
40
 *     // For getting/setting the Shibboleth-based IdPs, use the
41
 *     // getIdps()/setIdps() methods.  These methods utilize the
42
 *     // class member array $idp_uids for reading/writing. Two
43
 *     // convenience methods (setIdpsFromKeys($array) and
44
 *     // setIdpsFromValues($array)) are provided to populate the
45
 *     // $idp_uids array from the passed-in $array.
46
 *     $dbservice->getIdps();
47
 *     foreach($dbservice->idp_uids as $value) {
48
 *         echo "$value\n";
49
 *     }
50
 *
51
 *     $idps = array('urn:mace:incommon:ucsd.edu',
52
 *                   'urn:mace:incommon:uiuc.edu');
53
 *     $dbservice->setIdpsFromValues($idps);
54
 *     //   --- OR ---
55
 *     $idps = array('urn:mace:incommon:ucsd.edu' => 1,
56
 *                   'urn:mace:incommon:uiuc.edu' => 1);
57
 *     $dbservice->setIdpsFromKeys($idps);
58
 */
59
60
class DBService
61
{
62
    /**
63
     * @var array $STATUS The various STATUS_* constants, originally from
64
     *      Store.pm. See cilogon2-server-loader-oauth2/src/main/java/org/cilogon/oauth2/servlet/impl/DBService2.java
65
     *      in the https://github.com/cilogon/cilogon-java/ repo for the
66
     *      definitive list of oauth2 return status codes.
67
     *      The keys of the array are strings corresponding to the
68
     *      constant names. The values of the array are the integer (hex)
69
     *      values. For example, DBService::$STATUS['STATUS_OK'] = 0;
70
     *      Use 'array_search($this->status,DBService::$STATUS)' to look
71
     *      up the STATUS_* name given the status integer value.
72
     */
73
    public static $STATUS = array(
74
        'STATUS_OK'                        => 0x0,
75
        'STATUS_ACTION_NOT_FOUND'          => 0x1,
76
        'STATUS_NEW_USER'                  => 0x2,
77
        'STATUS_USER_UPDATED'              => 0x4,
78
        'STATUS_USER_NOT_FOUND'            => 0x6,
79
        'STATUS_USER_EXISTS'               => 0x8,
80
        'STATUS_USER_EXISTS_ERROR'         => 0xFFFA1, // 1048481
81
        'STATUS_USER_NOT_FOUND_ERROR'      => 0xFFFA3, // 1048483
82
        'STATUS_TRANSACTION_NOT_FOUND'     => 0xFFFA5, // 1048485
83
        'STATUS_IDP_SAVE_FAILED'           => 0xFFFA7, // 1048487
84
        'STATUS_DUPLICATE_PARAMETER_FOUND' => 0xFFFF1, // 1048561
85
        'STATUS_INTERNAL_ERROR'            => 0xFFFF3, // 1048563
86
        'STATUS_SAVE_IDP_FAILED'           => 0xFFFF5, // 1048565
87
        'STATUS_MALFORMED_INPUT_ERROR'     => 0xFFFF7, // 1048567
88
        'STATUS_MISSING_PARAMETER_ERROR'   => 0xFFFF9, // 1048569
89
        'STATUS_NO_REMOTE_USER'            => 0xFFFFB, // 1048571
90
        'STATUS_NO_IDENTITY_PROVIDER'      => 0xFFFFD, // 1048573
91
        'STATUS_CLIENT_NOT_FOUND'          => 0xFFFFF, // 1048575
92
        'STATUS_TRANSACTION_NOT_FOUND'     => 0x10001, //   65537
93
        'STATUS_EPTID_MISMATCH'            => 0x100001,// 1048577
94
        'STATUS_PAIRWISE_ID_MISMATCH'      => 0x100003,// 1048579
95
        'STATUS_SUBJECT_ID_MISMATCH'       => 0x100005,// 1048581
96
        'STATUS_EXPIRED_TOKEN'             => 0x10003, //   65539
97
        'STATUS_CREATE_TRANSACTION_FAILED' => 0x10005, //   65541
98
        'STATUS_UNKNOWN_CALLBACK'          => 0x10007, //   65543
99
        'STATUS_MISSING_CLIENT_ID'         => 0x10009, //   65545
100
        'STATUS_NO_REGISTERED_CALLBACKS'   => 0x1000B, //   65547
101
        'STATUS_UNKNOWN_CLIENT'            => 0x1000D, //   65549
102
        'STATUS_UNAPPROVED_CLIENT'         => 0x1000F, //   65551
103
        'STATUS_NO_SCOPES'                 => 0x10011, //   65553
104
        'STATUS_MALFORMED_SCOPE'           => 0x10013, //   65555
105
    );
106
107
    public static $STATUS_TEXT = array(
108
        'STATUS_OK'                        => 'Status OK.',
109
        'STATUS_ACTION_NOT_FOUND'          => 'Action not found.',
110
        'STATUS_NEW_USER'                  => 'New user created.',
111
        'STATUS_USER_UPDATED'              => 'User data updated.',
112
        'STATUS_USER_NOT_FOUND'            => 'User not found.',
113
        'STATUS_USER_EXISTS'               => 'User exists.',
114
        'STATUS_USER_EXISTS_ERROR'         => 'User already exists.',
115
        'STATUS_USER_NOT_FOUND_ERROR'      => 'User not found.',
116
        'STATUS_TRANSACTION_NOT_FOUND'     => 'Transaction not found.',
117
        'STATUS_IDP_SAVE_FAILED'           => 'Could not save IdPs.',
118
        'STATUS_DUPLICATE_PARAMETER_FOUND' => 'Duplicate parameter.',
119
        'STATUS_INTERNAL_ERROR'            => 'Internal error.',
120
        'STATUS_SAVE_IDP_FAILED'           => 'Could not save IdP.',
121
        'STATUS_MALFORMED_INPUT_ERROR'     => 'Malformed input.',
122
        'STATUS_MISSING_PARAMETER_ERROR'   => 'Missing parameter.',
123
        'STATUS_NO_REMOTE_USER'            => 'Missing Remote User.',
124
        'STATUS_NO_IDENTITY_PROVIDER'      => 'Missing IdP.',
125
        'STATUS_CLIENT_NOT_FOUND'          => 'Missing client.',
126
        'STATUS_TRANSACTION_NOT_FOUND'     => 'Transaction not found.',
127
        'STATUS_EPTID_MISMATCH'            => 'EPTID mismatch.',
128
        'STATUS_PAIRWISE_ID_MISMATCH'      => 'Pairwise ID mismatch.',
129
        'STATUS_SUBJECT_ID_MISMATCH'       => 'Subject ID mismatch.',
130
        'STATUS_EXPIRED_TOKEN'             => 'Expired token.',
131
        'STATUS_CREATE_TRANSACTION_FAILED' => 'Failed to initialize OIDC flow.',
132
        'STATUS_UNKNOWN_CALLBACK'          => 'The redirect_uri does not match a registered callback URI.',
133
        'STATUS_MISSING_CLIENT_ID'         => 'Missing client_id parameter.',
134
        'STATUS_NO_REGISTERED_CALLBACKS'   => 'No registered callback URIs.',
135
        'STATUS_UNKNOWN_CLIENT'            => 'Unknown client_id.',
136
        'STATUS_UNAPPROVED_CLIENT'         => 'Client has not been approved.',
137
        'STATUS_NO_SCOPES'                 => 'Missing or empty scope parameter.',
138
        'STATUS_MALFORMED_SCOPE'           => 'Malformed scope parameter.',
139
    );
140
141
    /**
142
     * @var array $user_attrs An array of all the user attributes that
143
     *      get passed to the getUser function. This is available to other
144
     *      function since these user attributes are set frequently
145
     *      throughout the code.
146
     */
147
    public static $user_attrs = [
148
        'remote_user',
149
        'idp',
150
        'idp_display_name',
151
        'first_name',
152
        'last_name',
153
        'display_name',
154
        'email',
155
        'loa',
156
        'eppn',
157
        'eptid',
158
        'open_id',
159
        'oidc',
160
        'subject_id',
161
        'pairwise_id',
162
        'affiliation',
163
        'ou',
164
        'member_of',
165
        'acr',
166
        'amr',
167
        'entitlement',
168
        'itrustuin',
169
    ];
170
171
    /**
172
     * @var int|null $status The returned status code from dbService calls
173
     */
174
    public $status;
175
176
    /**
177
     * @var string|null $user_uid The CILogon UID
178
     */
179
    public $user_uid;
180
181
    /**
182
     * @var string|null $remote_user The HTTP session REMOTE_USER
183
     */
184
    public $remote_user;
185
186
    /**
187
     * @var string|null $idp The Identity Provider's entityId
188
     */
189
    public $idp;
190
191
    /**
192
     * @var string|null $idp_display_name The Identity Provider's name
193
     */
194
    public $idp_display_name;
195
196
    /**
197
     * @var string|null $first_name User's given name
198
     */
199
    public $first_name;
200
201
    /**
202
     * @var string|null $last_name User's family name
203
     */
204
    public $last_name;
205
206
    /**
207
     * @var string|null $display_name User's full name
208
     */
209
    public $display_name;
210
211
    /**
212
     * @var string|null $email User's email address
213
     */
214
    public $email;
215
216
    /**
217
     * @var string|null $loa Level of Assurance (Note: not saved in database)
218
     */
219
    public $loa;
220
221
    /**
222
     * @var string|null $distinguished_name X.509 DN + email address
223
     */
224
    public $distinguished_name;
225
226
    /**
227
     * @var string|null $eppn eduPersonPrincipalName
228
     */
229
    public $eppn;
230
231
    /**
232
     * @var string|null $eptid eduPersonTargetedID
233
     */
234
    public $eptid;
235
236
    /**
237
     * @var string|null $open_id Old Google OpenID 2.0 identifier
238
     */
239
    public $open_id;
240
241
    /**
242
     * @var string|null $oidc OpenID Connect identifier
243
     */
244
    public $oidc;
245
246
    /**
247
     * @var string|null $affiliation eduPersonScopedAffiliation
248
     */
249
    public $affiliation;
250
251
    /**
252
     * @var string|null $ou Organizational Unit
253
     */
254
    public $ou;
255
256
    /**
257
     * @var string|null $member_of isMemberOf group information
258
     */
259
    public $member_of;
260
261
    /**
262
     * @var string|null $acr Authentication Context Class Ref
263
     */
264
    public $acr;
265
266
    /**
267
     * @var string|null $amr Authentication Method Reference from ORCID
268
     */
269
    public $amr;
270
271
    /**
272
     * @var string|null $entitlement eduPersonEntitlement
273
     */
274
    public $entitlement;
275
276
    /**
277
     * @var string|null $itrustuin Person's univeristy ID number
278
     */
279
    public $itrustuin;
280
281
    /**
282
     * @var string|null $subject_id Person's univeristy subject identifier
283
     */
284
    public $subject_id;
285
286
    /**
287
     * @var string|null $pairwise_id Person's univeristy pairwise identifier
288
     */
289
    public $pairwise_id;
290
291
    /**
292
     * @var string|null $serial_string CILogon serial string (e.g., A34201)
293
     */
294
    public $serial_string;
295
296
    /**
297
     * @var string|null $create_time Time user entry was created
298
     */
299
    public $create_time;
300
301
    /**
302
     * @var string|null $oauth_token OAuth 2.0 token
303
     */
304
    public $oauth_token;
305
306
    /**
307
     * @var string|null $cilogon_callback OAuth 1.0a callback URL
308
     */
309
    public $cilogon_callback;
310
311
    /**
312
     * @var string|null $cilogon_success OAuth 1.0a success URL
313
     */
314
    public $cilogon_success;
315
316
    /**
317
     * @var string|null $cilogon_failure OAuth 1.0a failure URL
318
     */
319
    public $cilogon_failure;
320
321
    /**
322
     * @var string|null $cilogon_portal_name OAuth client name
323
     */
324
    public $cilogon_portal_name;
325
326
    /**
327
     * @var array $idp_uids IdPs stored in the 'values' of the array
328
     */
329
    public $idp_uids;
330
331
    /**
332
     * @var string|null $dbservice URL The URL to use for the dbService
333
     */
334
    private $dbserviceurl;
335
336
    /**
337
     * __construct
338
     *
339
     * Default constructor.  All of the various class members are
340
     * initialized to 'null' or empty arrays.
341
     *
342
     * @param string $serviceurl (Optional) The URL of the database service
343
     *        servlet
344
     */
345
    public function __construct($serviceurl = DEFAULT_DBSERVICE_URL)
0 ignored issues
show
The constant CILogon\Service\DEFAULT_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
346
    {
347
        $this->clear();
348
        $this->setDBServiceURL($serviceurl);
349
    }
350
351
    /**
352
     * getDBServiceURL
353
     *
354
     * Returns the full URL of the database servlet used by the call()
355
     * function.
356
     *
357
     * @return string The URL of the database service servlet
358
     */
359
    public function getDBServiceURL()
360
    {
361
        return $this->dbserviceurl;
362
    }
363
364
    /**
365
     * setDBServiceURL
366
     *
367
     * Set the private variable $dbserviceurl to the full URL of the
368
     * database servlet, which is used by the call() function.
369
     *
370
     * @param string $serviceurl The URL of the database service servlet.
371
     */
372
    public function setDBServiceURL($serviceurl)
373
    {
374
        $this->dbserviceurl = $serviceurl;
375
    }
376
377
    /**
378
     * clear
379
     *
380
     * Set all of the class members to 'null' or empty arrays.
381
     */
382
    public function clear()
383
    {
384
        $this->clearUser();
385
        $this->clearPortal();
386
        $this->clearIdps();
387
    }
388
389
    /**
390
     * clearUser
391
     *
392
     * Set all of the class member variables associated with getUser()
393
     * to 'null'.
394
     */
395
    public function clearUser()
396
    {
397
        foreach (static::$user_attrs as $value) {
398
            $this->$value = null;
399
        }
400
        $this->status = null;
401
        $this->user_uid = null;
402
        $this->distinguished_name = null;
403
        $this->serial_string = null;
404
        $this->create_time = null;
405
    }
406
407
    /**
408
     * clearPortal
409
     *
410
     * Set all of the class member variables associated with
411
     * getPortalParameters() to 'null'.
412
     */
413
    public function clearPortal()
414
    {
415
        $this->status = null;
416
        $this->oauth_token = null;
417
        $this->cilogon_callback = null;
418
        $this->cilogon_success = null;
419
        $this->cilogon_failure = null;
420
        $this->cilogon_portal_name = null;
421
    }
422
423
    /**
424
     * clearIdps
425
     *
426
     * Set the class member variable $idp_uids to an empty array.
427
     */
428
    public function clearIdps()
429
    {
430
        $this->status = null;
431
        $this->idp_uids = array();
432
    }
433
434
    /**
435
     * getUser
436
     *
437
     * This method calls the 'getUser' action of the servlet and sets
438
     * the class member variables associated with user info
439
     * appropriately.  If the servlet returns correctly (i.e. an HTTP
440
     * status code of 200), this method returns true.
441
     *
442
     * @param mixed $args Variable number of parameters: 1, or more.
443
     *        For 1 parameter : $uid (database user identifier)
444
     *        For more than 1 parameter, parameters can include:
445
     *            $remote_user, $idp, $idp_display_name,
446
     *            $first_name, $last_name, $display_name, $email,
447
     *            $eppn, $eptid, $openid, $oidc,
448
     *            $subject_id, $pairwise_id, $affiliation,
449
     *            $ou, $member_of, $acr, $amr, $entitlement,
450
     *            $itrustuin
451
     *
452
     * @return bool True if the servlet returned correctly. Else false.
453
     */
454
    public function getUser(...$args)
455
    {
456
        $retval = false;
457
        $this->clearUser();
458
        $this->setDBServiceURL(DEFAULT_DBSERVICE_URL);
0 ignored issues
show
The constant CILogon\Service\DEFAULT_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
459
        $numargs = count($args);
460
        if ($numargs == 1) {
461
            $retval = $this->call('action=getUser&user_uid=' .
462
                urlencode($args[0]));
463
        } elseif ($numargs > 1) {
464
            $cmd = 'action=getUser';
465
            $attr_arr = array();
466
            $ou_pos = array_search('ou', static::$user_attrs);
467
            for ($i = 0; $i < $numargs; $i++) {
468
                $arg = $args[$i];
469
                if (strlen($arg) > 0) {
470
                    if ($i > $ou_pos) {
471
                        // Put params after $ou into JSON object
472
                        $attr_arr[static::$user_attrs[$i]] = $arg;
473
                    } else {
474
                        $cmd .= '&' . static::$user_attrs[$i] . '=' . urlencode($arg);
475
                    }
476
                }
477
            }
478
            // If any elements in $attr_arr, append converted JSON object
479
            if (count($attr_arr) > 0) {
480
                if (
481
                    ($attr_json = json_encode(
482
                        $attr_arr,
483
                        JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES
484
                    )
485
                    ) !== false
486
                ) {
487
                    $cmd .= '&attr_json=' . urlencode($attr_json);
488
                }
489
            }
490
            // Add 'us_idp' parameter for InCommon/Google (1) or eduGAIN (0)
491
            $us_idp = 0;
492
            $idp = $args[1];
493
            $idp_display_name = $args[2];
494
            if (
495
                (Util::getIdpList()->isRegisteredByInCommon($idp)) ||
496
                (in_array($idp_display_name, Util::$oauth2idps))
497
            ) {
498
                $us_idp = 1;
499
            }
500
            $cmd .= "&us_idp=$us_idp";
501
502
            $retval = $this->call($cmd);
503
        }
504
        return $retval;
505
    }
506
507
    /**
508
     * removeUser
509
     *
510
     * This method calls the 'removeUser' action of the servlet and
511
     * sets the class member variable $status appropriately.  If the
512
     * servlet returns correctly (i.e. an HTTP status code of 200),
513
     * this method returns true.
514
     *
515
     * @param string $uid The database user identifier
516
     * @return bool True if the servlet returned correctly. Else false.
517
     */
518
    public function removeUser($uid)
519
    {
520
        $this->clearUser();
521
        $this->setDBServiceURL(DEFAULT_DBSERVICE_URL);
0 ignored issues
show
The constant CILogon\Service\DEFAULT_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
522
        return $this->call('action=removeUser&user_uid=' .
523
            urlencode($uid));
524
    }
525
526
    /**
527
     * getPortalParameters
528
     *
529
     * This method calls the 'getPortalParameter' action of the servlet
530
     * and sets the class member variables associated with the portal
531
     * parameters appropriately. If the servlet returns correctly (i.e.
532
     * an HTTP status code of 200), this method returns true.
533
     *
534
     * @param string $oauth_token The database OAuth identifier token
535
     * @return bool True if the servlet returned correctly. Else false.
536
     */
537
    public function getPortalParameters($oauth_token)
538
    {
539
        $this->clearPortal();
540
        $this->setDBServiceURL(OAUTH1_DBSERVICE_URL);
0 ignored issues
show
The constant CILogon\Service\OAUTH1_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
541
        return $this->call('action=getPortalParameter&oauth_token=' .
542
            urlencode($oauth_token));
543
    }
544
545
    /**
546
     * getIdps
547
     *
548
     * This method calls the 'getAllIdps' action of the servlet and
549
     * sets the class member array $idp_uris to contain all of the
550
     * Idps in the database, stored in the 'values' of the array.  If
551
     * the servlet returns correctly (i.e. an HTTP status code of 200),
552
     * this method returns true.
553
     *
554
     * @return bool True if the servlet returned correctly. Else false.
555
     */
556
    public function getIdps()
557
    {
558
        $this->clearIdps();
559
        $this->setDBServiceURL(DEFAULT_DBSERVICE_URL);
0 ignored issues
show
The constant CILogon\Service\DEFAULT_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
560
        return $this->call('action=getAllIdps');
561
    }
562
563
    /**
564
     * setIdps
565
     *
566
     * This method calls the 'setAllIdps' action of the servlet using
567
     * the class memeber array $idp_uris as the source for the Idps to
568
     * be stored to the database.  Note that if this array is empty,
569
     * an error code will be returned in the status since at least one
570
     * IdP should be saved to the database.  If you want to pass an
571
     * array of Idps to be saved, see the setIdpsFromKeys($array) and
572
     * setIdpsFromValues($array) methods.  If the servlet returns
573
     * correctly (i.e. an HTTP status code of 200), this method
574
     * returns true.
575
     *
576
     * @return bool True if the servlet returned correctly. Else false.
577
     */
578
    public function setIdps()
579
    {
580
        $retval = false;
581
        $this->setDBServiceURL(DEFAULT_DBSERVICE_URL);
0 ignored issues
show
The constant CILogon\Service\DEFAULT_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
582
        $idpcount = count($this->idp_uids);
583
        $idpidx = 0;
584
        if ($idpcount > 0) {
585
            // Loop through the idp_uids in chunks of 50 to deal
586
            // with query parameter limit of http browsers/servers.
587
            while ($idpidx < $idpcount) { // Loop through all IdPs
588
                $fiftyidx = 0;
589
                $idplist = '';
590
                while (
591
                    ($fiftyidx < 50) && // Send 50 IdPs at a time
592
                       ($idpidx < $idpcount)
593
                ) {
594
                    $idplist .=  '&idp_uid=' .
595
                                 urlencode($this->idp_uids[$idpidx]);
596
                    $fiftyidx++;
597
                    $idpidx++;
598
                }
599
                $cmd = 'action=setAllIdps' . $idplist;
600
                $retval = $this->call($cmd);
601
            }
602
        }
603
        return $retval;
604
    }
605
606
    /**
607
     * setIdpsFromKeys
608
     *
609
     * This is a convenience method which calls setIdps using a
610
     * passed-in array of IdPs stored as the keys of the array.  It
611
     * first sets the class member array $idp_uids appropriately and
612
     * then calls the setIdps() method. If the servlet returns
613
     * correctly (i.e. an HTTP status code of 200), this method
614
     * returns true.  See also setIdpsFromValues().
615
     *
616
     * @param array $idps An array of IdPs to be saved, stored in the
617
     *       'keys' of the array.
618
     * @return bool True if the servlet returned correctly. Else false.
619
     */
620
    public function setIdpsFromKeys($idps)
621
    {
622
        $this->clearIdps();
623
        foreach ($idps as $key => $value) {
624
            $this->idp_uids[] = $key;
625
        }
626
        return $this->setIdps();
627
    }
628
629
    /**
630
     * setIdpsFromValues
631
     *
632
     * This is a convenience method which calls setIdps using a
633
     * passed-in array of IdPs stored as the values of the array.  It
634
     * first sets the class member array $idp_uids appropriately and
635
     * then calls the setIdps() method. If the servlet returns
636
     * correctly (i.e. an HTTP status code of 200), this method
637
     * returns true.  See also setIdpsFromKeys().
638
     *
639
     * @param array $idps An array of IdPs to be saved, stored in the
640
     *        'values' of the array.
641
     * @return bool True if the servlet returned correctly. Else false.
642
     */
643
    public function setIdpsFromValues($idps)
644
    {
645
        $this->clearIdps();
646
        foreach ($idps as $value) {
647
            $this->idp_uids[] = $value;
648
        }
649
        return $this->setIdps();
650
    }
651
652
    /**
653
     * setTransactionState
654
     *
655
     * This method calls the 'setTransactionState' action of the Oauth
656
     * 2.0 servlet to associate the Oauth 2.0 'code' with the database
657
     * user UID. This is necessary for the Oauth 2.0 server to be able
658
     * to return information about the user (name, email address) as
659
     * well as return a certificate for the user. If the servlet
660
     * returns correctly (i.e. an HTTP status code of 200), this method
661
     * returns true. Check the 'status' return value to verify that
662
     * the transaction state was set successfully.
663
     *
664
     * @param string $code The 'code' as returned by the OAuth 2.0 server.
665
     * @param string $uid The database user UID.
666
     * @param int $authntime The Unix timestamp of the user authentication.
667
     * @param string $loa (Optional) The Level of Assurance: '' = basic,
668
     *        'openid' =  OpenID Connect (e.g., Google),
669
     *        'http://incommonfederation.org/assurance/silver' = silver
670
     * @param string $myproxyinfo (Optional) the 'info:...' string to be
671
     *        passed to MyProxy.
672
     * @return bool True if the servlet returned correctly. Else false.
673
     */
674
    public function setTransactionState(
675
        $code,
676
        $uid,
677
        $authntime,
678
        $loa = '',
679
        $myproxyinfo = ''
680
    ) {
681
        $this->setDBServiceURL(OAUTH2_DBSERVICE_URL);
0 ignored issues
show
The constant CILogon\Service\OAUTH2_DBSERVICE_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
682
        return $this->call(
683
            'action=setTransactionState' .
684
            '&code=' . urlencode($code) .
685
            '&user_uid=' . urlencode($uid) .
686
            '&auth_time=' . urlencode($authntime) .
687
            '&loa=' . urlencode($loa) .
688
            ((strlen($myproxyinfo) > 0) ?
689
                ('&cilogon_info=' . urlencode($myproxyinfo)) : '')
690
        );
691
    }
692
693
    /**
694
     * call
695
     *
696
     * This method does the brunt of the work for calling the
697
     * dbService servlet.  The single parameter is a string of
698
     * 'key1=value1&key2=value2&...' containing all of the parameters
699
     * for the dbService.  If the servlet returns an HTTP status code
700
     * of 200, then this method will return true.  It parses the return
701
     * output for various 'key=value' lines and stores then in the
702
     * appropriate member variables, urldecoded of course.
703
     *
704
     * @param string $params A string containing 'key=value' pairs,
705
     *        separated by ampersands ('&') as appropriate for passing to a
706
     *        URL for a GET query.
707
     * @return bool True if the servlet returned correctly. Else false.
708
     */
709
    public function call($params)
710
    {
711
        $success = false;
712
713
        $attr_json = '';
714
        $ch = curl_init();
715
        if ($ch !== false) {
716
            $url = $this->getDBServiceURL() . '?' . $params;
717
            curl_setopt($ch, CURLOPT_URL, $url);
718
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
719
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
720
            $output = curl_exec($ch);
721
            if (curl_errno($ch)) { // Send alert on curl errors
722
                Util::sendErrorAlert(
723
                    'cUrl Error',
724
                    'cUrl Error    = ' . curl_error($ch) . "\n" .
725
                    "URL Accessed  = $url"
726
                );
727
            }
728
            if (!empty($output)) {
729
                $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
730
                if ($httpcode == 200) {
731
                    $success = true;
732
                    if (preg_match('/status=([^\r\n]+)/', $output, $match)) {
733
                        $this->status = (int)(urldecode($match[1]));
734
                    }
735
                    if (preg_match('/user_uid=([^\r\n]+)/', $output, $match)) {
736
                        $this->user_uid = urldecode($match[1]);
737
                    }
738
                    if (preg_match('/remote_user=([^\r\n]+)/', $output, $match)) {
739
                        $this->remote_user = urldecode($match[1]);
740
                    }
741
                    if (preg_match('/idp=([^\r\n]+)/', $output, $match)) {
742
                        $this->idp = urldecode($match[1]);
743
                    }
744
                    if (preg_match('/idp_display_name=([^\r\n]+)/', $output, $match)) {
745
                        $this->idp_display_name = urldecode($match[1]);
746
                    }
747
                    if (preg_match('/first_name=([^\r\n]+)/', $output, $match)) {
748
                        $this->first_name = urldecode($match[1]);
749
                    }
750
                    if (preg_match('/last_name=([^\r\n]+)/', $output, $match)) {
751
                        $this->last_name = urldecode($match[1]);
752
                    }
753
                    if (preg_match('/[^_]display_name=([^\r\n]+)/', $output, $match)) {
754
                        $this->display_name = urldecode($match[1]);
755
                    }
756
                    if (preg_match('/email=([^\r\n]+)/', $output, $match)) {
757
                        $this->email = urldecode($match[1]);
758
                    }
759
                    if (preg_match('/distinguished_name=([^\r\n]+)/', $output, $match)) {
760
                        $this->distinguished_name = urldecode($match[1]);
761
                    }
762
                    if (preg_match('/eppn=([^\r\n]+)/', $output, $match)) {
763
                        $this->eppn = urldecode($match[1]);
764
                    }
765
                    if (preg_match('/eptid=([^\r\n]+)/', $output, $match)) {
766
                        $this->eptid = urldecode($match[1]);
767
                    }
768
                    if (preg_match('/open_id=([^\r\n]+)/', $output, $match)) {
769
                        $this->open_id = urldecode($match[1]);
770
                    }
771
                    if (preg_match('/oidc=([^\r\n]+)/', $output, $match)) {
772
                        $this->oidc = urldecode($match[1]);
773
                    }
774
                    if (preg_match('/subject_id=([^\r\n]+)/', $output, $match)) {
775
                        $this->subject_id = urldecode($match[1]);
776
                    }
777
                    if (preg_match('/pairwise_id=([^\r\n]+)/', $output, $match)) {
778
                        $this->pairwise_id = urldecode($match[1]);
779
                    }
780
                    if (preg_match('/affiliation=([^\r\n]+)/', $output, $match)) {
781
                        $this->affiliation = urldecode($match[1]);
782
                    }
783
                    if (preg_match('/ou=([^\r\n]+)/', $output, $match)) {
784
                        $this->ou = urldecode($match[1]);
785
                    }
786
                    if (preg_match('/attr_json=([^\r\n]+)/', $output, $match)) {
787
                        // Decode $attr_json into class members later
788
                        $attr_json = urldecode($match[1]);
789
                    }
790
                    if (preg_match('/serial_string=([^\r\n]+)/', $output, $match)) {
791
                        $this->serial_string = urldecode($match[1]);
792
                    }
793
                    if (preg_match('/create_time=([^\r\n]+)/', $output, $match)) {
794
                        $this->create_time = urldecode($match[1]);
795
                    }
796
                    if (preg_match('/oauth_token=([^\r\n]+)/', $output, $match)) {
797
                        $this->oauth_token = urldecode($match[1]);
798
                    }
799
                    if (preg_match('/cilogon_callback=([^\r\n]+)/', $output, $match)) {
800
                        $this->cilogon_callback = urldecode($match[1]);
801
                    }
802
                    if (preg_match('/cilogon_success=([^\r\n]+)/', $output, $match)) {
803
                        $this->cilogon_success = urldecode($match[1]);
804
                    }
805
                    if (preg_match('/cilogon_failure=([^\r\n]+)/', $output, $match)) {
806
                        $this->cilogon_failure = urldecode($match[1]);
807
                    }
808
                    if (preg_match('/cilogon_portal_name=([^\r\n]+)/', $output, $match)) {
809
                        $this->cilogon_portal_name = urldecode($match[1]);
810
                    }
811
                    if (preg_match_all('/idp_uid=([^\r\n]+)/', $output, $match)) {
812
                        foreach ($match[1] as $value) {
813
                            $this->idp_uids[] = urldecode($value);
814
                        }
815
                    }
816
                }
817
            }
818
            curl_close($ch);
819
        }
820
821
        // Convert $attr_json into array and extract elements into class members
822
        if (strlen($attr_json) > 0) {
823
            $attr_arr = json_decode($attr_json, true);
824
            if (!is_null($attr_arr)) {
825
                if (isset($attr_arr['member_of'])) {
826
                    $this->member_of = $attr_arr['member_of'];
827
                }
828
                if (isset($attr_arr['acr'])) {
829
                    $this->acr = $attr_arr['acr'];
830
                }
831
                if (isset($attr_arr['amr'])) {
832
                    $this->amr = $attr_arr['amr'];
833
                }
834
                if (isset($attr_arr['entitlement'])) {
835
                    $this->entitlement = $attr_arr['entitlement'];
836
                }
837
                if (isset($attr_arr['itrustuin'])) {
838
                    $this->itrustuin = $attr_arr['itrustuin'];
839
                }
840
            }
841
        }
842
843
        return $success;
844
    }
845
846
    /**
847
     * dump
848
     *
849
     * This is a convenience method which prints out all of the
850
     * non-null / non-empty member variables to stdout.
851
     */
852
    public function dump()
853
    {
854
        if (!is_null($this->status)) {
855
            echo "status=$this->status (" .
856
            (string)(array_search($this->status, static::$STATUS)) . ")\n";
857
        }
858
        if (!is_null($this->user_uid)) {
859
            echo "user_uid=$this->user_uid\n";
860
        }
861
        if (!is_null($this->remote_user)) {
862
            echo "remote_user=$this->remote_user\n";
863
        }
864
        if (!is_null($this->idp)) {
865
            echo "idp=$this->idp\n";
866
        }
867
        if (!is_null($this->idp_display_name)) {
868
            echo "idp_display_name=$this->idp_display_name\n";
869
        }
870
        if (!is_null($this->first_name)) {
871
            echo "first_name=$this->first_name\n";
872
        }
873
        if (!is_null($this->last_name)) {
874
            echo "last_name=$this->last_name\n";
875
        }
876
        if (!is_null($this->display_name)) {
877
            echo "display_name=$this->display_name\n";
878
        }
879
        if (!is_null($this->email)) {
880
            echo "email=$this->email\n";
881
        }
882
        if (!is_null($this->distinguished_name)) {
883
            echo "distinguished_name=$this->distinguished_name\n";
884
        }
885
        if (!is_null($this->eppn)) {
886
            echo "eppn=$this->eppn\n";
887
        }
888
        if (!is_null($this->eptid)) {
889
            echo "eptid=$this->eptid\n";
890
        }
891
        if (!is_null($this->open_id)) {
892
            echo "open_id=$this->open_id\n";
893
        }
894
        if (!is_null($this->oidc)) {
895
            echo "oidc=$this->oidc\n";
896
        }
897
        if (!is_null($this->affiliation)) {
898
            echo "affiliation=$this->affiliation\n";
899
        }
900
        if (!is_null($this->ou)) {
901
            echo "ou=$this->ou\n";
902
        }
903
        if (!is_null($this->member_of)) {
904
            echo "member_of=$this->member_of\n";
905
        }
906
        if (!is_null($this->acr)) {
907
            echo "acr=$this->acr\n";
908
        }
909
        if (!is_null($this->amr)) {
910
            echo "amr=$this->amr\n";
911
        }
912
        if (!is_null($this->entitlement)) {
913
            echo "entitlement=$this->entitlement\n";
914
        }
915
        if (!is_null($this->itrustuin)) {
916
            echo "itrustuin=$this->itrustuin\n";
917
        }
918
        if (!is_null($this->subject_id)) {
919
            echo "subject_id=$this->subject_id\n";
920
        }
921
        if (!is_null($this->pairwise_id)) {
922
            echo "pairwise_id=$this->pairwise_id\n";
923
        }
924
        if (!is_null($this->serial_string)) {
925
            echo "serial_string=$this->serial_string\n";
926
        }
927
        if (!is_null($this->create_time)) {
928
            echo "create_time=$this->create_time\n";
929
        }
930
        if (!is_null($this->oauth_token)) {
931
            echo "oauth_token=$this->oauth_token\n";
932
        }
933
        if (!is_null($this->cilogon_callback)) {
934
            echo "cilogon_callback=$this->cilogon_callback\n";
935
        }
936
        if (!is_null($this->cilogon_success)) {
937
            echo "cilogon_success=$this->cilogon_success\n";
938
        }
939
        if (!is_null($this->cilogon_failure)) {
940
            echo "cilogon_failure=$this->cilogon_failure\n";
941
        }
942
        if (!is_null($this->cilogon_portal_name)) {
943
            echo "cilogon_portal_name=$this->cilogon_portal_name\n";
944
        }
945
        if (count($this->idp_uids) > 0) {
946
            uasort($this->idp_uids, 'strcasecmp');
947
            echo "idp_uids={\n";
948
            foreach ($this->idp_uids as $value) {
949
                echo "    $value\n";
950
            }
951
            echo "}\n";
952
        }
953
    }
954
}
955