Completed
Push — master ( 0dd51b...0db328 )
by Terrence
14:19
created

index-functions.php ➔ printLogonPage()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 75
rs 8.5454
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file contains functions called by index-site.php. The index-site.php
5
 * file should include this file with the following statement at the top:
6
 *
7
 * require_once __DIR__ . '/index-functions.php';
8
 */
9
10
use CILogon\Service\Util;
11
use CILogon\Service\Content;
12
use CILogon\Service\PortalCookie;
13
use CILogon\Service\DBService;
14
use CILogon\Service\Loggit;
15
16
/**
17
 * printLogonPage
18
 *
19
 * This function prints out the HTML for the main cilogon.org page.
20
 * Explanatory text is shown as well as a button to log in to an IdP
21
 * and get rerouted to the Shibboleth protected getuser script.
22
 */
23
function printLogonPage()
24
{
25
    $log = new Loggit();
26
    $log->info('Welcome page hit.');
27
28
    Util::setSessionVar('stage', 'logon');
29
30
    // Check if this is the first time the user has visited the site from
31
    // the current portal.  We do this by checking the portal cookie's
32
    // lifetime for a positive value.  If the portal cookie has NOT YET been
33
    // set, then check the skin config to see if either initialremember or
34
    // initiallifetime has been set.  We do this here because these two
35
    // values set the portal cookie, which needs to be done before we go
36
    // to the next page (where the cookie is actually read).
37
    $skin = Util::getSkin();
38
    $pc = new PortalCookie();
39
    $portallife = $pc->get('lifetime');
40
41
    if ((strlen($portallife) == 0) || ($portallife == 0)) {
42
        $needtosetcookie = 0;
43
44
        // Try to read the skin's initiallifetime
45
        $initlife = $skin->getConfigOption('delegate', 'initiallifetime');
46
        if ((!is_null($initlife)) && ((int)$initlife > 0)) {
47
            $needtosetcookie = 1;
48
            $initlife = (int)$initlife;
49
        } else { // Set a default lifetime value in case initialremember is set
50
            $initlife = 12;
51
        }
52
53
        // Make sure initiallifetime is within [minlifetime..maxlifetime]
54
        list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
0 ignored issues
show
Bug introduced by
The method getMinMaxLifetimes() does not seem to exist on object<CILogon\Service\Util>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
55
        if ($initlife < $minlife) {
56
            $needtosetcookie = 1;
57
            $initlife = $minlife;
58
        } elseif ($initlife > $maxlife) {
59
            $needtosetcookie = 1;
60
            $initlife = $maxlife;
61
        }
62
63
        // Next, try to read the skin's initialremember
64
        $initialremember = $skin->getConfigOption('delegate', 'initialremember');
65
        if ((!is_null($initialremember)) && ((int)$initialremember > 0)) {
66
            $needtosetcookie = 1;
67
            $initialremember = (int)$initialremember;
68
        } else { // Set a default remember value in case initiallifetime is set
69
            $initialremember = 0;
70
        }
71
72
        if ($needtosetcookie) {
73
            $pc->set('remember', $initialremember);
74
            $pc->set('lifetime', $initlife);
75
            $pc->write();
76
        }
77
    }
78
79
    Content::printHeader('Welcome To The CILogon Delegation Service');
80
81
    // If the <hideportalinfo> option is set, do not show the portal info if
82
    // the callback uri is in the portal list.
83
    $showportalinfo = true;
84
    if (
85
        ((int)$skin->getConfigOption('portallistaction', 'hideportalinfo') == 1) &&
86
        ($skin->inPortalList(Util::getSessionVar('callbackuri')))
87
    ) {
88
        $showportalinfo = false;
89
    }
90
91
    if ($showportalinfo) {
92
        printOAuth1Consent();
93
    }
94
95
    Content::printWAYF();
96
    Content::printFooter();
97
}
98
99
/**
100
 * printOAuth1BadTokenPage
101
 *
102
 * This function prints out the HTML for the page when the oauth_token
103
 * (tempcred) or associated OAuth information is missing, bad, or expired.
104
 */
105
function printOAuth1ErrorPage()
106
{
107
    $log = new Loggit();
108
109
    Content::printHeader('CILogon Delegation Service');
110
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
111
        'oauth1default',
112
        'CILogon OAuth1 Delegation Endpoint',
113
        false
114
    );
