Completed
Push — master ( 720d6c...037e93 )
by Terrence
15:17 queued 12s
created

index-functions.php ➔ getUID()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 8
nop 0
dl 0
loc 52
rs 9.0472
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\Content;
12
use CILogon\Service\DBService;
13
use CILogon\Service\MyProxy;
14
use CILogon\Service\Loggit;
15
16
/**
17
 * getUID
18
 *
19
 * This function takes all of the various required SAML attributes (as
20
 * set in the current Shibboleth session) and makes a call to the
21
 * database (via the dbservice) to get the userid assoicated with
22
 * those attributes.  It sets several PHP session variables such as the
23
 * status code returned by the dbservice, the uid (if found), the
24
 * username to be passed to MyProxy ('distinguished_name'), etc.  If
25
 * there is some kind of error with the database call, an email is
26
 * sent showing which SAML attributes were missing.
27
 *
28
 * All 'returned' variables are stored in various  PHP session variables
29
 * (e.g. 'user_uid', 'distinguished_name', 'status').
30
 */
31
function getUID()
32
{
33
    $shibarray = Util::getIdpList()->getShibInfo();
34
35
    // Don't allow Organization Name to be empty
36
    if (strlen(@$shibarray['Organization Name']) == 0) {
37
        $shibarray['Organization Name'] = 'Unspecified';
38
    }
39
40
    // Extract Silver Level of Assurance from Shib-AuthnContext-Class
41
    if (
42
        preg_match(
43
            '%http://id.incommon.org/assurance/silver%',
44
            Util::getServerVar('Shib-AuthnContext-Class')
45
        )
46
    ) {
47
        $shibarray['Level of Assurance'] =
48
            'http://incommonfederation.org/assurance/silver';
49
    }
50
51
    // Check for session var 'storeattributes' which indicates to
52
    // simply store the user attributes in the PHP session.
53
    // If not set, then by default save the user attributes to
54
    // the database (which also stores the user attributes in
55
    // the PHP session).
56
    $func = 'CILogon\Service\Util::saveUserToDataStore';
57
    if (!empty(Util::getSessionVar('storeattributes'))) {
58
        $func = 'CILogon\Service\Util::setUserAttributeSessionVars';
59
    }
60
    $func(
61
        @$shibarray['User Identifier'],
62
        @$shibarray['Identity Provider'],
63
        @$shibarray['Organization Name'],
64
        @$shibarray['First Name'],
65
        @$shibarray['Last Name'],
66
        @$shibarray['Display Name'],
67
        @$shibarray['Email Address'],
68
        @$shibarray['Level of Assurance'],
69
        @$shibarray['ePPN'],
70
        @$shibarray['ePTID'],
71
        '', // OpenID 2.0 ID
72
        '', // OpenID Connect ID
73
        @$shibarray['Subject ID'],
74
        @$shibarray['Pairwise ID'],
75
        @$shibarray['Affiliation'],
76
        @$shibarray['OU'],
77
        @$shibarray['Member'],
78
        @$shibarray['Authn Context'],
79
        @$shibarray['Entitlement'],
80
        @$shibarray['iTrustUIN']
81
    );
82
}
83
84
/**
85
 * getUserAndRespond
86
 *
87
 * This function gets the user's database UID puts several variables
88
 * in the current PHP session, and responds by redirecting to the
89
 * responseurl in the passed-in parameter.  If there are any issues
90
 * with the database call, an email is sent to the CILogon admins.
91
 *
92
 * @param string $responseurl The full URL to redirect to after getting
93
 *        the userid.
94
 */
95
function getUserAndRespond($responseurl)
0 ignored issues
show
Best Practice introduced by
The function getUserAndRespond() has been defined more than once; this definition is ignored, only the first definition in getuser/index-functions.php (L22-116) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
96
{
97
    getUID(); // Get the user's database user ID, put info in PHP session
98
99
    // Finally, redirect to the calling script.
100
    header('Location: ' . $responseurl);
101
    exit; // No further processing necessary
102
}
103
104
/**
105
 * getPKCS12
106
 *
107
 * This function is called when an ECP client wants to get a PKCS12
108
 * credential.  It first attempts to get the user's database UID. If
109
 * successful, it tries to create a PKCS12 file on disk by calling
110
 * MyProxy.  If successful, it returns the PKCS12 file by setting the
111
 * HTTP Content-type.  If there is an error, it returns a plain text
112
 * file and sets the HTTP response code to an error code.
113
 */
