Closed nickjer closed 7 years ago
Interesting.
The issue is with this code in display_login_form
function:
$provider_claims = array_filter(array(
"Name" => $_SERVER["OIDC_CLAIM_idp_name"],
"Login ID" => $_SERVER["OIDC_CLAIM_eppn"],
"Login User" => $_SERVER["OIDC_CLAIM_name"],
"Login Email" => $_SERVER["OIDC_CLAIM_email"]
));
In the version of PHP we are using, if OIDC_CLAIM_name
doesn't exist, $_SERVER["OIDC_CLAIM_name"]
is null, so when I log in with an OH-TECH account, this ends up being:
$provider_claims = array_filter(array(
"Name" => "Ohio Technology Consortium (OH-TECH)",
"Login ID" => "efranz@oar.net",
"Login User" => null,
"Login Email" => "efranz@osc.edu"
));
And array_filter without any extra arguments will filter out all the key value pairs where the value is null. So we end up with:
$provider_claims = array(
"Name" => "Ohio Technology Consortium (OH-TECH)",
"Login ID" => "efranz@oar.net",
"Login Email" => "efranz@osc.edu"
);
I can still navigate to register but do not see an error displayed. So the user doesn't experience a crash, though the log file gets this PHP Notice: Undefined index:
. Perhaps I should use another method to get the value that is more intentional about being okay with an undefined index.
From http://php.net/manual/en/language.types.array.php
Note: Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an E_NOTICE-level error message will be issued, and the result will be NULL.
Is there an equivalent fetch
method in PHP?
I haven't found it yet. @basilgohar do you know of one off the top of your head? or else I'll accomplish this some other way; perhaps:
$provider_claim_display_fields = array(
"Name" => "OIDC_CLAIM_idp_name",
"Login ID" => "OIDC_CLAIM_eppn",
"Login User" => "OIDC_CLAIM_name",
"Login Email" => "OIDC_CLAIM_email"
);
$provider_claims = array();
foreach($provider_claim_display_fields as $k => $v){
if(array_key_exists($v, $_SERVER)){
$provider_claims[$k] = $_SERVER[$v]
}
}
@brianmcmichael my last comment here shows a solution. This is to avoid warnings being posted.
What about setting defaults with the ternary shorthand?
$provider_claims = array_filter(array(
"Name" => $_SERVER["OIDC_CLAIM_idp_name"] ?: "Undefined",
"Login ID" => $_SERVER["OIDC_CLAIM_eppn"] ?: "Undefined",
"Login User" => $_SERVER["OIDC_CLAIM_name"] ?: "Undefined",
"Login Email" => $_SERVER["OIDC_CLAIM_email"] ?: "Undefined"
));
I'm not sure how to test this in production. Seems to work on commandline.
bmcmichael@webdev02:~$ php -a
Interactive shell
php > $provider_claims = array_filter(array(
php ( "Name" => $_SERVER["OIDC_CLAIM_idp_name"] ?: "Undefined",
php ( "Login ID" => $_SERVER["OIDC_CLAIM_eppn"] ?: "Undefined",
php ( "Login User" => $_SERVER["OIDC_CLAIM_name"] ?: "Undefined",
php ( "Login Email" => $_SERVER["OIDC_CLAIM_email"] ?: "Undefined"
php ( ));
PHP Notice: Undefined index: OIDC_CLAIM_idp_name in php shell code on line 2
PHP Notice: Undefined index: OIDC_CLAIM_eppn in php shell code on line 3
PHP Notice: Undefined index: OIDC_CLAIM_name in php shell code on line 4
PHP Notice: Undefined index: OIDC_CLAIM_email in php shell code on line 5
php > print_r($provider_claims);
Array
(
[Name] => Undefined
[Login ID] => Undefined
[Login User] => Undefined
[Login Email] => Undefined
)
php >
Disregard the last message, I see you want to get rid of the undefined index warnings.
What about this? Seems a little simpler:
function serverFetch($key) {
return isset($_SERVER[$key]) ? $_SERVER[$key] : $key;
}
$provider_claims = array_filter(array(
"Name" => serverFetch("OIDC_CLAIM_idp_name"),
"Login ID" => serverFetch("OIDC_CLAIM_eppn"),
"Login User" => serverFetch("OIDC_CLAIM_name"),
"Login Email" => serverFetch("OIDC_CLAIM_email")
));
Result:
php > function serverFetch($key) {
php { return isset($_SERVER[$key]) ? $_SERVER[$key] : $key;
php { }
php >
php > $provider_claims = array_filter(array(
php ( "Name" => serverFetch("OIDC_CLAIM_idp_name"),
php ( "Login ID" => serverFetch("OIDC_CLAIM_eppn"),
php ( "Login User" => serverFetch("OIDC_CLAIM_name"),
php ( "Login Email" => serverFetch("OIDC_CLAIM_email")
php ( ));
php > print_r($provider_claims);
Array
(
[Name] => OIDC_CLAIM_idp_name
[Login ID] => OIDC_CLAIM_eppn
[Login User] => OIDC_CLAIM_name
[Login Email] => OIDC_CLAIM_email
)
php >
If you do that we would want this:
function serverFetch($key, $default = NULL) {
return isset($_SERVER[$key]) ? $_SERVER[$key] : $default;
}
The reason is that the whole point is to filter out claims values that are not set. This way if OIDC_CLAIM_idp_name and OIDC_CLAIM_eppn are the only values set you would end up with:
$provider_claims = array_filter(array(
"Name" => serverFetch("OIDC_CLAIM_idp_name"),
"Login ID" => serverFetch("OIDC_CLAIM_eppn"),
"Login User" => serverFetch("OIDC_CLAIM_name"),
"Login Email" => serverFetch("OIDC_CLAIM_email")
));
# => call serverFetch
$provider_claims = array_filter(array(
"Name" => "Google",
"Login ID" => "efranzosc@google.com",
"Login User" => NULL,
"Login Email" => NULL
));
# = > call array_filter:
$provider_claims = array(
"Name" => "Google",
"Login ID" => "efranzosc@google.com"
);
Sorry - automated tests would have helped here.
Ok, so no errors, and no undefined keys.
FWIW these are similar in length:
serverFetch("OIDC_CLAIM_idp_name")
fetch($_SERVER, "OIDC_CLAIM_idp_name")
I'd vote for the second, as its pretty clear without looking at the implementation of fetch what it does, especially coming from Ruby.
To clarify, this isn't really a bug, just a nuisance. The log file claims its an [error] but its really just an annoying warning PHP Notice: Undefined index
.
I didn't want to do that because it's specific to the $_SERVER
variable here, and should not be confused with similar functionality on a $_GET
or $_POST
request.
It was also a safeguard because I didn't want to override any existing functionality in php.
Oh, I see, you are passing in the $_SERVER
, so we're making a general fetch()
method.
Yep. There is no fetch
function in PHP
I was just going to scope this to the method. But it can probably be more general if we think it's going to be used elsewhere.
I see this for an unmapped user who logged in from the Ohio Technology Consortium through CILogon: