<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       https://www.life-style.de
 */

namespace SimpleSAML\Module\lifestyle\Auth\Process;

use SimpleSAML\Auth\ProcessingFilter;
use SimpleSAML\Module\lifestyle\Webservice\Handler;

/**
 * Class WebserviceAttributes
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       https://www.life-style.de
 * @package SimpleSAML\Module\lifestyle\Auth\Process
 */
class WebserviceAttributes extends ProcessingFilter
{
    const APPLICATION_IDENTIFIER = 'application::';

    /**
     * Process a request. Add application attributes and roles to response
     *
     * When a filter returns from this function, it is assumed to have completed its task.
     *
     * @param array &$request The request we are currently processing.
     */
    public function process(&$request)
    {
        assert('is_array($request)');
        assert('is_array($request[\'Attributes\'][\'username\'])');

        // The current service provider doesn't want any attributes
        if (!isset($request['SPMetadata']['attributes'])) {
            return;
        }

        /*
         * The list of attributes has been labeled - hopefully - because every service provider may have
         * its own list of attributes. In case we now are in process with another service provider, we
         * have to pull values from user-webservice again
         */
        $entityId = isset($request['Attributes']['__entityid__']) ? $request['Attributes']['__entityid__'] : false;
        if ($entityId !== $request['SPMetadata']['entityid']) {
            $request['Attributes'] = array_merge(
                $request['Attributes'],
                $this->getApplications(reset($request['Attributes']['username']), $request['SPMetadata']['attributes'])
            );
        }
    }

    /**
     * @param string $username
     * @param array $attributes
     * @return array
     */
    private function getApplications($username, array $attributes)
    {
        $applications = $this->findApplications($attributes);
        if (!count($applications)) {
            return [];
        }

        $userApplications = Handler::getUserApplicationAttributes(
            $username,
            $applications
        );

        $attributes = [];
        $applicationNames = [];
        foreach ($userApplications as $applicationName => $userApplication) {
            $attributes[static::APPLICATION_IDENTIFIER . $applicationName][] = $userApplication->toString();
            $applicationNames[] = $userApplication->getName();
        }

        $attributes['applications'] = array_unique($applicationNames);

        return $attributes;
    }

    /**
     * @param array $attributes
     * @return array
     */
    private function findApplications(array $attributes)
    {
        $applicationNames = array();
        foreach ($attributes as $attribute) {
            if (0 === strpos($attribute, static::APPLICATION_IDENTIFIER)) {
                $applicationNames[] = substr($attribute, strlen(static::APPLICATION_IDENTIFIER));
            } elseif ('applications' === strtolower($attribute)) {
                $applicationNames[] = '*';
            }
        }
        return $applicationNames;
    }
}