114
function getPKCS12()
115
{
116
    $log = new Loggit();
117
118
    getUID(); // Get the user's database user ID, put info in PHP session
119
120
    $skin = Util::getSkin();
121
    $skin->init(); // Check for forced skin
122
123
    // If 'status' is not STATUS_OK*, then return error message
124
    if (Util::getSessionVar('status') & 1) { // Bad status codes are odd
125
        $errstr = array_search(Util::getSessionVar('status'), DBService::$STATUS);
126
        $log->info('ECP PKCS12 error: ' . $errstr . '.');
127
        outputError($errstr);
128
        Util::unsetAllUserSessionVars();
129
        return; // ERROR means no further processing is necessary
130
    }
131
132
    // Verify myproxy-logon binary is configured
133
    $disabledbyconf = ((!defined('MYPROXY_LOGON')) || (empty(MYPROXY_LOGON)));
134
    if ($disabledbyconf) {
135
        $log->info('ECP PKCS12 error: Downloading certificates is ' .
136
            'disabled due to myproxy-logon not configured.');
137
        outputError('Downloading certificates is disabled.');
138
        Util::unsetAllUserSessionVars();
139
        return; // ERROR means no further processing is necessary
140
    }
141
142
    $shibarray = Util::getIdpList()->getShibInfo();
143
    if (Util::isEduGAINAndGetCert(@$shibarray['Identity Provider'], @$shibarray['Organization Name'])) {
144
        $log->info('ECP PKCS12 error: Failed to get cert due to eduGAIN IdP restriction.');
145
        outputError('Failed to get cert due to eduGAIN IdP restriction.');
146
        return; // ERROR means no further processing is necessary
147
    }
148
149
    $skin->setMyProxyInfo();
150
    Content::generateP12();  // Try to create the PKCS12 credential file on disk
151
152
    // Look for the p12error PHP session variable. If set, return it.
153
    $p12error = Util::getSessionVar('p12error');
154
    if (strlen($p12error) > 0) {
155
        $log->info('ECP PKCS12 error: ' . $p12error);
156
        outputError($p12error);
157
    } else { // Try to read the .p12 file from disk and return it
158
        $p12 = Util::getSessionVar('p12');
159
        $p12expire = '';
160
        $p12link = '';
161
        $p12file = '';
162
        if (preg_match('/([^\s]*)\s(.*)/', $p12, $match)) {
163
            $p12expire = $match[1];
164
            $p12link = $match[2];
165
        }
166
        if ((strlen($p12link) > 0) && (strlen($p12expire) > 0)) {
167
            $p12file = file_get_contents($p12link);
168
        }
169
170
        if (strlen($p12file) > 0) {
171
            $log->info('ECP PKCS12 success!');
172
            // CIL-507 Special log message for XSEDE
173
            $log->info('USAGE email="' . Util::getSessionVar('email') .
174
                       '" client="ECP"');
175
            header('Content-type: application/x-pkcs12');
176
            echo $p12file;
177
        } else {
178
            $log->info('ECP PKCS12 error: Missing or empty PKCS12 file.');
179
            outputError('Missing or empty PKCS12 file.');
180
        }
181
    }
182
}
183
184
/**
185
 * getCert
186
 *
187
 * This function is called when an ECP client wants to get a PEM-
188
 * formatted X.509 certificate by inputting a certificate request
189
 * generated by 'openssl req'.  It first attempts to get the user's
190
 * database UID. If successful, it calls out to myproxy-logon to get
191
 * a certificate. If successful, it returns the certificate by setting
192
 * the HTTP Content-type to 'text/plain'.  If there is an error, it
193
 * returns a plain text file and sets the HTTP response code to an
194
 * error code.
195
 */
