<commit_before><?php

/*
 * eduVPN - End-user friendly VPN.
 *
 * Copyright: 2016-2019, The Commons Conservancy eduVPN Programme
 * SPDX-License-Identifier: AGPL-3.0+
 */

namespace LetsConnect\Portal;

use fkooman\SAML\SP\SP;
use LetsConnect\Common\Http\Exception\HttpException;
use LetsConnect\Common\Http\RedirectResponse;
use LetsConnect\Common\Http\Request;
use LetsConnect\Common\Http\Response;
use LetsConnect\Common\Http\Service;
use LetsConnect\Common\Http\ServiceModuleInterface;

class SamlModule implements ServiceModuleInterface
{
    /** @var \fkooman\SAML\SP\SP */
    private $samlSp;

    /** @var string|null */
    private $discoUrl;

    /**
     * @param \fkooman\SAML\SP\SP $samlSp
     * @param string|null         $discoUrl
     */
    public function __construct(SP $samlSp, $discoUrl)
    {
        $this->samlSp = $samlSp;
        $this->discoUrl = $discoUrl;
    }

    /**
     * @return void
     */
    public function init(Service $service)
    {
        $service->get(
            '/_saml/login',
            /**
             * @return \LetsConnect\Common\Http\Response
             */
            function (Request $request, array $hookData) {
                $relayState = $request->getQueryParameter('ReturnTo');
                $idpEntityId = $request->getQueryParameter('IdP', false);
                $authnContextQuery = $request->getQueryParameter('AuthnContext', false);
                // XXX is this safe (enough?)
                $authnContext = null !== $authnContextQuery ? explode(',', $authnContextQuery) : [];

                // if and entityId is specified, use it
                if (null !== $idpEntityId) {
                    return new RedirectResponse($this->samlSp->login($idpEntityId, $relayState, $authnContext));
                }

                // we didn't get an IdP entityId so we MUST perform discovery
                if (null === $this->discoUrl) {
                    throw new HttpException('no IdP specified, and no discovery service configured', 500);
                }

                // perform discovery
                $discoQuery = http_build_query(
                    [
                        'entityID' => $this->samlSp->getSpInfo()->getEntityId(),
                        'returnIDParam' => 'IdP',
                        'return' => $request->getUri(),
                    ]
                );

                $querySeparator = false === strpos($this->discoUrl, '?') ? '?' : '&';

                return new RedirectResponse(
                    sprintf(
                        '%s%s%s',
                        $this->discoUrl,
                        $querySeparator,
                        $discoQuery
                    )
                );
            }
        );

        $service->post(
            '/_saml/acs',
            /**
             * @return \LetsConnect\Common\Http\Response
             */
            function (Request $request, array $hookData) {
                $this->samlSp->handleResponse(
                    $request->getPostParameter('SAMLResponse')
                );

                return new RedirectResponse($request->getPostParameter('RelayState'));
            }
        );

        $service->get(
            '/_saml/logout',
            /**
             * @return \LetsConnect\Common\Http\Response
             */
            function (Request $request, array $hookData) {
                $logoutUrl = $this->samlSp->logout($request->getQueryParameter('ReturnTo'));

                return new RedirectResponse($logoutUrl);<commit_msg>catch SamlException and turn it into HttpException<commit_after><?php

/*
 * eduVPN - End-user friendly VPN.
 *
 * Copyright: 2016-2019, The Commons Conservancy eduVPN Programme
 * SPDX-License-Identifier: AGPL-3.0+
 */

namespace LetsConnect\Portal;

use fkooman\SAML\SP\Exception\SamlException;
use fkooman\SAML\SP\SP;
use LetsConnect\Common\Http\Exception\HttpException;
use LetsConnect\Common\Http\RedirectResponse;
use LetsConnect\Common\Http\Request;
use LetsConnect\Common\Http\Response;
use LetsConnect\Common\Http\Service;
use LetsConnect\Common\Http\ServiceModuleInterface;

class SamlModule implements ServiceModuleInterface
{
    /** @var \fkooman\SAML\SP\SP */
    private $samlSp;

    /** @var string|null */
    private $discoUrl;

    /**
     * @param \fkooman\SAML\SP\SP $samlSp
     * @param string|null         $discoUrl
     */
    public function __construct(SP $samlSp, $discoUrl)
    {
        $this->samlSp = $samlSp;
        $this->discoUrl = $discoUrl;
    }

    /**
     * @return void
     */
    public function init(Service $service)
    {
        $service->get(
            '/_saml/login',
            /**
             * @return \LetsConnect\Common\Http\Response
             */
            function (Request $request, array $hookData) {
                try {
                    $relayState = $request->getQueryParameter('ReturnTo');
                    $idpEntityId = $request->getQueryParameter('IdP', false);
                    $authnContextQuery = $request->getQueryParameter('AuthnContext', false);
                    // XXX is this safe (enough?)
                    $authnContext = null !== $authnContextQuery ? explode(',', $authnContextQuery) : [];

                    // if and entityId is specified, use it
                    if (null !== $idpEntityId) {
                        return new RedirectResponse($this->samlSp->login($idpEntityId, $relayState, $authnContext));
                    }

                    // we didn't get an IdP entityId so we MUST perform discovery
                    if (null === $this->discoUrl) {
                        throw new HttpException('no IdP specified, and no discovery service configured', 500);
                    }

                    // perform discovery
                    $discoQuery = http_build_query(
                        [
                            'entityID' => $this->samlSp->getSpInfo()->getEntityId(),
                            'returnIDParam' => 'IdP',
                            'return' => $request->getUri(),
                        ]
                    );

                    $querySeparator = false === strpos($this->discoUrl, '?') ? '?' : '&';

                    return new RedirectResponse(
                        sprintf(
                            '%s%s%s',
                            $this->discoUrl,
                            $querySeparator,
                            $discoQuery
                        )
                    );
                } catch (SamlException $e) {
                    throw new HttpException($e->getMessage(), 500, [], $e);
                }
            }
        );

        $service->post(
            '/_saml/acs',
            /**
             * @return \LetsConnect\Common\Http\Response
             */
            function (Request $request, array $hookData) {
                try {
                    $this->samlSp->handleResponse(
                        $request->getPostParameter('SAMLResponse')
                    );

                    return new RedirectResponse($request->getPostParameter('RelayState'));
                } catch (SamlException $e) {
                    throw new HttpException($e->getMessage(), 500, [], $e);
                }
            }
        );

        $service->get(
            '/_saml/logout',
            /**
             * @return \LetsConnect\Common\Http\Response
             */
            function (Request $request, array $hookData) {
                $logoutUrl = $this->samlSp->logout($request->getQueryParameter('ReturnTo'));

                return new RedirectResponse($logoutUrl);
{'fraction_non_alphanumeric': 0.12037037037037036, 'fraction_numerical': 0.004173187271778821, 'mean_word_length': 1.4891269068484259, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7014173', 'n_tokens_mistral': 2128, 'n_tokens_neox': 1997, 'n_words': 383}