Skip to content

Commit

Permalink
Parse EU Access attributes.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 7, 2020
1 parent 8609b79 commit 44cc7dc
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public function it_can_load_a_user_from_a_response(ResponseInterface $response)
<cas:group>group1</cas:group>
<cas:group>group2</cas:group>
</cas:groups>
<cas:extendedAttributes>
<cas:extendedAttribute name="http://stork.eu/motherInLawDogName">
<cas:attributeValue>rex</cas:attributeValue>
<cas:attributeValue>snoopy</cas:attributeValue>
</cas:extendedAttribute>
</cas:extendedAttributes>
</cas:authenticationSuccess>
</cas:serviceResponse>
EOF;
Expand All @@ -77,11 +83,17 @@ public function it_can_load_a_user_from_a_response(ResponseInterface $response)
'group2',
],
],
'extendedAttributes' => [
'http://stork.eu/motherInLawDogName' => [
'rex',
'snoopy',
],
],
]);

$this
->loadUserByResponse($response)
->getUser()
->getUsername()
->shouldReturn('username');

$this
Expand All @@ -92,6 +104,17 @@ public function it_can_load_a_user_from_a_response(ResponseInterface $response)
'group2',
'ROLE_CAS_AUTHENTICATED',
]);

$this->loadUserByResponse($response)
->getExtendedAttributes()
->shouldReturn(
[
'http://stork.eu/motherInLawDogName' => [
'rex',
'snoopy',
],
]
);
}

public function it_can_refresh_a_user(EuLoginUserInterface $user)
Expand Down
160 changes: 112 additions & 48 deletions spec/EcPhp/EuLoginBundle/Security/Core/User/EuLoginUserSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,47 @@

use EcPhp\CasBundle\Security\Core\User\CasUser;
use EcPhp\CasBundle\Security\Core\User\CasUserInterface;
use EcPhp\CasLib\Introspection\Introspector;
use EcPhp\EuLoginBundle\Security\Core\User\EuLoginUser;
use Nyholm\Psr7\Response;
use PhpSpec\ObjectBehavior;