196
function getCert()
197
{
198
    $log = new Loggit();
199
200
    // Verify that a non-empty certreq <form> variable was posted
201
    $certreq = Util::getPostVar('certreq');
202
    if (strlen($certreq) == 0) {
203
        $log->info('ECP certreq error: Missing certificate request.');
204
        outputError('Missing certificate request.');
205
        return; // ERROR means no further processing is necessary
206
    }
207
208
    getUID(); // Get the user's database user ID, put info in PHP session
209
210
    $skin = Util::getSkin();
211
    $skin->init(); // Check for forced skin
212
213
    // If 'status' is not STATUS_OK*, then return error message
214
    if (Util::getSessionVar('status') & 1) { // Bad status codes are odd
215
        $errstr = array_search(Util::getSessionVar('status'), DBService::$STATUS);
216
        $log->info('ECP certreq error: ' . $errstr . '.');
217
        outputError($errstr);
218
        Util::unsetAllUserSessionVars();
219
        return; // ERROR means no further processing is necessary
220
    }
221
    //
222
    // Verify myproxy-logon binary is configured
223
    $disabledbyconf = ((!defined('MYPROXY_LOGON')) || (empty(MYPROXY_LOGON)));
224
    if ($disabledbyconf) {
225
        $log->info('ECP certreq error: Downloading certificates is ' .
226
            'disabled due to myproxy-logon not configured.');
227
        outputError('Downloading certificates is disabled.');
228
        Util::unsetAllUserSessionVars();
229
        return; // ERROR means no further processing is necessary
230
    }
231
232
    $shibarray = Util::getIdpList()->getShibInfo();
233
    if (Util::isEduGAINAndGetCert(@$shibarray['Identity Provider'], @$shibarray['Organization Name'])) {
234
        $log->info('ECP certreq error: Failed to get cert due to eduGAIN IdP restriction.');
235
        outputError('Failed to get cert due to eduGAIN IdP restriction.');
236
        return; // ERROR means no further processing is necessary
237
    }
238
239
    // Get the certificate lifetime. Set to a default value if not set.
240
    $certlifetime = (int)(Util::getPostVar('certlifetime'));
241
    if ($certlifetime == 0) {  // If not specified, set to default value
242
        $defaultlifetime = $skin->getConfigOption('ecp', 'defaultlifetime');
243
        if ((!is_null($defaultlifetime)) && ((int)$defaultlifetime > 0)) {
244
            $certlifetime = (int)$defaultlifetime;
245
        } else {
246
            $certlifetime = MyProxy::getDefaultLifetime();
247
        }
248
    }
249
250
    // Make sure lifetime is within acceptable range. 277 hrs = 1000000 secs.
251
    list($minlifetime, $maxlifetime) = Util::getMinMaxLifetimes('ecp', 277);
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...
252
    if ($certlifetime < $minlifetime) {
253
        $certlifetime = $minlifetime;
254
    } elseif ($certlifetime > $maxlifetime) {
255
        $certlifetime = $maxlifetime;
256
    }
257
258
    // Make sure that the user's MyProxy username is available.
259
    $dn = Util::getSessionVar('distinguished_name');
260
    if (strlen($dn) > 0) {
261
        // Append extra info, such as 'skin', to be processed by MyProxy.
262
        $skin->setMyProxyInfo();
263
        $myproxyinfo = Util::getSessionVar('myproxyinfo');
264
        if (strlen($myproxyinfo) > 0) {
265
            $dn .= " $myproxyinfo";
266
        }
267
        // Attempt to fetch a credential from the MyProxy server
268
        $cert = MyProxy::getMyProxyCredential(
269
            $dn,
270
            '',
271
            MYPROXY_HOST,
272
            Util::getLOAPort(),
0 ignored issues
show
Bug introduced by
The method getLOAPort() 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...
273
            $certlifetime,
274
            '/var/www/config/hostcred.pem',
275
            '',
276
            $certreq
277
        );
278
279
        if (strlen($cert) > 0) { // Successfully got a certificate!
280
            $log->info('ECP getcert success!');
281
            // CIL-507 Special log message for XSEDE
282
            $log->info('USAGE email="' . Util::getSessionVar('email') .
283
                       '" client="ECP"');
284
            header('Content-type: text/plain');
285
            echo $cert;
286
        } else { // The myproxy-logon command failed - shouldn't happen!
287
            $log->info('ECP certreq error: MyProxy unable to create certificate.');
288
            outputError('Error! MyProxy unable to create certificate.');
289
        }
290
    } else { // Couldn't find the 'distinguished_name' PHP session value
291
        $log->info('ECP certreq error: Missing \'distinguished_name\' session value.');
292
        outputError('Cannot create certificate due to missing attributes.');
293
    }
294
}
295
296
/**
297
 * outputError
298
 *
299
 * This function sets the HTTP return type to 'text/plain' and also
300
 * sets the HTTP return code to 400, meaning there was an error of
301
 * some kind.  If there is also a passed in errstr, that is output as
302
 * the body of the HTTP return.
303
 * @param string $errstr (Optional) The error string to print in the
304
 *        text/plain return body.
305
 */
306
function outputError($errstr = '')
307
{
308
    header('Content-type: text/plain', true, 400);
309
    if (strlen($errstr) > 0) {
310
        echo $errstr;
311
    }
312
}
313