115
116
    // CIL-624 If X509 certs are disabled, show a suitable error message
117
    // to the end user.
118
    if ((defined('DISABLE_X509')) && (DISABLE_X509 === true)) {
119
        $log->warn('OAuth1 transaction failed due to DISABLE_X509 set.');
120
        echo '
121
        <div class="card-body px-5">
122
          <div class="card-text my-2">
123
            You have reached the CILogon Delegation Service. This service is
124
            for use by third parties to obtain certificates for their users.
125
            <strong>However, downloading X.509 certificates has been
126
            disabled.</strong>
127
          </div>
128
          <div class="card-text my-2">
129
            Please direct questions to the email address at the bottom of
130
            the page.
131
          </div>
132
        </div> <!-- end card-body -->
133
        ';
134
    } else {
135
        $log->warn('Missing or invalid oauth_token.');
136
        echo '
137
        <div class="card-body px-5">
138
          <div class="card-text my-2">
139
            You have reached the CILogon Delegation Service. This service is
140
            for use by third parties to obtain certificates for their users.
141
            End users should not normally see this page.
142
          </div>
143
          <div class="card-text my-2">
144
          Possible reasons for seeing this page include:
145
          </div>
146
          <div class="card-text my-2">
147
            <ul>
148
              <li>You navigated directly to this page.</li>
149
              <li>You clicked your browser\'s "Back" button.</li>
150
              <li>There was a problem with the delegation process.</li>
151
            </ul>
152
          </div>
153
          <div class="card-text my-2">
154
            Please return to the previous site and try again. If the error
155
            persists, please contact us at the email address at the bottom of
156
            the page.
157
          </div>
158
          <div class="card-text my-2">
159
            If you are an individual wishing to download a certificate to your
160
            local computer, please try the <a target="_blank"
161
            href="https://' , Util::getHN() , '/">CILogon Service</a>.
162
          </div>
163
          <div class="card-text my-2">
164
            <strong>Note:</strong> You must enable cookies in your web
165
            browser to use this site.
166
          </div>
167
        </div> <!-- end card-body -->
168
        ';
169
    }
170
171
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
172
    Content::printFooter();
173
}
174
175
/**
176
 * printMainPage
177
 *
178
 * This function prints out the HTML for the main page where the user
179
 * is presented with the portal information and asked to either allow
180
 * or deny delegation of a certificate to the portal.  We first check
181
 * to see if the 'remember' cookie has been set for this portal. If
182
 * so, then we automatically always approve delegation.  Otherwise,
183
 * we print out the HTML for the <form> buttons.
184
 */
185
function printMainPage()
186
{
187
    $log = new Loggit();
188
    $log->info('Allow Or Deny Delegation page hit.');
189
190
    Util::setSessionVar('stage', 'main');
191
192
    $remember = 0;   // Default value for remember checkbox is unchecked
193
    $life = 12;      // Default value for lifetime is 12 hours
194
195
    // Check the skin for forceremember and forcelifetime
196
    $skin = Util::getSkin();
197
    $forceremember = $skin->getConfigOption('delegate', 'forceremember');
198
    if ((!is_null($forceremember)) && ((int)$forceremember == 1)) {
199
        $forceremember = 1;
200
    } else {
201
        $forceremember = 0;
202
    }
203
    $forcelife = $skin->getConfigOption('delegate', 'forcelifetime');
204
    if ((!is_null($forcelife)) && ((int)$forcelife > 0)) {
205
        $forcelife = (int)$forcelife;
206
    } else {
207
        $forcelife = 0;
208
    }
209
210
    // Try to read the portal coookie for the remember and lifetime values.
211
    $pc = new PortalCookie();
212
    $portalremember = $pc->get('remember');
213
    $portallife = $pc->get('lifetime');
214
215
    // If skin's forceremember or portal cookie's remember is set,
216
    // then we bypass the Allow/Deny delegate page.
217
    if (($forceremember == 1) || ($portalremember == 1)) {
218
        $remember = 1;
219
    }
220
221
    // If skin's forcelifetime or portal cookie's lifetime is set,
222
    // set lifetime accordingly and make sure value is between the
223
    // configured minlifetime and maxlifetime.
224
    if ($forcelife > 0) {
225
        $life = $forcelife;
226
    } elseif ($portallife > 0) {
227
        $life = $portallife;
228
    }
229
    list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
0 ignored issues
show
Bug introduced by
The method getMinMaxLifetimes() does not seem to exist on object<CILogon\Service\Util>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
230
    if ($life < $minlife) {
231
        $life = $minlife;
232
    } elseif ($life > $maxlife) {
233
        $life = $maxlife;
234
    }
235
236
    // If 'remember' is set, then auto-click the 'OK' button for the user.
237
    if ($remember == 1) {
238
        handleAllowDelegation(true);
239
    } else {
240
        // User did not check 'Remember OK' before, so show the
241
        // HTML to prompt user for OK or Cancel delegation.
242
        Content::printHeader('Confirm Allow Delegation');
243
        printOAuth1Certificate($life, $minlife, $maxlife, $forcelife);
244
        Content::printFooter();
245
    }
246
}
247
248
/**
249
 * printOAuth1Consent
250
 *
251
 * This function prints out the 'consent' block showing the portal name and
252
 * callback uris just above the 'Select an Identity Provider' block.
253
 */
