Skip to content
This repository has been archived by the owner on Apr 6, 2021. It is now read-only.

Commit

Permalink
Merge pull request lightSAML#36 from denniscoorn/feature/simple-attri…
Browse files Browse the repository at this point in the history
…bute-mapper

Added a SimpleAttributeMapper
  • Loading branch information
tmilos authored Jan 16, 2017
2 parents 4a62c9d + ce1a4cf commit 79b329c
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ before_install:
- echo "session.gc_probability = 0" >> $INI_FILE
- composer self-update
- composer --version
- wget http://get.sensiolabs.org/php-cs-fixer.phar -O php-cs-fixer.phar
- wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v1.12.3/php-cs-fixer.phar -O php-cs-fixer.phar

install:
- COMPOSER_ROOT_VERSION=dev-master composer update --prefer-source $COMPOSER_FLAGS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function addConfiguration(NodeDefinition $node)
->booleanNode('force')->defaultFalse()->end()
->scalarNode('username_mapper')->defaultValue('lightsaml_sp.username_mapper.simple')->end()
->scalarNode('user_creator')->defaultNull()->end()
->scalarNode('attribute_mapper')->defaultNull()->end()
->scalarNode('attribute_mapper')->defaultValue('lightsaml_sp.attribute_mapper.simple')->end()
->scalarNode('token_factory')->defaultValue('lightsaml_sp.token_factory')->end()
->end()
->end();
Expand Down
2 changes: 1 addition & 1 deletion src/LightSaml/SpBundle/Resources/config/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ services:
- "@security.user_checker"
- "@lightsaml_sp.username_mapper.simple" # username mapper
- ~ # user creator
- ~ # attribute mapper
- "@lightsaml_sp.attribute_mapper.simple" # attribute mapper
- ~ # token factory
abstract: true
3 changes: 3 additions & 0 deletions src/LightSaml/SpBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ services:
arguments:
- []

lightsaml_sp.attribute_mapper.simple:
class: LightSaml\SpBundle\Security\User\SimpleAttributeMapper

lightsaml_sp.token_factory:
class: LightSaml\SpBundle\Security\Authentication\Token\SamlSpTokenFactory
85 changes: 85 additions & 0 deletions src/LightSaml/SpBundle/Security/User/SimpleAttributeMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

/*
* This file is part of the LightSAML SP-Bundle package.
*
* (c) Milos Tomic <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace LightSaml\SpBundle\Security\User;

use LightSaml\Model\Assertion\Assertion;
use LightSaml\Model\Assertion\Attribute;
use LightSaml\Model\Assertion\AttributeStatement;
use LightSaml\SpBundle\Security\Authentication\Token\SamlSpResponseToken;

class SimpleAttributeMapper implements AttributeMapperInterface
{
/**
* @param SamlSpResponseToken $token
*
* @return array
*/
public function getAttributes(SamlSpResponseToken $token)
{
$response = $token->getResponse();
$assertions = $response->getAllAssertions();

return array_reduce($assertions, [$this, 'resolveAttributesFromAssertion'], []);
}

/**
* @param array $attributes
* @param Assertion $assertion
*
* @return array
*/
private function resolveAttributesFromAssertion(array $attributes, Assertion $assertion)
{
$attributeStatements = $assertion->getAllAttributeStatements();

return array_reduce($attributeStatements, [$this, 'resolveAttributesFromAttributeStatement'], $attributes);
}

/**
* @param array $attributes
* @param AttributeStatement $attributeStatement
*
* @return array
*/
private function resolveAttributesFromAttributeStatement(array $attributes, AttributeStatement $attributeStatement)
{
$statementAttributes = $attributeStatement->getAllAttributes();

return array_reduce($statementAttributes, [$this, 'mapAttributeValues'], $attributes);
}

/**
* @param array $attributes
* @param Attribute $attribute
*
* @return array
*/
private function mapAttributeValues(array $attributes, Attribute $attribute)
{
$key = $attribute->getName();
$value = $attribute->getAllAttributeValues();

if (!array_key_exists($key, $attributes) && count($value) === 1) {
$value = array_shift($value);
}

if (array_key_exists($key, $attributes)) {
$currentValue = (is_array($attributes[$key]) ? $attributes[$key] : [$attributes[$key]]);

$value = array_merge($currentValue, $value);
}

$attributes[$key] = $value;

return $attributes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function loads_service_provider()
['security.authentication.listener.lightsaml_sp'],
['security.authentication.provider.lightsaml_sp'],
['lightsaml_sp.username_mapper.simple'],
['lightsaml_sp.attribute_mapper.simple'],
['lightsaml_sp.token_factory'],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function configuration_provider()
['force', BooleanNode::class, false],
['username_mapper', ScalarNode::class, 'lightsaml_sp.username_mapper.simple'],
['user_creator', ScalarNode::class, null],
['attribute_mapper', ScalarNode::class, null],
['attribute_mapper', ScalarNode::class, 'lightsaml_sp.attribute_mapper.simple'],
['token_factory', ScalarNode::class, 'lightsaml_sp.token_factory'],
];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php