class EuLoginUserSpec extends ObjectBehavior
{
public function it_can_get_groups_when_no_groups_are_available()
{
$attributes = $this->getAttributesData();
unset($attributes['groups']);

$data = [
'user' => 'user',
'proxyGrantingTicket' => 'proxyGrantingTicket',
'proxies' => [
'proxy1',
],
'attributes' => $attributes,
];
$body = <<<'EOF'
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:authenticationSuccess>
<cas:user>username</cas:user>
<cas:foo>bar</cas:foo>
<cas:proxies>
<cas:proxy>foo</cas:proxy>
</cas:proxies>
<cas:attributes>
<cas:groups number="10">
<cas:group>group1</cas:group>
<cas:group>group2</cas:group>
</cas:groups>
<cas:extendedAttributes>
<cas:extendedAttribute name="http://stork.eu/motherInLawDogName">
<cas:attributeValue>rex</cas:attributeValue>
<cas:attributeValue>snoopy</cas:attributeValue>
</cas:extendedAttribute>
</cas:extendedAttributes>
</cas:attributes>
</cas:authenticationSuccess>
</cas:serviceResponse>
EOF;

$response = new Response(200, ['Content-Type' => 'application/xml'], $body);
$data = (new Introspector())->parse($response)['serviceResponse']['authenticationSuccess'];
unset($data['attributes']['groups']);

$casUser = new CasUser($data);

$this
->beConstructedWith(new CasUser($data));
->beConstructedWith($casUser);

$this
->getGroups()
Expand All @@ -37,11 +57,11 @@ public function it_can_get_specific_attribute()
{
$this
->getAssuranceLevel()
->shouldReturn('assuranceLevel');
->shouldReturn('40');

$this
->getAuthenticationFactors()
->shouldReturn(['foobar']);
->shouldReturn(['ecphp@ec.europa.eu']);

$this
->getDepartmentNumber()
Expand Down Expand Up @@ -73,7 +93,10 @@ public function it_can_get_specific_attribute()

$this
->getGroups()
->shouldReturn(['foo']);
->shouldReturn([
'group1',
'group2',
]);

$this
->getLastName()
Expand Down Expand Up @@ -114,28 +137,14 @@ public function it_can_get_specific_attribute()
$this
->getUid()
->shouldReturn('uid');

$this
->getAttributes()
->shouldReturn($this->getAttributesData());
}

public function it_can_get_the_attributes_only(CasUserInterface $user)
{
$data = [
'user' => 'user',
'proxyGrantingTicket' => 'proxyGrantingTicket',
'proxies' => [
'proxy1',
],
'attributes' => $this->getAttributesData(),
];

$user
->getAttributes()
->willReturn($this->getAttributesData());

$user
->beConstructedWith($data);
$this
->beConstructedWith($user);

$this
->getAttributes()
->shouldReturn($this->getAttributesData());
Expand All @@ -148,26 +157,64 @@ public function it_is_initializable()

public function let(CasUserInterface $user)
{
$data = [
'user' => 'user',
'proxyGrantingTicket' => 'proxyGrantingTicket',
'proxies' => [
'proxy1',
],
'attributes' => $this->getAttributesData(),
];
$body = <<<'EOF'
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
<cas:authenticationSuccess>
<cas:user>username</cas:user>
<cas:foo>bar</cas:foo>
<cas:proxies>
<cas:proxy>foo</cas:proxy>
</cas:proxies>
<cas:attributes>
<cas:authenticationFactors>
<cas:moniker number="1">
ecphp@ec.europa.eu
</cas:moniker>
</cas:authenticationFactors>
<cas:assuranceLevel>40</cas:assuranceLevel>
<cas:groups number="10">
<cas:group>group1</cas:group>
<cas:group>group2</cas:group>
</cas:groups>
<cas:extendedAttributes>
<cas:extendedAttribute name="http://stork.eu/motherInLawDogName">
<cas:attributeValue>rex</cas:attributeValue>
<cas:attributeValue>snoopy</cas:attributeValue>
</cas:extendedAttribute>
</cas:extendedAttributes>
</cas:attributes>
</cas:authenticationSuccess>
</cas:serviceResponse>
EOF;

$response = new Response(200, ['Content-Type' => 'application/json'], $body);
$data = (new Introspector())->parse($response)['serviceResponse']['authenticationSuccess'];

$user
->beConstructedWith($data);

$user
->getAttribute('extendedAttributes', [])
->willReturn([
'extendedAttribute' => [
'attributeValue' => [
'value1',
'value2',
],
'@attributes' => [
'name' => 'attr1',
],
],
]);

$user
->getAttribute('assuranceLevel')
->willReturn('assuranceLevel');
->willReturn($data['attributes']['assuranceLevel']);

$user
->getAttribute('authenticationFactors', [])
->willReturn([
'foobar',
'ecphp@ec.europa.eu',
]);

$user
Expand Down Expand Up @@ -199,9 +246,15 @@ public function let(CasUserInterface $user)
->willReturn('firstName');

$user
->getAttribute('groups', [])
->getAttribute('groups', ['group' => []])
->willReturn([
'foo',
'group' => [
'group1',
'group2',
],
'@attributes' => [
'number' => 2,
],
]);

$user
Expand Down Expand Up @@ -246,6 +299,10 @@ public function let(CasUserInterface $user)
->getAttribute('uid')
->willReturn('uid');

$user
->getAttributes()
->willReturn($this->getAttributesData());

$this
->beConstructedWith($user);
}
Expand All @@ -257,24 +314,31 @@ private function getAttributesData(): array
'email' => 'email',
'employeeNumber' => 'employeeNumber',
'employeeType' => 'employeeType',
'extendedAttributes' => [
'attr1' => [
'value1',
'value2',
],
],
'firstName' => 'firstName',
'lastName' => 'lastName',
'domain' => 'domain',
'domainUsername' => 'domainUsername',
'telephoneNumber' => 'telephoneNumber',
'locale' => 'locale',
'assuranceLevel' => 'assuranceLevel',
'assuranceLevel' => '40',
'uid' => 'uid',
'orgId' => 'orgId',
'teleworkingPriority' => 'teleworkingPriority',
'groups' => [
'foo',
'group1',
'group2',
],
'strengths' => [
'bar',
],
'authenticationFactors' => [
'foobar',
'ecphp@ec.europa.eu',
],
'loginDate' => 'loginDate',
'sso' => 'sso',
Expand Down
32 changes: 19 additions & 13 deletions src/Security/Core/User/EuLoginUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
namespace EcPhp\EuLoginBundle\Security\Core\User;

use EcPhp\CasBundle\Security\Core\User\CasUserInterface;

use function array_key_exists;
use function is_array;
use loophp\collection\Collection;

final class EuLoginUser implements EuLoginUserInterface
{
Expand All @@ -16,9 +14,6 @@ final class EuLoginUser implements EuLoginUserInterface
*/
private $user;

/**
* EuLoginUser constructor.
*/
public function __construct(CasUserInterface $user)
{
$this->user = $user;
Expand Down Expand Up @@ -61,7 +56,10 @@ public function getAttribute(string $key, $default = null)
*/
public function getAttributes(): array
{
return $this->user->getAttributes();
$attributes = $this->user->getAttributes();
$attributes['extendedAttributes'] = $this->getExtendedAttributes();

return $attributes;
}

/**
Expand Down Expand Up @@ -120,6 +118,18 @@ public function getEmployeeType(): ?string
return $this->user->getAttribute('employeeType');
}

public function getExtendedAttributes(): array
{
return Collection::fromIterable($this->user->getAttribute('extendedAttributes', []))
->map(
static function (array $item): array {
return [$item['@attributes']['name'] => $item['attributeValue']];
}
)
->unwrap()
->all();
}

/**
* {@inheritdoc}
*/
Expand All @@ -133,7 +143,7 @@ public function getFirstName(): ?string
*/
public function getGroups(): array
{
return $this->user->getAttribute('groups', []);
return $this->user->getAttribute('groups', ['group' => []])['group'];
}

/**
Expand Down Expand Up @@ -191,11 +201,7 @@ public function getRoles()
{
$default = ['ROLE_CAS_AUTHENTICATED'];

if (([] !== $roles = $this->getGroups()) && (array_key_exists('group', $roles) && is_array($roles['group']))) {
return array_merge($roles['group'], $default);
}

return $default;
return array_merge($this->getGroups(), $default);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Security/Core/User/EuLoginUserInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public function getEmployeeNumber(): ?string;

public function getEmployeeType(): ?string;

public function getExtendedAttributes(): array;

public function getFirstName(): ?string;

/**
Expand Down

0 comments on commit 44cc7dc

Please sign in to comment.