254
function printOAuth1Consent()
255
{
256
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
257
        'oauth2consent',
258
        'Consent to Attribute Release',
259
        false
260
    );
261
262
    echo '
263
        <div class="card-body px-5">
264
          <div class="card-row">
265
            "', htmlspecialchars(Util::getSessionVar('portalname')), '"
266
            requests that you select an Identity Provider and click
267
            "', Content::getLogOnButtonText(), '".
268
            If you do not approve this request, do not proceed.
269
          </div>
270
          <div class="card-row">
271
            By proceeding you agree to share your <em>name</em> and
272
            <em>email address</em> with
273
            "', htmlspecialchars(Util::getSessionVar('portalname')), '".
274
          </div>
275
    ';
276
277
    printOAuth1PortalInfo();
278
279
    echo '
280
        </div> <!-- end card-body -->
281
    ';
282
283
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
284
}
285
286
/**
287
 * printOAuth1Certificate
288
 *
289
 * This function prints out the block showing the portal name and callback
290
 * uris, as well as a text input for the user to set the lifetime of the
291
 * certificate to be delegated to the OAuth1 client.
292
 *
293
 * @param int $life The lifetime (in hours) for the delegated certificate.
294
 * @param int $minlife The minimum lifetime for the cert.
295
 * @param int $maxlife The maximum lifetime for the cert.
296
 * @param int $force The forced-set lifetime for the cert.
297
 */
298
function printOAuth1Certificate($life, $minlife, $maxlife, $force)
299
{
300
    $lifehelp = 'Certificate lifetime range is between ' .
301
        $minlife . ' and ' . $maxlife . ' hours.';
302
    $rememberhelp = "Check this box to automatically approve " .
303
        "certificate issuance to the site on future visits. " .
304
        "The certificate lifetime will be remembered. You will " .
305
        "need to clear your browser's cookies to return here.";
306
307
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
308
        'oauth1cert',
309
        'Confirm Certificate Delegation',
310
        false
311
    );
312
313
    echo '
314
        <div class="card-body px-5">
315
          <div class="row mb-3">
316
            "', htmlspecialchars(Util::getSessionVar('portalname')) , '"
317
            is requesting a certificate for you. If you approve, then
318
            "OK" the request. Otherwise, "Cancel" the request or
319
            navigate away from this page.
320
          </div>
321
    ';
322
323
    printOAuth1PortalInfo();
324
325
    Content::printFormHead();
326
327
    echo '
328
          <div class="container col-lg-6 offset-lg-3
329
          col-md-8 offset-md-2 col-sm-10 offset-sm-1">
330
            <div class="form-group">
331
              <div class="form-row">
332
                <label for="lifetime">Certificate Lifetime (in hours):</label>
333
                <input type="number" name="lifetime" id="lifetime"
334
                min="', $minlife, '"
335
                max="', $maxlife, '"
336
                value="', $life , '" ' ,
337
                (($force > 0) ? 'disabled="disabled" ' : ' ') , '
338
                class="form-control" required="required"
339
                aria-describedby="lifetime1help" />
340
                <small id="lifetime1help" class="form-text text-muted">',
341
                $lifehelp, '
342
                </small>
