Completed
Push — master ( 5a053e...8eeafe )
by Terrence
10:16
created

index-functions.php ➔ getUserAndRespond()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 99

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 99
rs 8.0218
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.php. The index.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\OAuth2Provider;
12
use League\OAuth2\Client\Token\AccessToken;
13
14
/**
15
 * getUserAndRespond
16
 *
17
 * This function specifically handles the redirect from OAuth2 providers.
18
 * The function reads client keys/secrets from a local configuration file,
19
 * and then uses the PHP League OAuth2 client library to extract user
20
 * parameters from the HTTP response.
21
 */
22
function getUserAndRespond()
23
{
24
    $firstname = '';
25
    $lastname = '';
26
    $displayname = '';
27
    $fullname = '';
0 ignored issues
show
Unused Code introduced by
$fullname is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
28
    $emailaddr = '';
29
    $openidid = '';
30
    $oidcid = '';
31
32
    Util::unsetSessionVar('logonerror');
33
34
    $state = Util::getGetVar('state');  // 'state' must match last CSRF value
35
    $code = Util::getGetVar('code');    // 'code' must not be empty
36
    $lastcsrf = Util::getCsrf()->getTheCookie();
37
    if ($state != $lastcsrf) {
38
        // Verify that response's 'state' equals the last CSRF token
39
        Util::setSessionVar('logonerror', 'Invalid state parameter.');
40
    } elseif (strlen($code) == 0) {
41
        // Make sure the response has a non-empty 'code'
42
        $error = Util::getGetVar('error');
43
        $error_description = Util::getGetVar('error_description');
44
        if ((strlen($error) > 0) && (strlen($error_description) > 0)) {
45
            Util::setSessionVar('logonerror', $error_description . '. Please try again.');
46
        } else {
47
            Util::setSessionVar('logonerror', 'Empty code parameter. Please try again.');
48
        }
49
    } else {
50
        // When using OAuth or OIDC, check portalcookie for providerId
51
        $providerId = Util::getPortalOrNormalCookieVar('providerId');
52
        $providerName = Util::getAuthzIdP($providerId);
53
        $prov = strtolower($providerName); // IdP name all lowercase
54
55
        // Read the client secret keys from local config file
56
        $clientid     = Util::getConfigVar($prov . 'oauth2.clientid');
57
        $clientsecret = Util::getConfigVar($prov . 'oauth2.clientsecret');
58
        if ((strlen($clientid) > 0) && (strlen($clientsecret) > 0)) {
59
            $oauth2 = new OAuth2Provider($providerName);
60
            try {
61
                $token = $oauth2->provider->getAccessToken(
62
                    'authorization_code',
63
                    [ 'code' => $code ]
64
                );
65
                $user = $oauth2->provider->getResourceOwner($token);
66
                $oidcid = $user->getId();
67
                $emailaddr = $user->getEmail();
68
                // GitHub email may require special handling
69
                if ((strlen($emailaddr) == 0) && ($prov == 'github')) {
70
                    $emailaddr = getGitHubEmail($oauth2, $token);
71
                }
72
                $name = $user->getName();
73
                $first = '';
74
                $last = '';
75
                if ($prov != 'github') { // No first/last for GitHub
76
                    $first = $user->getFirstName();
77
                    $last = $user->getLastName();
78
                }
79
                list($firstname, $lastname) =
80
                    Util::getFirstAndLastName($name, $first, $last);
81
            } catch (Exception $e) {
82
                Util::setSessionVar('logonerror', $e->getMessage());
83
            }
84
        } else {
85
            Util::setSessionVar(
86
                'logonerror',
87
                'Missing OAuth2 client configuration values.'
88
            );
89
        }
90
    }
91
92
    // If no error reported, check for session var 'storeattributes'
93
    // which indicates to simply store the user attributes in the
94
    // PHP session. If not set, then by default save the user
95
    // attributes to the database (which also stores the user
96
    // attributes in the PHP session).
97
    if (strlen(Util::getSessionVar('logonerror')) == 0) {
98
        $func = 'CILogon\Service\Util::saveUserToDataStore';
99
        if (!empty(Util::getSessionVar('storeattributes'))) {
100
            $func = 'CILogon\Service\Util::setUserAttributeSessionVars';
101
            Util::unsetSessionVar('storeattributes');
102
        }
103
        $func(
104
            $openidid,
105
            $providerId,
0 ignored issues
show
Bug introduced by
The variable $providerId does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
106
            $providerName,
0 ignored issues
show
Bug introduced by
The variable $providerName does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
107
            $firstname,
108
            $lastname,
109
            $displayname,
110
            $emailaddr,
111
            'openid',
112
            '', // ePPN
113
            '', // ePTID
114
            $openidid,
115
            $oidcid
116
        );
117
    } else {
118
        Util::unsetSessionVar('submit');
119
    }
120
}
121
122
/**
123
 * getGitHubEmail
124
 *
125
 * This function gets a GitHub user email address from the special
126
 * user email API endpoint. It returns an email address that is marked
127
 * as 'primary' by GitHub.
128
 *
129
 * @param OAuth2Provider An exsiting OAuth2Provider object
130
 * @param League\OAuth2\Client\Token\AccessToken An oauth2 token
131
 * @return string A GitHub user's primary email address, or empty string
132
 *         if no such email address exists.
133
 */
134
function getGitHubEmail($oauth2, $token)
135
{
136
    $oauth2_email = '';
137
138
    $request = $oauth2->provider->getAuthenticatedRequest(
139
        'GET',
140
        'https://api.github.com/user/emails',
141
        $token
142
    );
143
    $github_emails = json_decode(
144
        $oauth2->provider->getResponse($request)->getBody()
145
    );
146
147
    foreach ($github_emails as $email) {
148
        if ($email->primary == 1) {
149
            $oauth2_email = $email->email;
150
            break;
151
        }
152
    }
153
154
    return $oauth2_email;
155
}
156