namespace LightSaml\SpBundle\Tests\Security\User;

use LightSaml\Model\Assertion\Assertion;
use LightSaml\Model\Assertion\Attribute;
use LightSaml\Model\Assertion\AttributeStatement;
use LightSaml\Model\Protocol\Response;
use LightSaml\SpBundle\Security\Authentication\Token\SamlSpResponseToken;
use LightSaml\SpBundle\Security\User\SimpleAttributeMapper;

class SimpleAttributeMapperTest extends \PHPUnit_Framework_TestCase
{
public function test_get_attributes_from_single_assertion_response()
{
$assertion = $this->buildAssertion([
'organization' => 'test',
'name' => 'John',
'email_address' => '[email protected]',
'test' => ['one', 'two'],
]);
$response = $this->buildResponse($assertion);
$samlSpResponseToken = $this->buildSamlSpResponseToken($response);

$expectedAttributes = [
'organization' => 'test',
'name' => 'John',
'email_address' => '[email protected]',
'test' => ['one', 'two'],
];

$simpleAttributeMapper = new SimpleAttributeMapper();
$actualAttributes = $simpleAttributeMapper->getAttributes($samlSpResponseToken);

$this->assertEquals($expectedAttributes, $actualAttributes);
}

public function test_get_attributes_from_multi_assertions_response()
{
$assertion = $this->buildAssertion([
'organization' => 'test',
'name' => 'John',
'email_address' => '[email protected]',
'test' => ['one', 'two'],
]);
$response = $this->buildResponse($assertion);

$assertion = $this->buildAssertion([
'name' => 'Doe',
'email_address' => '[email protected]',
'test' => ['three', 'four'],
]);
$response = $this->buildResponse($assertion, $response);

$samlSpResponseToken = $this->buildSamlSpResponseToken($response);

$expectedAttributes = [
'organization' => 'test',
'name' => ['John', 'Doe'],
'email_address' => ['[email protected]', '[email protected]'],
'test' => ['one', 'two', 'three', 'four'],
];

$simpleAttributeMapper = new SimpleAttributeMapper();
$actualAttributes = $simpleAttributeMapper->getAttributes($samlSpResponseToken);

$this->assertEquals($expectedAttributes, $actualAttributes);
}

public function test_get_attributes_from_multi_attribute_statements_response()
{
$assertion = $this->buildAssertion([
'organization' => 'test',
'name' => 'John',
'email_address' => '[email protected]',
'test' => ['one', 'two']
]);
$assertion = $this->buildAssertion([
'name' => 'Doe',
'email_address' => '[email protected]',
'test' => ['three', 'four']
], $assertion);
$response = $this->buildResponse($assertion);

$samlSpResponseToken = $this->buildSamlSpResponseToken($response);

$expectedAttributes = [
'organization' => 'test',
'name' => ['John', 'Doe'],
'email_address' => ['[email protected]', '[email protected]'],
'test' => ['one', 'two', 'three', 'four'],
];

$simpleAttributeMapper = new SimpleAttributeMapper();
$actualAttributes = $simpleAttributeMapper->getAttributes($samlSpResponseToken);

$this->assertEquals($expectedAttributes, $actualAttributes);
}

/**
* @param Response $response
*
* @return \LightSaml\SpBundle\Security\Authentication\Token\SamlSpResponseToken
*/
private function buildSamlSpResponseToken(Response $response)
{
return new SamlSpResponseToken($response, 'test');
}

/**
* @param Assertion $assertion
* @param Response $response
*
* @return Response
*/
private function buildResponse(Assertion $assertion, Response $response = null)
{
if (null == $response) {
$response = new Response();
}

$response->addAssertion($assertion);

return $response;
}

/**
* @param array $assertionAttributes
* @param Assertion $assertion
*
* @return Assertion
*/
private function buildAssertion(array $assertionAttributes, Assertion $assertion = null)
{
if (null == $assertion) {
$assertion = new Assertion();
}

$assertion->addItem($attributeStatement = new AttributeStatement());
foreach ($assertionAttributes as $attributeName => $attributeValue) {
$attributeStatement->addAttribute(new Attribute($attributeName, $attributeValue));
}

return $assertion;
}
}

0 comments on commit 79b329c

Please sign in to comment.