lightSAML / SpBundle

SAML2 SP Symfony Bundle based on LightSAML
https://www.lightsaml.com/SP-Bundle/
MIT License
66 stars 70 forks source link

private->protected in SimpleUsernameMapper #55

Closed 01e9 closed 7 years ago

01e9 commented 7 years ago

Easier to extend

I extended it in my child bundle and it currently duplicates $attributes because of private

<?php

namespace Tema\Api\LightSamlBundle\Security\User;

use LightSaml\Model\Assertion\Assertion;
use LightSaml\Model\Protocol\Response;
use LightSaml\SamlConstants;
use LightSaml\SpBundle\Security\User\SimpleUsernameMapper as SimpleUsernameMapperBase;

class PersistentUsernameMapper extends SimpleUsernameMapperBase
{
    const NAME_ID_FORMAT = SamlConstants::NAME_ID_FORMAT_PERSISTENT;

    /** @var string[] */
    protected $attributes;

    /**
     * @param string[] $attributes
     */
    public function __construct(array $attributes)
    {
        parent::__construct($attributes);

        $this->attributes = $attributes;
    }

    /**
     * @param Response $response
     *
     * @return string|null
     */
    public function getUsername(Response $response)
    {
        foreach ($response->getAllAssertions() as $assertion) {
            $username = $this->getUsernameFromAssertion($assertion);
            if ($username) {
                return $username;
            }
        }

        return null;
    }

    /**
     * @param Assertion $assertion
     *
     * @return null|string
     */
    protected function getUsernameFromAssertion(Assertion $assertion)
    {
        foreach ($this->attributes as $attributeName) {
            if (self::NAME_ID == $attributeName) {
                if ($assertion->getSubject() &&
                    $assertion->getSubject()->getNameID() &&
                    $assertion->getSubject()->getNameID()->getValue() &&
                    $assertion->getSubject()->getNameID()->getFormat() === self::NAME_ID_FORMAT
                ) {
                    return $assertion->getSubject()->getNameID()->getValue();
                }
            } else {
                foreach ($assertion->getAllAttributeStatements() as $attributeStatement) {
                    $attribute = $attributeStatement->getFirstAttributeByName($attributeName);
                    if ($attribute && $attribute->getFirstAttributeValue()) {
                        return $attribute->getFirstAttributeValue();
                    }
                }
            }
        }

        return null;
    }
}
coveralls commented 7 years ago

Coverage Status

Coverage increased (+0.5%) to 98.618% when pulling 9a63ebe2e84079b25a7a7542fd10d999330c2a4a on arteniioleg:patch-1 into c32db2ea093b7047ed50e4935d29b6b492718311 on lightSAML:master.

01e9 commented 7 years ago

Not needed anymore, it was working wrongly when response contained email attribute, email was returned instead of persistent id. The fixed/simplified version:

class PersistentUsernameMapper extends SimpleUsernameMapperBase
{
    const NAME_ID_FORMAT = SamlConstants::NAME_ID_FORMAT_PERSISTENT;

    /**
     * @param string[] $attributes
     */
    public function __construct(array $attributes)
    {
        parent::__construct($attributes);
    }

    /**
     * @param Response $response
     *
     * @return string|null
     */
    public function getUsername(Response $response)
    {
        foreach ($response->getAllAssertions() as $assertion) {
            $username = $this->getUsernameFromAssertion($assertion);
            if ($username) {
                return $username;
            }
        }

        return null;
    }

    /**
     * @param Assertion $assertion
     *
     * @return null|string
     */
    protected function getUsernameFromAssertion(Assertion $assertion)
    {
        if ($assertion->getSubject() &&
            $assertion->getSubject()->getNameID() &&
            $assertion->getSubject()->getNameID()->getValue() &&
            $assertion->getSubject()->getNameID()->getFormat() === self::NAME_ID_FORMAT
        ) {
            return $assertion->getSubject()->getNameID()->getValue();
        }

        return null;
    }
}