343
<!--[if IE]><input type="text" style="display:none;" disabled="disabled" size="1"/><![endif]-->
344
              </div> <!-- end form-row -->
345
            </div> <!-- end form-group -->
346
347
            <div class="form-group">
348
              <div class="form-row align-items-center justify-content-center">
349
                <div class="form-check">
350
                  <input class="form-check-input" type="checkbox"
351
                  name="rememberok" id="rememberok" />
352
                  <label class="form-check-label"
353
                  for="rememberok">Remember my OK for the site</label>
354
                  <a href="#" tabindex="0" data-trigger="hover click"
355
                  class="helpcursor"
356
                  data-toggle="popover" data-html="true"
357
                  data-content="', $rememberhelp, '"><i class="fa
358
                  fa-question-circle"></i></a>
359
                </div> <!-- end form-check -->
360
              </div> <!-- end form-row -->
361
            </div> <!-- end form-group -->
362
363
            <div class="form-group">
364
              <div class="form-row align-items-center justify-content-center">
365
                <div class="col-auto">
366
                  <input type="submit" name="submit"
367
                  class="btn btn-primary submit form-control" value="OK" />
368
                </div>
369
                <div class="col-auto">
370
                  <input type="submit" name="submit"
371
                  class="btn btn-primary submit form-control" value="Cancel" />
372
                </div>
373
              </div> <!-- end form-row align-items-center -->
374
            </div> <!-- end form-group -->
375
          </div> <!-- end container -->
376
377
        </form>
378
        </div> <!-- end card-body -->
379
    ';
380
381
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
382
}
383
384
/**
385
 * printOAuth1PortalInfo
386
 *
387
 * This function prints the portal name, success uri (i.e., the uri to
388
 * redirect to upon successful delegation of the certificate), and the
389
 * callback uri used by the OAuth1 protocol.
390
 */
391
function printOAuth1PortalInfo()
392
{
393
    echo '
394
    <table class="table table-striped table-sm">
395
    <tbody>
396
      <tr>
397
        <th>Site Name:</th>
398
        <td></td>
399
        <td>', htmlspecialchars(Util::getSessionVar('portalname')), '</td>';
400
401
    $helptext = "The location where you will be redirected upon completion.";
402
403
    echo '
404
      </tr>
405
      <tr>
406
        <th>Site URL:</th>
407
        <td><a href="#" tabindex="0" data-trigger="hover click"
408
          class="helpcursor" data-toggle="popover" data-html="true"
409
          data-content="', $helptext, '"><i class="fa
410
          fa-question-circle"></i></a></td>
411
        <td>', htmlspecialchars(Util::getSessionVar('successuri')), '</td>';
412
413
    $helptext = "The location where CILogon " .
414
        "will send a certificate containing your identity information.";
415
416
    echo '
417
      </tr>
418
      <tr>
419
        <th>Service URL:</th>
420
        <td><a href="#" tabindex="0" data-trigger="hover click"
421
          class="helpcursor" data-toggle="popover" data-html="true"
422
          data-content="', $helptext, '"><i class="fa
423
          fa-question-circle"></i></a></td>
424
        <td>', htmlspecialchars(Util::getSessionVar('callbackuri')), '</td>
425
      </tr>
426
    </tbody>
427
    </table>
428
    ';
429
}
430
431
/**
432
 * printOAuth1DelegationDone
433
 *
434
 * This function prints out the block after generation of the certificate.
435
 * The $success parameter indicates if the cert was generated successfully
436
 * or not. If so, the $responseurl will contain the link to redirect the
437
 * user to, and the $certtext will contain the contents of the cert.
438
 *
439
 * @param bool $success True if the certificate was successfully generated
440
 *        and delegated to the OAuth1 client.
441
 * @param string $responseurl The url to redirect the user to. If this is
442
 *        empty, then the PHP session success/failure uris will be used as
443
 *        determined by the $success value.
444
 * @param string $certtext The contents of the generated cert.
445
 */
446
function printOAuth1DelegationDone($success, $responseurl, $certtext)
447
{
448
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
449
        'oauth1done',
450
        'Certificate Delegation ' . ($success ? 'Success' : 'Failure'),
451
        false
452
    );
453
454
    echo '
455
        <div class="card-body px-5">
456
    ';
