Skip to content

Commit 9cdf8e1

Browse files
authored
remove extra values from shib attributes (#308)
* remove extra values from shib attributes typo * add comment * throw SSOException, require attributes not empty * add test * fix test, move from functional to unit
1 parent cf03cc3 commit 9cdf8e1

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

resources/lib/UnitySSO.php

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,44 @@ private static function eppnToOrg($eppn)
2626
return strtolower($org);
2727
}
2828

29+
// shibboleth service provider writes attributes into "server variables"
30+
// shibboleth service provider does not garuntee attributes are set, even REMOTE_USER
31+
// https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2065335257/AttributeAccess
32+
// I have observed attributes to be set to empty strings while shibd complains of bad config
33+
private static function getAttributeRaw($attributeName, $fallbackAttributeName = null)
34+
{
35+
if (isset($_SERVER[$attributeName]) && $_SERVER[$attributeName] != "") {
36+
return $_SERVER[$attributeName];
37+
}
38+
if (is_null($fallbackAttributeName)) {
39+
throw new SSOException("\$_SERVER[\"$attributeName\"] is unset or empty!");
40+
}
41+
if (isset($_SERVER[$fallbackAttributeName]) && $_SERVER[$fallbackAttributeName] != "") {
42+
return $_SERVER[$fallbackAttributeName];
43+
}
44+
throw new SSOException(
45+
"\$_SERVER[\"$attributeName\"] and \$_SERVER[\"$fallbackAttributeName\"]"
46+
. " are both unset or empty!"
47+
);
48+
}
49+
50+
private static function getAttribute($attributeName, $fallbackAttributeName = null)
51+
{
52+
$attribute_raw = self::getAttributeRaw($attributeName, $fallbackAttributeName);
53+
// attributes may have multiple values, by default they are split by ';'
54+
// see SPConfig setting attributeValueDelimiter
55+
return explode(";", $attribute_raw)[0];
56+
}
57+
2958
public static function getSSO()
3059
{
3160
return array(
32-
"user" => self::eppnToUID($_SERVER["REMOTE_USER"]),
33-
"org" => self::eppnToOrg($_SERVER["REMOTE_USER"]),
34-
"firstname" => $_SERVER["givenName"],
35-
"lastname" => $_SERVER["sn"],
36-
"name" => $_SERVER["givenName"] . " " . $_SERVER["sn"],
37-
"mail" => isset($_SERVER["mail"]) ? $_SERVER["mail"] : $_SERVER["eppn"]
61+
"user" => self::eppnToUID(self::getAttribute("REMOTE_USER")),
62+
"org" => self::eppnToOrg(self::getAttribute("REMOTE_USER")),
63+
"firstname" => self::getAttribute("givenName"),
64+
"lastname" => self::getAttribute("sn"),
65+
"name" => self::getAttribute("givenName") . " " . self::getAttribute("sn"),
66+
"mail" => self::getAttribute("mail", "eppn")
3867
);
3968
}
4069
}

test/phpunit-bootstrap.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,23 @@ function getNonExistentUserAndExpectedUIDGIDWithCustomMapping()
196196
return [["[email protected]", "foo", "bar", "[email protected]"], 555];
197197
}
198198

199+
function getMultipleValueAttributesAndExpectedSSO()
200+
{
201+
return [
202+
[
203+
"REMOTE_USER" => "[email protected]",
204+
"givenName" => "foo;foo",
205+
"sn" => "bar;bar",
206+
207+
],
208+
[
209+
"firstname" => "foo",
210+
"lastname" => "bar",
211+
"mail" => "[email protected]",
212+
]
213+
];
214+
}
215+
199216
function getAdminUser()
200217
{
201218
return ["[email protected]", "foo", "bar", "[email protected]"];

test/unit/UnitySSOTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace UnityWebPortal\lib;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
class UnitySSOTest extends TestCase
8+
{
9+
public function testMultipleAttributeValues()
10+
{
11+
$PREVIOUS_SERVER = $_SERVER;
12+
$two_vars = getMultipleValueAttributesAndExpectedSSO();
13+
$attributes = $two_vars[0];
14+
$expectedSSO = $two_vars[1];
15+
try {
16+
$_SERVER = array_merge($_SERVER, $attributes);
17+
$sso = UnitySSO::getSSO();
18+
$this->assertEquals($expectedSSO["firstname"], $sso["firstname"]);
19+
$this->assertEquals($expectedSSO["lastname"], $sso["lastname"]);
20+
$this->assertEquals($expectedSSO["mail"], $sso["mail"]);
21+
} finally {
22+
$_PREVIOUS_SERVER = $_SERVER;
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)