457
458
    if ($success) {
459
        echo '
460
          <div class="card-text my-2">
461
            The CILogon Service has issued a certificate to "' ,
462
            htmlspecialchars(Util::getSessionVar('portalname')) , '".
463
            Below is a link to return to
464
            the site to use the issued certificate.
465
          </div>
466
          ';
467
        Content::printCollapseBegin('certdetails', 'Certificate Details');
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
468
        echo '<div class="card-body px-5">
469
                <pre>', htmlspecialchars($certtext), '</pre>
470
              </div>
471
        ';
472
        Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
473
    } else {
474
        echo '
475
          <div class="card-text my-2">
476
            We were unable to issue a certificate to "' ,
477
            htmlspecialchars(Util::getSessionVar('portalname')) , '".
478
            Below is a link to return to the site.
479
          </div> <!-- end card-text -->';
480
    }
481
482
    echo '
483
          <div class="card-text my-2 text-center">
484
            <a class="btn btn-primary"
485
            href="' , ((strlen($responseurl) > 0) ? $responseurl :
486
            (Util::getSessionVar($success ? 'successuri' : 'failureuri'))),
487
            '">Return to ' ,
488
            htmlspecialchars(Util::getSessionVar('portalname')) , '</a>
489
          </div> <!-- end card-text -->
490
        </div> <!-- end card-body -->';
491
492
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
493
}
494
495
/**
496
 * printCancelPage
497
 *
498
 * This function prints out the HTML for when the user clicked the
499
 * 'Cancel' button on the 'Allow Delegation' page.  It gives the user a
500
 * link back to the portal via the 'failure URL'.
501
 */
502
function printCancelPage()
503
{
504
    $portalname = Util::getSessionVar('portalname');
505
506
    Content::printHeader('Delegation Denied');
507
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
508
        'oauth1cancel',
509
        'Certificate Delegation Cancelled',
510
        false
511
    );
512
513
    echo '
514
        <div class="card-body px-5">
515
          <div class="card-text my-2">
516
            You have canceled delegation of a certificate to "' ,
517
            htmlspecialchars($portalname) , '".
518
            Below is a link to return to the portal.
519
            This link has been provided by the portal to be used when
520
            delegation of a certificate fails.
521
          </div>
522
          <div class="card-text my-2">
523
            <strong>Note:</strong> If you do not trust the information
524
            provided by the portal, <strong>do not</strong> click on the
525
            link below.  Instead, please contact your portal administrators
526
            or contact us at the email address at the bottom of the page.
527
          </div>
528
          <div class="card-text my-2 text-center">
529
            <a class="btn btn-primary"
530
            href="' , Util::getSessionVar('failureuri') , '">Return to ' ,
531
            htmlspecialchars($portalname) , '</a>
532
          </div>
533
        </div> <!-- end card-body -->
534
    ';
535
536
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
537
    Content::printFooter();
538
}
539
540
/**
541
 * handleAllowDelegation
542
 *
543
 * This fuction is called when the user clicks the 'OK' button on the
544
 * main page, or when the user had previously checked the 'Remember
545
 * my OK for this portal' checkbox which saved the 'remember' cookie
546
 * for the current portal. It first reads the cookie for the portal and
547
 * updates the 'lifetime' and 'remember' parameters, then (re)saves
548
 * the cookie.  Then it calls out to the 'oauth/authorized' servlet
549
 * in order to do the back-end certificate delegation process. If the
550
 * $always parameter is true, then the user is automatically returned
551
 * to the portal's successuri or failureuri.  Otherwise, the user is
552
 * presented with a page showing the result of the attempted
553
 * certificate delegation as well as a link to 'return to your portal'.
554
 *
555
 * @param bool $always True if the user selected to always allow delegation.
556
 */
557
function handleAllowDelegation($always = false)
558
{
559
    // The 'authorized' servlet may return a response URL to be used
560
    // instead of the success / failure URLs.
561
    $responseurl = '';
562
563
    $log = new Loggit();
564
    $log->info('Attempting to delegate a certificate to a portal...');
565
566
    $life = 0;
567
    // Check the skin's forcelifetime and use it if it is configured.
568
    $forcelife = Util::getSkin()->getConfigOption('delegate', 'forcelifetime');
569
    if ((!is_null($forcelife)) && ((int)$forcelife > 0)) {
570
        $life = (int)$forcelife;
571
    }
572
573
    // Next, try to get the certificate lifetime from a submitted <form>
574
    if ($life == 0) {
575
        $life = (int)(trim(Util::getPostVar('lifetime')));
576
    }
577
578
    // If we couldn't get lifetime from the <form>, try the cookie
579
    $pc = new PortalCookie();
580
    if ($life == 0) {
581
        $life = (int)($pc->get('lifetime'));
582
    }
583
584
    // Default lifetime to 12 hours. And then make sure lifetime is in
585
    // acceptable range.
586
    if ($life == 0) {
587
        $life = 12;
588
    }
589
    list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
0 ignored issues
show
Bug introduced by
The method getMinMaxLifetimes() does not seem to exist on object<CILogon\Service\Util>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
590
    if ($life < $minlife) {
591
        $life = $minlife;
592
    } elseif ($life > $maxlife) {
593
        $life = $maxlife;
594
    }
595
596
    $pc->set('remember', (int)$always);
597
    $pc->set('lifetime', $life);
598
    $pc->write();
599
600
    $success = false;  // Assume delegation of certificate failed
601
    $certtext = '';    // Output of 'openssl x509 -noout -text -in cert.pem'
602
    $myproxyinfo = Util::getSessionVar('myproxyinfo');
603
604
    // Now call out to the 'oauth/authorized' servlet to execute
605
    // the delegation the credential to the portal.
606
    $ch = curl_init();
607
    if ($ch !== false) {
608
        $tempcred = Util::getSessionVar('tempcred');
609
        $url = OAUTH1_AUTHORIZED_URL . '?' .
610
               'oauth_token=' . urlencode($tempcred) . '&' .
611
               'cilogon_lifetime=' . $life . '&' .
612
               'cilogon_loa=' . urlencode(Util::getLOA()) . '&' .
0 ignored issues
show
Bug introduced by
The method getLOA() does not seem to exist on object<CILogon\Service\Util>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
613
               'cilogon_uid=' . urlencode(Util::getSessionVar('user_uid')) .
614
               ((strlen($myproxyinfo) > 0) ?
615
                   ('&cilogon_info=' . urlencode($myproxyinfo)) : '');
616
        curl_setopt($ch, CURLOPT_URL, $url);
617
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
618
        curl_setopt($ch, CURLOPT_TIMEOUT, 35);
619
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
620
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
621
        $output = curl_exec($ch);
622
        if (curl_errno($ch)) { // Send alert on curl errors
623
            Util::sendErrorAlert(
624
                'cUrl Error',
625
                'cUrl Error    = ' . curl_error($ch) . "\n" .
626
                "URL Accessed  = $url"
627
            );
628
        }
629
        if (!empty($output)) {
630
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
631
            if ($httpcode == 200) {
632
                // Check body of curl query for cilogon_status=ok
633
                if (preg_match('/cilogon_status=ok/', $output)) {
634
                    $success = true;
635
                    // Also check if the cert was returned as base64
636
                    // encoded PEM certificate.  If so, get info about it.
637
                    if (
638
                        preg_match(
639
                            '/cilogon_cert=([^\s]+)/',
640
                            $output,
641
                            $matches
642
                        )
643
                    ) {
644
                        $b64cert = $matches[1];
645
                        $cert = base64_decode($b64cert);
646
                        if ($cert !== false) {
647
                            // Run 'openssl x509' command for cert info
648
                            exec(
649
                                '/bin/env RANDFILE=/tmp/.rnd ' .
650
                                '/usr/bin/openssl x509 -text ' .
651
                                '<<< ' . escapeshellarg($cert) . ' 2>&1',
652
                                $x509out,
653
                                $retcode
654
                            );
655
                            if ($retcode === 0) {
656
                                $certtext = implode("\n", $x509out);
657
                            } else {
658
                                $certtext = $cert;
659
                            }
660
                        }
661
                    }
662
                }
663
                // Check for an alternate response URL to be used
664
                // in place of success / failure URLs.
665
                if (
666
                    preg_match(
667
                        '/cilogon_response_url=([^\s]+)/',
668
                        $output,
669
                        $matches
670
                    )
671
                ) {
672
                    $responseurl = $matches[1];
673
                }
674
            }
675
        }
676
        curl_close($ch);
677
    }
678
679
    $log = new Loggit();
680
    $log->info('Delegation of certificate to portal ' .
681
               ($success ? 'succeeded.' : 'failed.'));
682
    //CIL-507 Special log message for XSEDE
683
    $log->info('USAGE email="' . Util::getSessionVar('email') .
684
               '" client="' . Util::getSessionVar('portalname') . '"');
685
686
687
    // Depending on the result (success or failure), output appropriate
688
    // HTML to allow the user to return to the portal, or if $always
689
    // was set, then automatically return the user to the successuri,
690
    // failureuri, or cilogon_reponse_url if supplied by authorized servlet.
691
    if ($always) {
692
        $log->info("Automatically returning to portal's " .
693
            ($success ? 'success' : 'failure') . ' url.');
694
        $location = 'Location: ' . ((strlen($responseurl) > 0) ? $responseurl :
695
            (Util::getSessionVar($success ? 'successuri' : 'failureuri')));
696
        if ($success) {
697
            Util::unsetClientSessionVars();
698
            /// Util::unsetAllUserSessionVars();
699
        } else {
700
            Util::unsetAllUserSessionVars();
701
        }
702
        header($location);
703
        exit; // No further processing necessary
704
    } else {
705
        Content::printHeader('Delegation ' . ($success ? 'Successful' : 'Failed'));
706
        printOAuth1DelegationDone($success, $responseurl, $certtext);
707
        Content::printFooter();
708
        if ($success) {
709
            Util::unsetClientSessionVars();
710
        } else {
711
            Util::unsetAllUserSessionVars();
712
        }
713
    }
714
}
715
716
/**
717
 * verifyOAuthToken
718
 *
719
 * This function verifies that all of the various PortalParameters
720
 * have been set in the PHP session.  If the first parameter is passed
721
 * in, it first attempts to call CILogon::getPortalParameters() and
722
 * populates the PHP session with the associated values.
723
 *
724
 * @param string $token (Optional) The temporary credential passed from a
725
 *        Community Portal to the 'delegate' script as 'oauth_token' in the
726
 *        URL (as a $_GET variable). Defaults to empty string.
727
 * @return bool True if the various parameters related to the OAuth
728
 *         token (callbackuri, failureuri, successuri, portalname,
729
 *         and tempcred) are in the PHP session, false otherwise.
730
 */
731
function verifyOAuthToken($token = '')
732
{
733
    $retval = false; // Assume OAuth session info is not valid
734
735
    // CIL-624 If X509 certs are disabled, prevent the OAuth1 endpoint
736
    // from running since OAuth1 always generates an X.509 cert.
737
    if ((defined('DISABLE_X509')) && (DISABLE_X509 === true)) {
738
        return false;
739
    }
740
741
    // If passing in the OAuth $token, try to get the associated info
742
    // from the persistent store and put it into the PHP session.
743
    if (strlen($token) > 0) {
744
        $dbs = new DBService();
745
        $dbs->getPortalParameters($token);
746
        $status = $dbs->status;
747
        Util::setSessionVar('portalstatus', $status);
748
        if (!($status & 1)) {  // STATUS_OK* codes are even-numbered
749
            Util::setSessionVar('callbackuri', $dbs->cilogon_callback);
750
            Util::setSessionVar('failureuri', $dbs->cilogon_failure);
751
            Util::setSessionVar('successuri', $dbs->cilogon_success);
752
            Util::setSessionVar('portalname', $dbs->cilogon_portal_name);
753
            Util::setSessionVar('tempcred', $dbs->oauth_token);
754
        }
755
    }
756
757
    // Now check to verify all session variables have data
758
    if (
759
        (strlen(Util::getSessionVar('callbackuri')) > 0) &&
760
        (strlen(Util::getSessionVar('failureuri')) > 0) &&
761
        (strlen(Util::getSessionVar('successuri')) > 0) &&
762
        (strlen(Util::getSessionVar('portalname')) > 0) &&
763
        (strlen(Util::getSessionVar('tempcred')) > 0) &&
764
        (!(Util::getSessionVar('portalstatus') & 1))
765
    ) { // STATUS_OK* are even
766
        $retval = true;
767
    }
768
769
    // As a final check, see if this portal requires a forced skin
770
    if ($retval) {
771
        Util::getSkin()->init();
772
    }
773
774
    return $retval;
775
}
776