Viel neues
This commit is contained in:
25
qa-tool/htdocs/vendor/autoload.php
vendored
Normal file
25
qa-tool/htdocs/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInite830279ee99617ca9ab69fa346d50d57::getLoader();
|
||||
579
qa-tool/htdocs/vendor/composer/ClassLoader.php
vendored
Normal file
579
qa-tool/htdocs/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,579 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var string|null */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* List of PSR-0 prefixes
|
||||
*
|
||||
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var string|null */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var array<string, self>
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param string|null $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string> Array of classname => path
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $classMap Class to filename map
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||
*
|
||||
* @return array<string, self>
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
359
qa-tool/htdocs/vendor/composer/InstalledVersions.php
vendored
Normal file
359
qa-tool/htdocs/vendor/composer/InstalledVersions.php
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array()) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
21
qa-tool/htdocs/vendor/composer/LICENSE
vendored
Normal file
21
qa-tool/htdocs/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
23
qa-tool/htdocs/vendor/composer/autoload_classmap.php
vendored
Normal file
23
qa-tool/htdocs/vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'DateError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
|
||||
'DateException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
|
||||
'DateInvalidOperationException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php',
|
||||
'DateInvalidTimeZoneException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php',
|
||||
'DateMalformedIntervalStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php',
|
||||
'DateMalformedPeriodStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php',
|
||||
'DateMalformedStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php',
|
||||
'DateObjectError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php',
|
||||
'DateRangeError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php',
|
||||
'Jumbojett\\OpenIDConnectClient' => $vendorDir . '/jumbojett/openid-connect-php/src/OpenIDConnectClient.php',
|
||||
'Jumbojett\\OpenIDConnectClientException' => $vendorDir . '/jumbojett/openid-connect-php/src/OpenIDConnectClient.php',
|
||||
'Override' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/Override.php',
|
||||
'SQLite3Exception' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
|
||||
);
|
||||
12
qa-tool/htdocs/vendor/composer/autoload_files.php
vendored
Normal file
12
qa-tool/htdocs/vendor/composer/autoload_files.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
|
||||
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
);
|
||||
9
qa-tool/htdocs/vendor/composer/autoload_namespaces.php
vendored
Normal file
9
qa-tool/htdocs/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
17
qa-tool/htdocs/vendor/composer/autoload_psr4.php
vendored
Normal file
17
qa-tool/htdocs/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
|
||||
'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
|
||||
'RobRichards\\XMLSecLibs\\' => array($vendorDir . '/robrichards/xmlseclibs/src'),
|
||||
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
|
||||
'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'),
|
||||
'LightSaml\\' => array($vendorDir . '/litesaml/lightsaml/src'),
|
||||
);
|
||||
50
qa-tool/htdocs/vendor/composer/autoload_real.php
vendored
Normal file
50
qa-tool/htdocs/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInite830279ee99617ca9ab69fa346d50d57
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInite830279ee99617ca9ab69fa346d50d57', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInite830279ee99617ca9ab69fa346d50d57', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInite830279ee99617ca9ab69fa346d50d57::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInite830279ee99617ca9ab69fa346d50d57::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
102
qa-tool/htdocs/vendor/composer/autoload_static.php
vendored
Normal file
102
qa-tool/htdocs/vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInite830279ee99617ca9ab69fa346d50d57
|
||||
{
|
||||
public static $files = array (
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
|
||||
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'p' =>
|
||||
array (
|
||||
'phpseclib3\\' => 11,
|
||||
),
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php83\\' => 23,
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Component\\HttpFoundation\\' => 33,
|
||||
),
|
||||
'R' =>
|
||||
array (
|
||||
'RobRichards\\XMLSecLibs\\' => 23,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\EventDispatcher\\' => 20,
|
||||
'ParagonIE\\ConstantTime\\' => 23,
|
||||
),
|
||||
'L' =>
|
||||
array (
|
||||
'LightSaml\\' => 10,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'phpseclib3\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib',
|
||||
),
|
||||
'Symfony\\Polyfill\\Php83\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
|
||||
),
|
||||
'Symfony\\Polyfill\\Mbstring\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
|
||||
),
|
||||
'Symfony\\Component\\HttpFoundation\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/http-foundation',
|
||||
),
|
||||
'RobRichards\\XMLSecLibs\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/robrichards/xmlseclibs/src',
|
||||
),
|
||||
'Psr\\EventDispatcher\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/event-dispatcher/src',
|
||||
),
|
||||
'ParagonIE\\ConstantTime\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src',
|
||||
),
|
||||
'LightSaml\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/litesaml/lightsaml/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'DateError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
|
||||
'DateException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
|
||||
'DateInvalidOperationException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php',
|
||||
'DateInvalidTimeZoneException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php',
|
||||
'DateMalformedIntervalStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php',
|
||||
'DateMalformedPeriodStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php',
|
||||
'DateMalformedStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php',
|
||||
'DateObjectError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php',
|
||||
'DateRangeError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php',
|
||||
'Jumbojett\\OpenIDConnectClient' => __DIR__ . '/..' . '/jumbojett/openid-connect-php/src/OpenIDConnectClient.php',
|
||||
'Jumbojett\\OpenIDConnectClientException' => __DIR__ . '/..' . '/jumbojett/openid-connect-php/src/OpenIDConnectClient.php',
|
||||
'Override' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/Override.php',
|
||||
'SQLite3Exception' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInite830279ee99617ca9ab69fa346d50d57::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInite830279ee99617ca9ab69fa346d50d57::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInite830279ee99617ca9ab69fa346d50d57::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
698
qa-tool/htdocs/vendor/composer/installed.json
vendored
Normal file
698
qa-tool/htdocs/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,698 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "jumbojett/openid-connect-php",
|
||||
"version": "v1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jumbojett/OpenID-Connect-PHP.git",
|
||||
"reference": "4af1d11497ec765dccddf928c14c04535ca96017"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jumbojett/OpenID-Connect-PHP/zipball/4af1d11497ec765dccddf928c14c04535ca96017",
|
||||
"reference": "4af1d11497ec765dccddf928c14c04535ca96017",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"php": ">=7.0",
|
||||
"phpseclib/phpseclib": "~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"yoast/phpunit-polyfills": "^1.0"
|
||||
},
|
||||
"time": "2023-12-13T09:52:12+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"description": "Bare-bones OpenID Connect client",
|
||||
"support": {
|
||||
"issues": "https://github.com/jumbojett/OpenID-Connect-PHP/issues",
|
||||
"source": "https://github.com/jumbojett/OpenID-Connect-PHP/tree/v1.0.0"
|
||||
},
|
||||
"install-path": "../jumbojett/openid-connect-php"
|
||||
},
|
||||
{
|
||||
"name": "litesaml/lightsaml",
|
||||
"version": "v4.2.0",
|
||||
"version_normalized": "4.2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/litesaml/lightsaml.git",
|
||||
"reference": "da88de24e699418918a128f0142dd09e2c41dd38"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/litesaml/lightsaml/zipball/da88de24e699418918a128f0142dd09e2c41dd38",
|
||||
"reference": "da88de24e699418918a128f0142dd09e2c41dd38",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"robrichards/xmlseclibs": "~2.0|~3.0|~4.0",
|
||||
"symfony/http-foundation": "~5.0|~6.0|~7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"litesaml/schemas": "~1.0.0",
|
||||
"marcocesarato/php-conventional-changelog": "^1.15",
|
||||
"monolog/monolog": "^2.0|^3.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "~8.4|~9.5",
|
||||
"pimple/pimple": "~3.0",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"symfony/css-selector": "~5.0|~6.0|~7.0",
|
||||
"symfony/dom-crawler": "~5.0|~6.0|~7.0"
|
||||
},
|
||||
"time": "2024-02-08T11:59:00+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LightSaml\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "William",
|
||||
"email": "work@suppo.fr"
|
||||
},
|
||||
{
|
||||
"name": "Milos Tomic",
|
||||
"email": "tmilos@gmail.com",
|
||||
"homepage": "https://github.com/tmilos/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "SAML 2.0 PHP library",
|
||||
"keywords": [
|
||||
"SAML 2.0",
|
||||
"Single Logout",
|
||||
"Single SignOn",
|
||||
"library",
|
||||
"lightSAML",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://docs.litesaml.com",
|
||||
"issues": "https://github.com/litesaml/lightsaml/issues",
|
||||
"source": "https://github.com/litesaml/lightsaml"
|
||||
},
|
||||
"install-path": "../litesaml/lightsaml"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v3.0.0",
|
||||
"version_normalized": "3.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||
"reference": "df1e7fde177501eee2037dd159cf04f5f301a512"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512",
|
||||
"reference": "df1e7fde177501eee2037dd159cf04f5f301a512",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
"vimeo/psalm": "^4|^5"
|
||||
},
|
||||
"time": "2024-05-08T12:36:18+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\ConstantTime\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com",
|
||||
"role": "Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Steve 'Sc00bz' Thomas",
|
||||
"email": "steve@tobtu.com",
|
||||
"homepage": "https://www.tobtu.com",
|
||||
"role": "Original Developer"
|
||||
}
|
||||
],
|
||||
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||
"keywords": [
|
||||
"base16",
|
||||
"base32",
|
||||
"base32_decode",
|
||||
"base32_encode",
|
||||
"base64",
|
||||
"base64_decode",
|
||||
"base64_encode",
|
||||
"bin2hex",
|
||||
"encoding",
|
||||
"hex",
|
||||
"hex2bin",
|
||||
"rfc4648"
|
||||
],
|
||||
"support": {
|
||||
"email": "info@paragonie.com",
|
||||
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
|
||||
"source": "https://github.com/paragonie/constant_time_encoding"
|
||||
},
|
||||
"install-path": "../paragonie/constant_time_encoding"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v9.99.100",
|
||||
"version_normalized": "9.99.100.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
|
||||
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">= 7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*",
|
||||
"vimeo/psalm": "^1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"time": "2020-10-15T08:29:30+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"polyfill",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"support": {
|
||||
"email": "info@paragonie.com",
|
||||
"issues": "https://github.com/paragonie/random_compat/issues",
|
||||
"source": "https://github.com/paragonie/random_compat"
|
||||
},
|
||||
"install-path": "../paragonie/random_compat"
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "3.0.41",
|
||||
"version_normalized": "3.0.41.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/621c73f7dcb310b61de34d1da4c4204e8ace6ceb",
|
||||
"reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"paragonie/constant_time_encoding": "^1|^2|^3",
|
||||
"paragonie/random_compat": "^1.4|^2.0|^9.99.99",
|
||||
"php": ">=5.6.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "Install the DOM extension to load XML formatted public keys.",
|
||||
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
|
||||
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
|
||||
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
|
||||
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
|
||||
},
|
||||
"time": "2024-08-12T00:13:54+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"phpseclib/bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"phpseclib3\\": "phpseclib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jim Wigginton",
|
||||
"email": "terrafrost@php.net",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Monnerat",
|
||||
"email": "pm@datasphere.ch",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Andreas Fischer",
|
||||
"email": "bantu@phpbb.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Hans-Jürgen Petrich",
|
||||
"email": "petrich@tronic-media.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "graham@alt-three.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
|
||||
"homepage": "http://phpseclib.sourceforge.net",
|
||||
"keywords": [
|
||||
"BigInteger",
|
||||
"aes",
|
||||
"asn.1",
|
||||
"asn1",
|
||||
"blowfish",
|
||||
"crypto",
|
||||
"cryptography",
|
||||
"encryption",
|
||||
"rsa",
|
||||
"security",
|
||||
"sftp",
|
||||
"signature",
|
||||
"signing",
|
||||
"ssh",
|
||||
"twofish",
|
||||
"x.509",
|
||||
"x509"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.41"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/terrafrost",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpseclib",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../phpseclib/phpseclib"
|
||||
},
|
||||
{
|
||||
"name": "psr/event-dispatcher",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/event-dispatcher.git",
|
||||
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
|
||||
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0"
|
||||
},
|
||||
"time": "2019-01-08T18:20:26+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\EventDispatcher\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Standard interfaces for event handling.",
|
||||
"keywords": [
|
||||
"events",
|
||||
"psr",
|
||||
"psr-14"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/event-dispatcher/issues",
|
||||
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
|
||||
},
|
||||
"install-path": "../psr/event-dispatcher"
|
||||
},
|
||||
{
|
||||
"name": "robrichards/xmlseclibs",
|
||||
"version": "3.1.1",
|
||||
"version_normalized": "3.1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/robrichards/xmlseclibs.git",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"php": ">= 5.4"
|
||||
},
|
||||
"time": "2020-09-05T13:00:25+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RobRichards\\XMLSecLibs\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "A PHP library for XML Security",
|
||||
"homepage": "https://github.com/robrichards/xmlseclibs",
|
||||
"keywords": [
|
||||
"security",
|
||||
"signature",
|
||||
"xml",
|
||||
"xmldsig"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/robrichards/xmlseclibs/issues",
|
||||
"source": "https://github.com/robrichards/xmlseclibs/tree/3.1.1"
|
||||
},
|
||||
"install-path": "../robrichards/xmlseclibs"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v7.1.3",
|
||||
"version_normalized": "7.1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
|
||||
"reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/polyfill-mbstring": "~1.1",
|
||||
"symfony/polyfill-php83": "^1.27"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/dbal": "<3.6",
|
||||
"symfony/cache": "<6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/dbal": "^3.6|^4",
|
||||
"predis/predis": "^1.1|^2.0",
|
||||
"symfony/cache": "^6.4|^7.0",
|
||||
"symfony/dependency-injection": "^6.4|^7.0",
|
||||
"symfony/expression-language": "^6.4|^7.0",
|
||||
"symfony/http-kernel": "^6.4|^7.0",
|
||||
"symfony/mime": "^6.4|^7.0",
|
||||
"symfony/rate-limiter": "^6.4|^7.0"
|
||||
},
|
||||
"time": "2024-07-26T12:41:01+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\HttpFoundation\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.1.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/http-foundation"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.30.0",
|
||||
"version_normalized": "1.30.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
|
||||
"reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"time": "2024-06-19T12:30:46+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/polyfill-mbstring"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.30.0",
|
||||
"version_normalized": "1.30.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php83.git",
|
||||
"reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
|
||||
"reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2024-06-19T12:35:24+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php83\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/polyfill-php83"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
113
qa-tool/htdocs/vendor/composer/installed.php
vendored
Normal file
113
qa-tool/htdocs/vendor/composer/installed.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => null,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => null,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'jumbojett/openid-connect-php' => array(
|
||||
'pretty_version' => 'v1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => '4af1d11497ec765dccddf928c14c04535ca96017',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../jumbojett/openid-connect-php',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'litesaml/lightsaml' => array(
|
||||
'pretty_version' => 'v4.2.0',
|
||||
'version' => '4.2.0.0',
|
||||
'reference' => 'da88de24e699418918a128f0142dd09e2c41dd38',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../litesaml/lightsaml',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/constant_time_encoding' => array(
|
||||
'pretty_version' => 'v3.0.0',
|
||||
'version' => '3.0.0.0',
|
||||
'reference' => 'df1e7fde177501eee2037dd159cf04f5f301a512',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paragonie/constant_time_encoding',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/random_compat' => array(
|
||||
'pretty_version' => 'v9.99.100',
|
||||
'version' => '9.99.100.0',
|
||||
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paragonie/random_compat',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpseclib/phpseclib' => array(
|
||||
'pretty_version' => '3.0.41',
|
||||
'version' => '3.0.41.0',
|
||||
'reference' => '621c73f7dcb310b61de34d1da4c4204e8ace6ceb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/event-dispatcher' => array(
|
||||
'pretty_version' => '1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/event-dispatcher',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'robrichards/xmlseclibs' => array(
|
||||
'pretty_version' => '3.1.1',
|
||||
'version' => '3.1.1.0',
|
||||
'reference' => 'f8f19e58f26cdb42c54b214ff8a820760292f8df',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../robrichards/xmlseclibs',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-foundation' => array(
|
||||
'pretty_version' => 'v7.1.3',
|
||||
'version' => '7.1.3.0',
|
||||
'reference' => 'f602d5c17d1fa02f8019ace2687d9d136b7f4a1a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.30.0',
|
||||
'version' => '1.30.0.0',
|
||||
'reference' => 'fd22ab50000ef01661e2a31d850ebaa297f8e03c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php83' => array(
|
||||
'pretty_version' => 'v1.30.0',
|
||||
'version' => '1.30.0.0',
|
||||
'reference' => 'dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php83',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
26
qa-tool/htdocs/vendor/composer/platform_check.php
vendored
Normal file
26
qa-tool/htdocs/vendor/composer/platform_check.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 80200)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
2
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
2
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
**List of common tasks a pull request require complete**
|
||||
- [ ] Changelog entry is added or the pull request don't alter library's functionality
|
||||
38
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/.github/workflows/build.yml
vendored
Normal file
38
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
DEFAULT_COMPOSER_FLAGS: "--prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi"
|
||||
|
||||
jobs:
|
||||
phpunit:
|
||||
name: PHP ${{ matrix.php }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
- name: Install dependencies
|
||||
run: composer update $DEFAULT_COMPOSER_FLAGS
|
||||
- name: Run unit tests
|
||||
run: vendor/bin/phpunit --verbose --colors=always tests
|
||||
4
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/.gitignore
vendored
Normal file
4
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/.idea
|
||||
/vendor
|
||||
/composer.lock
|
||||
.phpunit.result.cache
|
||||
180
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/CHANGELOG.md
vendored
Normal file
180
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.0] - 2023-12-13
|
||||
|
||||
### Added
|
||||
- PHP 7.0 is required. #327
|
||||
- Support for signed and encrypted UserInfo response and ID Token. #305
|
||||
- Allow to set User-Agent header. #370
|
||||
|
||||
### Fixed
|
||||
- User-Agent is set for any HTTP method in fetchURL() (not just POST). #382
|
||||
- Update visibility of getWellKnownConfigValue to protected. #363
|
||||
- Fixed issue on authentication for php8. #354
|
||||
- Update construct typehint in docblock. #364
|
||||
- Fixed LogoutToken verification for single value aud claims. #334
|
||||
- Update well known config value function response types. #376
|
||||
|
||||
## [0.9.10] - 2022-09-30
|
||||
|
||||
### Fixed
|
||||
- `private_key_jwt` and `client_secret_jwt` need to explicitly be enabled #331
|
||||
|
||||
## [0.9.9] - 2022-09-28
|
||||
|
||||
### Added
|
||||
- Added support for back-channel logout. #302
|
||||
- Added support for `private_key_jwt` Client Authentication method #322
|
||||
- Added support for `client_secret_jwt` Client Authentication method #324
|
||||
- Added PS512 encryption support #342
|
||||
|
||||
### Fixed
|
||||
- Harden self-signed JWK header usage. #323
|
||||
|
||||
## [0.9.8] - 2022-08-05
|
||||
|
||||
### Fixed
|
||||
- Do not use PKCE if IdP does not support it. #317
|
||||
|
||||
## [0.9.7] - 2022-07-13
|
||||
|
||||
### Added
|
||||
- Support for Self-Contained JWTs. #308
|
||||
- Support for RFC8693 Token Exchange Request. #275
|
||||
|
||||
### Fixed
|
||||
- PHP 5.4 compatibility. #304
|
||||
- Use session_status(). #306
|
||||
|
||||
## [0.9.6] - 2022-05-08
|
||||
|
||||
### Added
|
||||
- Support for [phpseclib/phpseclib](https://phpseclib.com/) version **3**. #260
|
||||
- Support client_secret on token endpoint with PKCE. #293
|
||||
- Added new parameter to `requestTokens()` to pass custom HTTP headers #297
|
||||
|
||||
### Changed
|
||||
- Allow serializing `OpenIDConnectClient` using `serialize()` #295
|
||||
|
||||
## [0.9.5] - 2021-11-24
|
||||
|
||||
### Changed
|
||||
- signOut() Method parameter $accessToken -> $idToken to prevent confusion about access and id tokens usage. #127
|
||||
- Fixed issue where missing nonce within the claims was causing an exception. #280
|
||||
|
||||
## [0.9.4] - 2021-11-21
|
||||
|
||||
### Added
|
||||
- Enabled `client_secret_basic` authentication on `refreshToken()` #215
|
||||
- Basic auth support for requestResourceOwnerToken #271
|
||||
|
||||
## [0.9.3] - 2021-11-20
|
||||
|
||||
### Added
|
||||
- getRedirectURL() will not log a warning for PHP 7.1+ #179
|
||||
- it is now possible to disable upgrading from HTTP to HTTPS for development purposes by calling `setHttpUpgradeInsecureRequests(false)` #241
|
||||
- bugfix in getSessionKey when _SESSION key does not exist #251
|
||||
- Added scope parameter to refresh token request #225
|
||||
- bugfix in `verifyJWTclaims` when $accessToken is empty and $claims->at_hash is not #276
|
||||
- bugfix with the `empty` function in PHP 5.4 #267
|
||||
|
||||
## [0.9.2] - 2020-11-16
|
||||
|
||||
### Added
|
||||
- Support for [PKCE](https://tools.ietf.org/html/rfc7636). Currently, the supported methods are 'plain' and 'S256'.
|
||||
|
||||
## [0.9.1] - 2020-08-27
|
||||
|
||||
### Added
|
||||
- Add support for MS Azure Active Directory B2C user flows
|
||||
|
||||
### Changed
|
||||
- Fix at_hash verification #200
|
||||
- Getters for public parameters #204
|
||||
- Removed client ID query parameter when making a token request using Basic Auth
|
||||
- Use of `random_bytes()` for token generation instead of `uniqid()`; polyfill for PHP < 7.0 provided.
|
||||
|
||||
### Removed
|
||||
- Removed explicit content-length header - caused issues with proxy servers
|
||||
|
||||
## [0.9.0] - 2020-03-09
|
||||
|
||||
### Added
|
||||
- php 7.4 deprecates array_key_exists on objects, use property_exists in getVerifiedClaims and requestUserInfo
|
||||
- Adding a header to indicate JSON as the return type for userinfo endpoint #151
|
||||
- ~Updated OpenIDConnectClient to conditionally verify nonce #146~
|
||||
- Add possibility to change enc_type parameter for http_build_query #155
|
||||
- Adding OAuth 2.0 Token Introspection #156
|
||||
- Add optional parameters clientId/clientSecret for introspection #157 & #158
|
||||
- Adding OAuth 2.0 Token Revocation #160
|
||||
- Adding issuer validator #145
|
||||
- Adding signing algorithm PS256 #180
|
||||
- Check http status of request user info #186
|
||||
- URL encode clientId and clientSecret when using basic authentication, according to https://tools.ietf.org/html/rfc6749#section-2.3.1 #192
|
||||
- Adjust PHPDoc to state that null is also allowed #193
|
||||
|
||||
### Changed
|
||||
- Bugfix/code cleanup #152
|
||||
- Cleanup PHPDoc #46e5b59
|
||||
- Replace unnecessary double quotes with single quotes #2a76b57
|
||||
- Use original function names instead of aliases #1f37892
|
||||
- Remove unnecessary default values #5ab801e
|
||||
- Explicit declare field $redirectURL #9187c0b
|
||||
- Remove unused code #1e65384
|
||||
- Fix indent #e9cdf56
|
||||
- Cleanup conditional code flow for better readability #107f3fb
|
||||
- Added strict type comparisons #167
|
||||
- Bugfix: required `openid` scope was omitted when additional scopes were registered using `addScope` method. This resulted in failing OpenID process.
|
||||
|
||||
## [0.8.0] - 2019-01-02
|
||||
|
||||
### Added
|
||||
- Fix `verifyJWTsignature()`: verify JWT to prevent php errors and warnings on invalid token
|
||||
|
||||
### Changed
|
||||
- Decouple session manipulation, it's allow use of other session libraries #134
|
||||
- Broaden version requirements of the phpseclib/phpseclib package. #144
|
||||
|
||||
## [0.7.0] - 2018-10-15
|
||||
|
||||
### Added
|
||||
- Add "license" field to composer.json #138
|
||||
- Ensure key_alg is set when getting key #139
|
||||
- Add option to send additional registration parameters like post_logout_redirect_uris. #140
|
||||
|
||||
### Changed
|
||||
- disabled autoload for Crypt_RSA + make refreshToken() method tolerant for errors #137
|
||||
|
||||
## [0.6.0] - 2018-07-17
|
||||
|
||||
### Added
|
||||
- Added five minutes leeway due to clock skew between openidconnect server and client.
|
||||
- Fix save access_token from request in implicit flow authentication #129
|
||||
- `verifyJWTsignature()` method private -> public #126
|
||||
- Support for providers where provider/login URL is not the same as the issuer URL. #125
|
||||
- Support for providers that has a different login URL from the issuer URL, for instance Azure Active Directory. Here, the provider URL is on the format: https://login.windows.net/(tenant-id), while the issuer claim actually is on the format: https://sts.windows.net/(tenant-id).
|
||||
|
||||
### Changed
|
||||
- refreshToken method update #124
|
||||
|
||||
## [0.5.0] - 2018-04-09
|
||||
|
||||
### Added
|
||||
- Implement Azure AD B2C Implicit Workflow
|
||||
|
||||
## [0.4.1] - 2018-02-16
|
||||
|
||||
### Changed
|
||||
- Documentation updates for include path.
|
||||
|
||||
## [0.4.0] - 2018-02-15
|
||||
|
||||
### Added
|
||||
- Timeout is configurable via setTimeout method. This addresses issue #94.
|
||||
- Add the ability to authenticate using the Resource Owner flow (with or without the Client ID and ClientSecret). This addresses issue #98
|
||||
- Add support for HS256, HS512 and HS384 signatures
|
||||
- Removed unused calls to $this->getProviderConfigValue("token_endpoint_…
|
||||
201
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/LICENSE
vendored
Normal file
201
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/LICENSE
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
238
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/README.md
vendored
Normal file
238
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/README.md
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
PHP OpenID Connect Basic Client
|
||||
========================
|
||||
A simple library that allows an application to authenticate a user through the basic OpenID Connect flow.
|
||||
This library hopes to encourage OpenID Connect use by making it simple enough for a developer with little knowledge of
|
||||
the OpenID Connect protocol to set up authentication.
|
||||
|
||||
A special thanks goes to Justin Richer and Amanda Anganes for their help and support of the protocol.
|
||||
|
||||
# Requirements #
|
||||
1. PHP 5.4 or greater
|
||||
2. CURL extension
|
||||
3. JSON extension
|
||||
|
||||
## Install ##
|
||||
1. Install library using composer
|
||||
```
|
||||
composer require jumbojett/openid-connect-php
|
||||
```
|
||||
|
||||
2. Include composer autoloader
|
||||
```php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
```
|
||||
|
||||
## Example 1: Basic Client ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
'ClientSecretHere');
|
||||
$oidc->setCertPath('/path/to/my.cert');
|
||||
$oidc->authenticate();
|
||||
$name = $oidc->requestUserInfo('given_name');
|
||||
|
||||
```
|
||||
|
||||
[See openid spec for available user attributes][1]
|
||||
|
||||
## Example 2: Dynamic Registration ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient("https://id.provider.com");
|
||||
|
||||
$oidc->register();
|
||||
$client_id = $oidc->getClientID();
|
||||
$client_secret = $oidc->getClientSecret();
|
||||
|
||||
// Be sure to add logic to store the client id and client secret
|
||||
```
|
||||
|
||||
## Example 3: Network and Security ##
|
||||
```php
|
||||
// Configure a proxy
|
||||
$oidc->setHttpProxy("http://my.proxy.com:80/");
|
||||
|
||||
// Configure a cert
|
||||
$oidc->setCertPath("/path/to/my.cert");
|
||||
```
|
||||
|
||||
## Example 4: Request Client Credentials Token ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
'ClientSecretHere');
|
||||
$oidc->providerConfigParam(array('token_endpoint'=>'https://id.provider.com/connect/token'));
|
||||
$oidc->addScope('my_scope');
|
||||
|
||||
// this assumes success (to validate check if the access_token property is there and a valid JWT) :
|
||||
$clientCredentialsToken = $oidc->requestClientCredentialsToken()->access_token;
|
||||
|
||||
```
|
||||
|
||||
## Example 5: Request Resource Owners Token (with client auth) ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
'ClientSecretHere');
|
||||
$oidc->providerConfigParam(array('token_endpoint'=>'https://id.provider.com/connect/token'));
|
||||
$oidc->addScope('my_scope');
|
||||
|
||||
//Add username and password
|
||||
$oidc->addAuthParam(array('username'=>'<Username>'));
|
||||
$oidc->addAuthParam(array('password'=>'<Password>'));
|
||||
|
||||
//Perform the auth and return the token (to validate check if the access_token property is there and a valid JWT) :
|
||||
$token = $oidc->requestResourceOwnerToken(TRUE)->access_token;
|
||||
|
||||
```
|
||||
|
||||
## Example 6: Basic client for implicit flow e.g. with Azure AD B2C (see http://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth) ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
'ClientSecretHere');
|
||||
$oidc->setResponseTypes(array('id_token'));
|
||||
$oidc->addScope(array('openid'));
|
||||
$oidc->setAllowImplicitFlow(true);
|
||||
$oidc->addAuthParam(array('response_mode' => 'form_post'));
|
||||
$oidc->setCertPath('/path/to/my.cert');
|
||||
$oidc->authenticate();
|
||||
$sub = $oidc->getVerifiedClaims('sub');
|
||||
|
||||
```
|
||||
|
||||
## Example 7: Introspection of an access token (see https://tools.ietf.org/html/rfc7662) ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
'ClientSecretHere');
|
||||
$data = $oidc->introspectToken('an.access-token.as.given');
|
||||
if (!$data->active) {
|
||||
// the token is no longer usable
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Example 8: PKCE Client ##
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
null);
|
||||
$oidc->setCodeChallengeMethod('S256');
|
||||
$oidc->authenticate();
|
||||
$name = $oidc->requestUserInfo('given_name');
|
||||
|
||||
```
|
||||
|
||||
## Example 9: Back-channel logout ##
|
||||
|
||||
Back-channel authentication assumes you can end a session on the server side on behalf of the user (without relying
|
||||
on their browser). The request is a POST from the OP direct to your RP. In this way, the use of this library can
|
||||
ensure your RP performs 'single sign out' for the user even if they didn't have your RP open in a browser or other
|
||||
device, but still had an active session there.
|
||||
|
||||
Either the sid or the sub may be accessible from the logout token sent from the OP. You can use either
|
||||
`getSidFromBackChannel()` or `getSubjectFromBackChannel()` to retrieve them if it is helpful to match them to a session
|
||||
in order to destroy it.
|
||||
|
||||
The below ensures the use of this library to ensure validation of the back-channel logout token, but is afterward
|
||||
just a hypothetical way of finding such a session and destroying it. Adjust it to the needs of your RP.
|
||||
|
||||
```php
|
||||
|
||||
function handleLogout() {
|
||||
// NOTE: assumes that $this->oidc is an instance of OpenIDConnectClient()
|
||||
if ($this->oidc->verifyLogoutToken()) {
|
||||
$sid = $this->oidc->getSidFromBackChannel();
|
||||
|
||||
if (isset($sid)) {
|
||||
// Somehow find the session based on the $sid and
|
||||
// destroy it. This depends on your RP's design,
|
||||
// there is nothing in the OIDC spec to mandate how.
|
||||
//
|
||||
// In this example, we find a Redis key, which was
|
||||
// previously stored using the sid we obtained from
|
||||
// the access token after login.
|
||||
//
|
||||
// The value of the Redis key is that of the user's
|
||||
// session ID specific to this hypothetical RP app.
|
||||
//
|
||||
// We then switch to that session and destroy it.
|
||||
$this->redis->connect('127.0.0.1', 6379);
|
||||
$session_id_to_destroy = $this->redis->get($sid);
|
||||
if ($session_id_to_destroy) {
|
||||
session_commit();
|
||||
session_id($session_id_to_destroy); // switches to that session
|
||||
session_start();
|
||||
$_SESSION = array(); // effectively ends the session
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Example 10: Enable Token Endpoint Auth Methods ##
|
||||
|
||||
By default, only `client_secret_basic` is enabled on client side which was the only supported for a long time.
|
||||
Recently `client_secret_jwt` and `private_key_jwt` have been added, but they remain disabled until explicitly enabled.
|
||||
|
||||
```php
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient('https://id.provider.com',
|
||||
'ClientIDHere',
|
||||
null);
|
||||
# enable 'client_secret_basic' and 'client_secret_jwt'
|
||||
$oidc->setTokenEndpointAuthMethodsSupported(['client_secret_basic', 'client_secret_jwt']);
|
||||
|
||||
# for 'private_key_jwt' in addition also the generator function has to be set.
|
||||
$oidc->setTokenEndpointAuthMethodsSupported(['private_key_jwt']);
|
||||
$oidc->setPrivateKeyJwtGenerator(function(string $token_endpoint) {
|
||||
# TODO: what ever is necessary
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
## Development Environments ##
|
||||
In some cases you may need to disable SSL security on your development systems.
|
||||
Note: This is not recommended on production systems.
|
||||
|
||||
```php
|
||||
$oidc->setVerifyHost(false);
|
||||
$oidc->setVerifyPeer(false);
|
||||
```
|
||||
|
||||
Also, your local system might not support HTTPS, so you might disable upgrading to it:
|
||||
|
||||
```php
|
||||
$oidc->setHttpUpgradeInsecureRequests(false);
|
||||
```
|
||||
|
||||
### Todo ###
|
||||
- Dynamic registration does not support registration auth tokens and endpoints
|
||||
|
||||
[1]: http://openid.net/specs/openid-connect-basic-1_0-15.html#id_res
|
||||
|
||||
## Contributing ###
|
||||
- All pull requests, once merged, should be added to the CHANGELOG.md file.
|
||||
56
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/client_example.php
vendored
Normal file
56
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/client_example.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Copyright MITRE 2012
|
||||
*
|
||||
* OpenIDConnectClient for PHP5
|
||||
* Author: Michael Jett <mjett@mitre.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient(
|
||||
'http://myproviderURL.com/',
|
||||
'ClientIDHere',
|
||||
'ClientSecretHere'
|
||||
);
|
||||
|
||||
$oidc->authenticate();
|
||||
$name = $oidc->requestUserInfo('given_name');
|
||||
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Example OpenID Connect Client Use</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
Hello <?php echo $name; ?>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
23
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/composer.json
vendored
Normal file
23
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/composer.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "jumbojett/openid-connect-php",
|
||||
"description": "Bare-bones OpenID Connect client",
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*",
|
||||
"phpseclib/phpseclib": "~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"yoast/phpunit-polyfills": "^1.0"
|
||||
},
|
||||
"archive" : {
|
||||
"exclude" : [
|
||||
".*"
|
||||
]
|
||||
},
|
||||
"autoload" : {
|
||||
"classmap": [ "src/"]
|
||||
}
|
||||
}
|
||||
28
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/phpunit.xml.dist
vendored
Normal file
28
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
bootstrap="./vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
verbose="true"
|
||||
stopOnFailure="false"
|
||||
processIsolation="false"
|
||||
backupGlobals="false"
|
||||
syntaxCheck="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Tests">
|
||||
<directory>./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist addUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./src</directory>
|
||||
<exclude>
|
||||
<directory>./vendor</directory>
|
||||
<directory>./tests</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
2069
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/src/OpenIDConnectClient.php
vendored
Normal file
2069
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/src/OpenIDConnectClient.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
240
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/tests/OpenIDConnectClientTest.php
vendored
Normal file
240
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/tests/OpenIDConnectClientTest.php
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
use Jumbojett\OpenIDConnectClientException;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Yoast\PHPUnitPolyfills\TestCases\TestCase;
|
||||
|
||||
class OpenIDConnectClientTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testGetRedirectURL()
|
||||
{
|
||||
$client = new OpenIDConnectClient();
|
||||
|
||||
self::assertSame('http:///', $client->getRedirectURL());
|
||||
|
||||
$_SERVER['SERVER_NAME'] = 'domain.test';
|
||||
$_SERVER['REQUEST_URI'] = '/path/index.php?foo=bar&baz#fragment';
|
||||
self::assertSame('http://domain.test/path/index.php', $client->getRedirectURL());
|
||||
}
|
||||
|
||||
public function testAuthenticateDoesNotThrowExceptionIfClaimsIsMissingNonce()
|
||||
{
|
||||
$fakeClaims = new StdClass();
|
||||
$fakeClaims->iss = 'fake-issuer';
|
||||
$fakeClaims->aud = 'fake-client-id';
|
||||
$fakeClaims->nonce = null;
|
||||
|
||||
$_REQUEST['id_token'] = 'abc.123.xyz';
|
||||
$_REQUEST['state'] = false;
|
||||
$_SESSION['openid_connect_state'] = false;
|
||||
|
||||
/** @var OpenIDConnectClient | MockObject $client */
|
||||
$client = $this->getMockBuilder(OpenIDConnectClient::class)->setMethods(['decodeJWT', 'getProviderConfigValue', 'verifyJWTSignature'])->getMock();
|
||||
$client->method('decodeJWT')->willReturn($fakeClaims);
|
||||
$client->method('getProviderConfigValue')->with('jwks_uri')->willReturn(true);
|
||||
$client->method('verifyJWTSignature')->willReturn(true);
|
||||
|
||||
$client->setClientID('fake-client-id');
|
||||
$client->setIssuer('fake-issuer');
|
||||
$client->setIssuerValidator(function() {
|
||||
return true;
|
||||
});
|
||||
$client->setAllowImplicitFlow(true);
|
||||
$client->setProviderURL('https://jwt.io/');
|
||||
|
||||
try {
|
||||
$authenticated = $client->authenticate();
|
||||
$this->assertTrue($authenticated);
|
||||
} catch ( OpenIDConnectClientException $e ) {
|
||||
if ( $e->getMessage() === 'Unable to verify JWT claims' ) {
|
||||
self::fail( 'OpenIDConnectClientException was thrown when it should not have been.' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testSerialize()
|
||||
{
|
||||
$client = new OpenIDConnectClient('https://example.com', 'foo', 'bar', 'baz');
|
||||
$serialized = serialize($client);
|
||||
$this->assertInstanceOf(OpenIDConnectClient::class, unserialize($serialized));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provider
|
||||
*/
|
||||
public function testAuthMethodSupport($expected, $authMethod, $clientAuthMethods, $idpAuthMethods)
|
||||
{
|
||||
$client = new OpenIDConnectClient();
|
||||
if ($clientAuthMethods !== null) {
|
||||
$client->setTokenEndpointAuthMethodsSupported($clientAuthMethods);
|
||||
}
|
||||
$this->assertEquals($expected, $client->supportsAuthMethod($authMethod, $idpAuthMethods));
|
||||
}
|
||||
|
||||
public function provider(): array
|
||||
{
|
||||
return [
|
||||
'client_secret_basic - default config' => [true, 'client_secret_basic', null, ['client_secret_basic']],
|
||||
|
||||
'client_secret_jwt - default config' => [false, 'client_secret_jwt', null, ['client_secret_basic', 'client_secret_jwt']],
|
||||
'client_secret_jwt - explicitly enabled' => [true, 'client_secret_jwt', ['client_secret_jwt'], ['client_secret_basic', 'client_secret_jwt']],
|
||||
|
||||
'private_key_jwt - default config' => [false, 'private_key_jwt', null, ['client_secret_basic', 'client_secret_jwt', 'private_key_jwt']],
|
||||
'private_key_jwt - explicitly enabled' => [true, 'private_key_jwt', ['private_key_jwt'], ['client_secret_basic', 'client_secret_jwt', 'private_key_jwt']],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jumbojett\\OpenIDConnectClient::verifyLogoutTokenClaims
|
||||
* @dataProvider provideTestVerifyLogoutTokenClaimsData
|
||||
* @throws OpenIDConnectClientException
|
||||
*/
|
||||
public function testVerifyLogoutTokenClaims( $claims, $expectedResult )
|
||||
{
|
||||
/** @var OpenIDConnectClient | MockObject $client */
|
||||
$client = $this->getMockBuilder(OpenIDConnectClient::class)->setMethods(['decodeJWT'])->getMock();
|
||||
|
||||
$client->setClientID('fake-client-id');
|
||||
$client->setIssuer('fake-issuer');
|
||||
$client->setIssuerValidator(function() {
|
||||
return true;
|
||||
});
|
||||
$client->setProviderURL('https://jwt.io/');
|
||||
|
||||
$actualResult = $client->verifyLogoutTokenClaims( $claims );
|
||||
|
||||
$this->assertEquals( $expectedResult, $actualResult );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function provideTestVerifyLogoutTokenClaimsData(): array
|
||||
{
|
||||
return [
|
||||
'valid-single-aud' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => 'fake-client-id',
|
||||
'sid' => 'fake-client-sid',
|
||||
'sub' => 'fake-client-sub',
|
||||
'iat' => time(),
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
'valid-multiple-auds' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'sub' => 'fake-client-sub',
|
||||
'iat' => time(),
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
'invalid-no-sid-and-no-sub' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'iat' => time(),
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
],
|
||||
],
|
||||
false
|
||||
],
|
||||
'valid-no-sid' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sub' => 'fake-client-sub',
|
||||
'iat' => time(),
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
'valid-no-sub' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'iat' => time(),
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
'invalid-with-nonce' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'iat' => time(),
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
],
|
||||
'nonce' => 'must-not-be-set'
|
||||
],
|
||||
false
|
||||
],
|
||||
'invalid-no-events' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'iat' => time(),
|
||||
'nonce' => 'must-not-be-set'
|
||||
],
|
||||
false
|
||||
],
|
||||
'invalid-no-backchannel-event' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'iat' => time(),
|
||||
'events' => (object) [],
|
||||
'nonce' => 'must-not-be-set'
|
||||
],
|
||||
false
|
||||
],
|
||||
'invalid-no-iat' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
]
|
||||
],
|
||||
false
|
||||
],
|
||||
'invalid-bad-iat' => [
|
||||
(object)[
|
||||
'iss' => 'fake-issuer',
|
||||
'aud' => [ 'fake-client-id', 'some-other-aud' ],
|
||||
'sid' => 'fake-client-sid',
|
||||
'iat' => time() + 301,
|
||||
'events' => (object) [
|
||||
'http://schemas.openid.net/event/backchannel-logout' => (object)[]
|
||||
]
|
||||
],
|
||||
false
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
35
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/tests/TokenVerificationTest.php
vendored
Normal file
35
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/tests/TokenVerificationTest.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
use Jumbojett\OpenIDConnectClientException;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Yoast\PHPUnitPolyfills\TestCases\TestCase;
|
||||
|
||||
class TokenVerificationTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param $alg
|
||||
* @param $jwt
|
||||
* @throws OpenIDConnectClientException
|
||||
* @dataProvider providesTokens
|
||||
*/
|
||||
public function testTokenVerification($alg, $jwt)
|
||||
{
|
||||
/** @var OpenIDConnectClient | MockObject $client */
|
||||
$client = $this->getMockBuilder(OpenIDConnectClient::class)->setMethods(['fetchUrl'])->getMock();
|
||||
$client->method('fetchUrl')->willReturn(file_get_contents(__DIR__ . "/data/jwks-$alg.json"));
|
||||
$client->setProviderURL('https://jwt.io/');
|
||||
$client->providerConfigParam(['jwks_uri' => 'https://jwt.io/.well-known/jwks.json']);
|
||||
$verified = $client->verifyJWTSignature($jwt);
|
||||
self::assertTrue($verified);
|
||||
$client->setAccessToken($jwt);
|
||||
}
|
||||
|
||||
public function providesTokens(): array
|
||||
{
|
||||
return [
|
||||
'PS256' => ['ps256', 'eyJhbGciOiJQUzI1NiIsImtpZCI6Imtvbm5lY3RkLXRva2Vucy1zaWduaW5nLWtleSIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJrcG9wLWh0dHBzOi8va29wYW5vLmRlbW8vbWVldC8iLCJleHAiOjE1NjgzNzE0NjEsImp0aSI6IkpkR0tDbEdOTXl2VXJpcmlRRUlWUXZCVmttT2FfQkRjIiwiaWF0IjoxNTY4MzcxMjIxLCJpc3MiOiJodHRwczovL2tvcGFuby5kZW1vIiwic3ViIjoiUHpUVWp3NHBlXzctWE5rWlBILXJxVHE0MTQ1Z3lDdlRvQmk4V1E5bFBrcW5rbEc1aktvRU5LM21Qb0I1WGY1ZTM5dFRMR2RKWXBMNEJubXFnelpaX0FAa29ubmVjdCIsImtjLmlzQWNjZXNzVG9rZW4iOnRydWUsImtjLmF1dGhvcml6ZWRTY29wZXMiOlsicHJvZmlsZSIsImVtYWlsIiwia29wYW5vL2t3bSIsImtvcGFuby9nYyIsImtvcGFuby9rdnMiLCJvcGVuaWQiXSwia2MuYXV0aG9yaXplZENsYWltcyI6eyJpZF90b2tlbiI6eyJuYW1lIjpudWxsfX0sImtjLmlkZW50aXR5Ijp7ImtjLmkuZG4iOiJKb25hcyBCcmVra2UiLCJrYy5pLmlkIjoiQUFBQUFLd2hxVkJBMCs1SXN4bjdwMU13UkNVQkFBQUFCZ0FBQUJzQUFBQk5VVDA5QUFBQUFBPT0iLCJrYy5pLnVuIjoidXNlcjEiLCJrYy5pLnVzIjoiTVEifSwia2MucHJvdmlkZXIiOiJpZGVudGlmaWVyLWtjIn0.hGRuXvul2kOiALHexwYp5MBEJVwz1YV3ehyM3AOuwCoK2w5sJxdciqqY_TfXCKyO6nAEbYLK3J0CBOjfup_IG0aCZcwzjto8khYlc4ezXkGnFsbJBNQdDGkpHtWnioWx-OJ3cXvY9F8aOvjaq0gw11ZDAcqQl0g7LTbJ9-J_yx0pmy3NGai2JB30Fh1OgSDzYfxWnE0RRgZG-x68e65RXfSBaEGW85OUh4wihxO2zdTGAHJ3Iq_-QAG4yRbXZtLx3ZspG7LNmqG-YE3huy3Rd8u3xrJNhmUOfEnz3x07q7VW0cj9NedX98BAbj3iNvksQsE0oG0J_f_Tu8Ai8VbWB72sJuXZWxANDKdz0BBYLzXhsjXkNByRq9x3zqDVsX-cVHei_XudxEOVRBjhkvW2MmIjcAHNKCKsdar865-gFG9McP4PCcBlY28tC0Cvnzyi83LBfpGRXdl6MJunnUsKQ1C79iCoVI1doK1erFN959Q-TGJfJA3Tr5LNpuGawB5rpe1nDGWvmYhg3uYfNl8uTTyvNgvvejcflEb2DURuXdqABuSiP7RkDWYtzx6mq49G0tRxelBbvyjQ2id2QjmRRdQ6dHEZ2NCJ51b8OFoDJBtxN1CD62TTxa3FUqCdZAPAUR3hHn_69vYq82MR514s-Gb67A6j2PbMPFATQP2UdK8']
|
||||
];
|
||||
}
|
||||
}
|
||||
12
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/tests/data/jwks-ps256.json
vendored
Normal file
12
qa-tool/htdocs/vendor/jumbojett/openid-connect-php/tests/data/jwks-ps256.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "RSA",
|
||||
"use": "sig",
|
||||
"kid": "konnectd-tokens-signing-key",
|
||||
"n": "10hb3pFUVcqJcS-d1pLCkFTyTqVD1GavlAai582CoRwFcyIQxCPJz0LJVgkUNwxSRkY0g0PcgFN_MmuuzpFXMkkiMIC9O_KwnuL34FrbijZvcGpnDn7kb9KAM883OVTr_w3wFeQIyh0ksSwVQ9CxVQ-ZeCXP73CCGk99uDb8SeF8_vncXJmaak99pK6HKJteSLkA-Ywxo9HOINZK2vW06UYcSkeoQnSI27Cd5-T6GVgqKH0Su4c5Ydou_w0tL_UkbZA4fIbMZC6dtWmBQf6tyYsCM9fbWNIVOj_7WlWcAOSTFNF2We2dxJrOzt6vDND3k1nCgg_EEM6cgBO3swUCktTFuQxo1sryYX5WXz9wnJb38b9mTXhOeF0bd9y_VQq8erSlcyRu8UGzX65tIf534hLL16KQaHbjROGSQvzqFrISmSBjBTjkPedTZSYOhiVJ95-em_Y6uLi-T7V4bs4dcg3oa0H_glXltoC9JxzS6gfMGGLgh-NpGEOdC_QosyzVVfzT70TurOGnsB1_VcAm_fK-T1Zv_ztpr5OZNfXWXC3Pfq_3sxP5HDKMk8luZ7LOWk7HVSYBdCFmOM1A3KmHNS2fEs-QHIr-XjYQ7QrXsRFP3dmoEPfiYlu03m8Xs3UMB70eGeGQx7OhZSuogxV_oCfApV5EJfuz97tVmOg8iMs",
|
||||
"e": "AQAB"
|
||||
}
|
||||
],
|
||||
"kty": ""
|
||||
}
|
||||
59
qa-tool/htdocs/vendor/litesaml/lightsaml/composer.json
vendored
Normal file
59
qa-tool/htdocs/vendor/litesaml/lightsaml/composer.json
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "litesaml/lightsaml",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"description": "SAML 2.0 PHP library",
|
||||
"keywords": ["SAML 2.0", "PHP", "library", "lightSAML", "Single SignOn", "Single Logout"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "William",
|
||||
"email": "work@suppo.fr"
|
||||
},
|
||||
{
|
||||
"name": "Milos Tomic",
|
||||
"email": "tmilos@gmail.com",
|
||||
"homepage": "https://github.com/tmilos/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/litesaml/lightsaml/issues",
|
||||
"source": "https://github.com/litesaml/lightsaml",
|
||||
"docs": "https://docs.litesaml.com"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LightSaml\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"LightSaml\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"robrichards/xmlseclibs": "~2.0|~3.0|~4.0",
|
||||
"symfony/http-foundation": "~5.0|~6.0|~7.0",
|
||||
"psr/event-dispatcher": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dom-crawler": "~5.0|~6.0|~7.0",
|
||||
"symfony/css-selector": "~5.0|~6.0|~7.0",
|
||||
"pimple/pimple": "~3.0",
|
||||
"phpunit/phpunit": "~8.4|~9.5",
|
||||
"monolog/monolog": "^2.0|^3.0",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"litesaml/schemas": "~1.0.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"marcocesarato/php-conventional-changelog": "^1.15"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"minimum-stability": "stable",
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit",
|
||||
"phpcs": "vendor/bin/phpcs --standard=PSR12 --exclude=Generic.Files.LineLength ./src",
|
||||
"phpstan": "vendor/bin/phpstan analyse --memory-limit 512M --ansi",
|
||||
"tag": "vendor/bin/conventional-changelog --commit"
|
||||
}
|
||||
}
|
||||
10
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/ActionInterface.php
vendored
Normal file
10
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/ActionInterface.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
|
||||
interface ActionInterface
|
||||
{
|
||||
public function execute(ContextInterface $context);
|
||||
}
|
||||
26
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/ActionLogWrapper.php
vendored
Normal file
26
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/ActionLogWrapper.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ActionLogWrapper implements ActionWrapperInterface
|
||||
{
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ActionInterface
|
||||
*/
|
||||
public function wrap(ActionInterface $action)
|
||||
{
|
||||
return new LoggableAction($action, $this->logger);
|
||||
}
|
||||
}
|
||||
11
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/ActionWrapperInterface.php
vendored
Normal file
11
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/ActionWrapperInterface.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
interface ActionWrapperInterface
|
||||
{
|
||||
/**
|
||||
* @return ActionInterface
|
||||
*/
|
||||
public function wrap(ActionInterface $action);
|
||||
}
|
||||
31
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Assertion/AbstractAssertionAction.php
vendored
Normal file
31
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Assertion/AbstractAssertionAction.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion;
|
||||
|
||||
use LightSaml\Action\ActionInterface;
|
||||
use LightSaml\Context\ContextInterface;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
abstract class AbstractAssertionAction implements ActionInterface
|
||||
{
|
||||
/** @var LoggerInterface */
|
||||
protected $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
if ($context instanceof AssertionContext) {
|
||||
$this->doExecute($context);
|
||||
} else {
|
||||
throw new LightSamlContextException($context, 'Expected AssertionContext');
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected function doExecute(AssertionContext $context);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\SamlConstants;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AssertionIssuerFormatValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var string */
|
||||
private $expectedIssuerFormat = SamlConstants::NAME_ID_FORMAT_ENTITY;
|
||||
|
||||
/**
|
||||
* @param string $expectedIssuerFormat
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger, $expectedIssuerFormat)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->expectedIssuerFormat = $expectedIssuerFormat;
|
||||
}
|
||||
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
if (null == $context->getAssertion()->getIssuer()) {
|
||||
$message = 'Assertion element must have an issuer element';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if (
|
||||
$context->getAssertion()->getIssuer()->getFormat() &&
|
||||
$context->getAssertion()->getIssuer()->getFormat() != $this->expectedIssuerFormat
|
||||
) {
|
||||
$message = sprintf(
|
||||
"Response Issuer Format if set must have value '%s' but it was '%s'",
|
||||
$this->expectedIssuerFormat,
|
||||
$context->getAssertion()->getIssuer()->getFormat()
|
||||
);
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'actualFormat' => $context->getAssertion()->getIssuer()->getFormat(),
|
||||
'expectedFormat' => $this->expectedIssuerFormat,
|
||||
]));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Credential\Criteria\MetadataCriteria;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Error\LightSamlModelException;
|
||||
use LightSaml\Model\XmlDSig\AbstractSignatureReader;
|
||||
use LightSaml\Validator\Model\Signature\SignatureValidatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AssertionSignatureValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var SignatureValidatorInterface */
|
||||
protected $signatureValidator;
|
||||
|
||||
/** @var bool */
|
||||
protected $requireSignature;
|
||||
|
||||
/**
|
||||
* @param bool $requireSignature
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger, SignatureValidatorInterface $signatureValidator, $requireSignature = true)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->signatureValidator = $signatureValidator;
|
||||
$this->requireSignature = $requireSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
$signature = $context->getAssertion()->getSignature();
|
||||
if (null === $signature) {
|
||||
if ($this->requireSignature) {
|
||||
$message = 'Assertions must be signed';
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
} else {
|
||||
$this->logger->debug('Assertion is not signed', LogHelper::getActionContext($context, $this));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($signature instanceof AbstractSignatureReader) {
|
||||
$metadataType = ProfileContext::ROLE_IDP === $context->getProfileContext()->getOwnRole() ? MetadataCriteria::TYPE_SP : MetadataCriteria::TYPE_IDP;
|
||||
$credential = $this->signatureValidator->validate($signature, $context->getAssertion()->getIssuer()->getValue(), $metadataType);
|
||||
if ($credential) {
|
||||
$keyNames = $credential->getKeyNames();
|
||||
$this->logger->debug(
|
||||
sprintf('Assertion signature validated with key "%s"', implode(', ', $keyNames)),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'credential' => $credential,
|
||||
])
|
||||
);
|
||||
} else {
|
||||
$this->logger->warning(
|
||||
'Assertion signature verification was not performed',
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$message = 'Expected AbstractSignatureReader';
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlModelException($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Validator\Model\Assertion\AssertionValidatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AssertionValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var AssertionValidatorInterface */
|
||||
protected $assertionValidator;
|
||||
|
||||
public function __construct(LoggerInterface $logger, AssertionValidatorInterface $assertionValidator)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->assertionValidator = $assertionValidator;
|
||||
}
|
||||
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
$this->assertionValidator->validateAssertion($context->getAssertion());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContexts;
|
||||
use LightSaml\Context\Profile\RequestStateContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Store\Request\RequestStateStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class InResponseToValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var RequestStateStoreInterface */
|
||||
protected $requestStore;
|
||||
|
||||
public function __construct(LoggerInterface $logger, RequestStateStoreInterface $requestStore)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->requestStore = $requestStore;
|
||||
}
|
||||
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
if (null === $context->getAssertion()->getSubject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($context->getAssertion()->getSubject()->getAllSubjectConfirmations() as $subjectConfirmation) {
|
||||
if (
|
||||
$subjectConfirmation->getSubjectConfirmationData() &&
|
||||
$subjectConfirmation->getSubjectConfirmationData()->getInResponseTo()
|
||||
) {
|
||||
$requestState = $this->validateInResponseTo(
|
||||
$subjectConfirmation->getSubjectConfirmationData()->getInResponseTo(),
|
||||
$context
|
||||
);
|
||||
|
||||
/** @var RequestStateContext $requestStateContext */
|
||||
$requestStateContext = $context->getSubContext(ProfileContexts::REQUEST_STATE, RequestStateContext::class);
|
||||
$requestStateContext->setRequestState($requestState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $inResponseTo
|
||||
*
|
||||
* @return \LightSaml\State\Request\RequestState
|
||||
*/
|
||||
protected function validateInResponseTo($inResponseTo, AssertionContext $context)
|
||||
{
|
||||
$requestState = $this->requestStore->get($inResponseTo);
|
||||
if (null == $requestState) {
|
||||
$message = sprintf("Unknown InResponseTo '%s'", $inResponseTo);
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
return $requestState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Store\EntityDescriptor\EntityDescriptorStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class KnownAssertionIssuerAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var EntityDescriptorStoreInterface */
|
||||
private $idpEntityDescriptorProvider;
|
||||
|
||||
public function __construct(LoggerInterface $logger, EntityDescriptorStoreInterface $idpEntityDescriptorProvider)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->idpEntityDescriptorProvider = $idpEntityDescriptorProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
if (null === $context->getAssertion()->getIssuer()) {
|
||||
$message = 'Assertion element must have an issuer element';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if (false == $this->idpEntityDescriptorProvider->has($context->getAssertion()->getIssuer()->getValue())) {
|
||||
$message = sprintf("Unknown issuer '%s'", $context->getAssertion()->getIssuer()->getValue());
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'messageIssuer' => $context->getAssertion()->getIssuer()->getValue(),
|
||||
]));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf('Known assertion issuer: "%s"', $context->getAssertion()->getIssuer()->getValue()),
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Criteria\CriteriaSet;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Model\Assertion\SubjectConfirmation;
|
||||
use LightSaml\Model\Metadata\AssertionConsumerService;
|
||||
use LightSaml\Model\Metadata\SpSsoDescriptor;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\DescriptorTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\LocationCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\ServiceTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\EndpointResolverInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class RecipientValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var EndpointResolverInterface */
|
||||
private $endpointResolver;
|
||||
|
||||
public function __construct(LoggerInterface $logger, EndpointResolverInterface $endpointResolver)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->endpointResolver = $endpointResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
if ($context->getAssertion()->getAllAuthnStatements() && $context->getAssertion()->hasBearerSubject()) {
|
||||
$this->validateBearerAssertion($context);
|
||||
}
|
||||
}
|
||||
|
||||
protected function validateBearerAssertion(AssertionContext $context)
|
||||
{
|
||||
foreach ($context->getAssertion()->getSubject()->getBearerConfirmations() as $subjectConfirmation) {
|
||||
$this->validateSubjectConfirmation($context, $subjectConfirmation);
|
||||
}
|
||||
}
|
||||
|
||||
protected function validateSubjectConfirmation(AssertionContext $context, SubjectConfirmation $subjectConfirmation)
|
||||
{
|
||||
$recipient = $subjectConfirmation->getSubjectConfirmationData()->getRecipient();
|
||||
if (null == $recipient) {
|
||||
$message = 'Bearer SubjectConfirmation must contain Recipient attribute';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
$criteriaSet = new CriteriaSet([
|
||||
new DescriptorTypeCriteria(SpSsoDescriptor::class),
|
||||
new ServiceTypeCriteria(AssertionConsumerService::class),
|
||||
new LocationCriteria($recipient),
|
||||
]);
|
||||
$ownEntityDescriptor = $context->getProfileContext()->getOwnEntityDescriptor();
|
||||
$arrEndpoints = $this->endpointResolver->resolve($criteriaSet, $ownEntityDescriptor->getAllEndpoints());
|
||||
|
||||
if (empty($arrEndpoints)) {
|
||||
$message = sprintf("Recipient '%s' does not match SP descriptor", $recipient);
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'recipient' => $recipient,
|
||||
]));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
119
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Assertion/Inbound/RepeatedIdValidatorAction.php
vendored
Normal file
119
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Assertion/Inbound/RepeatedIdValidatorAction.php
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Store\Id\IdStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* 4.1.4.5 POST-Specific Processing Rules
|
||||
* The service provider MUST ensure that bearer assertions are not replayed, by maintaining the set of used
|
||||
* ID values for the length of time for which the assertion would be considered valid based on the
|
||||
* NotOnOrAfter attribute in the <SubjectConfirmationData>.
|
||||
*/
|
||||
class RepeatedIdValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var IdStoreInterface */
|
||||
protected $idStore;
|
||||
|
||||
public function __construct(LoggerInterface $logger, IdStoreInterface $idStore)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->idStore = $idStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
if ($context->getAssertion()->hasBearerSubject()) {
|
||||
$this->validateBearerAssertion($context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \LightSaml\Error\LightSamlContextException
|
||||
*/
|
||||
protected function validateBearerAssertion(AssertionContext $context)
|
||||
{
|
||||
if (null == $context->getAssertion()->getId()) {
|
||||
$message = 'Bearer Assertion must have ID attribute';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if (null == $context->getAssertion()->getIssuer()) {
|
||||
$message = 'Bearer Assertion must have Issuer element';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if ($this->idStore->has($context->getAssertion()->getIssuer()->getValue(), $context->getAssertion()->getId())) {
|
||||
$message = sprintf(
|
||||
"Repeated assertion id '%s' of issuer '%s'",
|
||||
$context->getAssertion()->getId(),
|
||||
$context->getAssertion()->getIssuer()->getValue()
|
||||
);
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'id' => $context->getAssertion()->getId(),
|
||||
'issuer' => $context->getAssertion()->getIssuer()->getValue(),
|
||||
]));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
$this->idStore->set(
|
||||
$context->getAssertion()->getIssuer()->getValue(),
|
||||
$context->getAssertion()->getId(),
|
||||
$this->getIdExpiryTime($context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \LogicException
|
||||
* @throws \LightSaml\Error\LightSamlValidationException
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
protected function getIdExpiryTime(AssertionContext $context)
|
||||
{
|
||||
/** @var \DateTime $result */
|
||||
$result = null;
|
||||
$bearerConfirmations = $context->getAssertion()->getSubject()->getBearerConfirmations();
|
||||
if (null == $bearerConfirmations) {
|
||||
throw new \LogicException('Bearer assertion must have bearer subject confirmations');
|
||||
}
|
||||
|
||||
foreach ($bearerConfirmations as $subjectConfirmation) {
|
||||
if (null == $subjectConfirmation->getSubjectConfirmationData()) {
|
||||
$message = 'Bearer SubjectConfirmation must have SubjectConfirmationData element';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
$dt = $subjectConfirmation->getSubjectConfirmationData()->getNotOnOrAfterDateTime();
|
||||
if (null == $dt) {
|
||||
$message = 'Bearer SubjectConfirmation must have NotOnOrAfter attribute';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if (null == $result || $result->getTimestamp() < $dt->getTimestamp()) {
|
||||
$result = $dt;
|
||||
}
|
||||
}
|
||||
|
||||
if (null == $result) {
|
||||
$message = 'Unable to find NotOnOrAfter attribute in bearer assertion';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
49
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Assertion/Inbound/TimeValidatorAction.php
vendored
Normal file
49
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Assertion/Inbound/TimeValidatorAction.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Assertion\Inbound;
|
||||
|
||||
use LightSaml\Action\Assertion\AbstractAssertionAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Provider\TimeProvider\TimeProviderInterface;
|
||||
use LightSaml\Validator\Model\Assertion\AssertionTimeValidatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class TimeValidatorAction extends AbstractAssertionAction
|
||||
{
|
||||
/** @var AssertionTimeValidatorInterface */
|
||||
protected $assertionTimeValidator;
|
||||
|
||||
/** @var TimeProviderInterface */
|
||||
protected $timeProvider;
|
||||
|
||||
/** @var int */
|
||||
protected $allowedSecondsSkew;
|
||||
|
||||
/**
|
||||
* @param int $allowedSecondsSkew
|
||||
*/
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
AssertionTimeValidatorInterface $assertionTimeValidator,
|
||||
TimeProviderInterface $timeProvider,
|
||||
$allowedSecondsSkew = 120
|
||||
) {
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->assertionTimeValidator = $assertionTimeValidator;
|
||||
$this->timeProvider = $timeProvider;
|
||||
$this->allowedSecondsSkew = $allowedSecondsSkew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(AssertionContext $context)
|
||||
{
|
||||
$this->assertionTimeValidator->validateTimeRestrictions(
|
||||
$context->getAssertion(),
|
||||
$this->timeProvider->getTimestamp(),
|
||||
$this->allowedSecondsSkew
|
||||
);
|
||||
}
|
||||
}
|
||||
38
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/CatchableErrorAction.php
vendored
Normal file
38
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/CatchableErrorAction.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
use LightSaml\Context\Profile\ExceptionContext;
|
||||
use LightSaml\Context\Profile\ProfileContexts;
|
||||
|
||||
class CatchableErrorAction implements ActionInterface
|
||||
{
|
||||
/** @var ActionInterface */
|
||||
protected $mainAction;
|
||||
|
||||
/** @var ActionInterface */
|
||||
protected $errorAction;
|
||||
|
||||
public function __construct(ActionInterface $mainAction, ActionInterface $errorAction)
|
||||
{
|
||||
$this->mainAction = $mainAction;
|
||||
$this->errorAction = $errorAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
try {
|
||||
$this->mainAction->execute($context);
|
||||
} catch (\Exception $ex) {
|
||||
/** @var ExceptionContext $exceptionContext */
|
||||
$exceptionContext = $context->getSubContext(ProfileContexts::EXCEPTION, ExceptionContext::class);
|
||||
$exceptionContext->addException($ex);
|
||||
|
||||
$this->errorAction->execute($context);
|
||||
}
|
||||
}
|
||||
}
|
||||
93
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/CompositeAction.php
vendored
Normal file
93
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/CompositeAction.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
|
||||
class CompositeAction implements ActionInterface, DebugPrintTreeActionInterface, CompositeActionInterface
|
||||
{
|
||||
/** @var ActionInterface[] */
|
||||
protected $children = [];
|
||||
|
||||
/**
|
||||
* @param ActionInterface[] $children
|
||||
*/
|
||||
public function __construct(array $children = [])
|
||||
{
|
||||
foreach ($children as $action) {
|
||||
$this->add($action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ActionInterface[]
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CompositeAction
|
||||
*/
|
||||
public function add(ActionInterface $action)
|
||||
{
|
||||
$this->children[] = $action;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return ActionInterface|null
|
||||
*/
|
||||
public function map($callable)
|
||||
{
|
||||
foreach ($this->children as $k => $action) {
|
||||
$newAction = call_user_func($callable, $action);
|
||||
if ($newAction) {
|
||||
$this->children[$k] = $newAction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
foreach ($this->children as $action) {
|
||||
$action->execute($context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function debugPrintTree()
|
||||
{
|
||||
$arr = [];
|
||||
foreach ($this->children as $childAction) {
|
||||
if ($childAction instanceof DebugPrintTreeActionInterface) {
|
||||
$arr = array_merge($arr, $childAction->debugPrintTree());
|
||||
} else {
|
||||
$arr = array_merge($arr, [get_class($childAction) => []]);
|
||||
}
|
||||
}
|
||||
|
||||
$result = [
|
||||
static::class => $arr,
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return json_encode($this->debugPrintTree(), JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
||||
18
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/CompositeActionInterface.php
vendored
Normal file
18
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/CompositeActionInterface.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
interface CompositeActionInterface extends ActionInterface
|
||||
{
|
||||
/**
|
||||
* @return CompositeActionInterface
|
||||
*/
|
||||
public function add(ActionInterface $action);
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return ActionInterface|null
|
||||
*/
|
||||
public function map($callable);
|
||||
}
|
||||
11
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/DebugPrintTreeActionInterface.php
vendored
Normal file
11
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/DebugPrintTreeActionInterface.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
interface DebugPrintTreeActionInterface
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function debugPrintTree();
|
||||
}
|
||||
26
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/DispatchEventAction.php
vendored
Normal file
26
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/DispatchEventAction.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
use LightSaml\Event\ActionOccurred;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class DispatchEventAction implements ActionInterface
|
||||
{
|
||||
/** @var EventDispatcherInterface */
|
||||
protected $eventDispatcher;
|
||||
|
||||
public function __construct(EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
$this->eventDispatcher->dispatch(new ActionOccurred($context));
|
||||
}
|
||||
}
|
||||
33
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/LoggableAction.php
vendored
Normal file
33
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/LoggableAction.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class LoggableAction extends WrappedAction
|
||||
{
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
public function __construct(ActionInterface $action, LoggerInterface $logger)
|
||||
{
|
||||
parent::__construct($action);
|
||||
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
protected function beforeAction(ContextInterface $context)
|
||||
{
|
||||
$this->logger->debug(sprintf('Executing action "%s"', get_class($this->action)), [
|
||||
'context' => $context,
|
||||
'action' => $this->action,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function afterAction(ContextInterface $context)
|
||||
{
|
||||
}
|
||||
}
|
||||
16
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/NullAction.php
vendored
Normal file
16
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/NullAction.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
|
||||
class NullAction implements ActionInterface
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
// null
|
||||
}
|
||||
}
|
||||
36
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/AbstractProfileAction.php
vendored
Normal file
36
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/AbstractProfileAction.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile;
|
||||
|
||||
use LightSaml\Action\ActionInterface;
|
||||
use LightSaml\Context\ContextInterface;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
abstract class AbstractProfileAction implements ActionInterface
|
||||
{
|
||||
/** @var LoggerInterface */
|
||||
protected $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
if ($context instanceof ProfileContext) {
|
||||
$this->doExecute($context);
|
||||
} else {
|
||||
$message = sprintf('Expected ProfileContext but got %s', get_class($context));
|
||||
$this->logger->emergency($message, ['context' => $context]);
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected function doExecute(ProfileContext $context);
|
||||
}
|
||||
43
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/Entity/SerializeOwnEntityAction.php
vendored
Normal file
43
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/Entity/SerializeOwnEntityAction.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Entity;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Context\Profile\ProfileContexts;
|
||||
use LightSaml\Model\Context\SerializationContext;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SerializeOwnEntityAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var string[] */
|
||||
protected $supportedContextTypes = ['application/samlmetadata+xml', 'application/xml', 'text/xml'];
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$ownEntityDescriptor = $context->getOwnEntityDescriptor();
|
||||
|
||||
/** @var SerializationContext $serializationContext */
|
||||
$serializationContext = $context->getSubContext(ProfileContexts::SERIALIZATION, SerializationContext::class);
|
||||
$serializationContext->getDocument()->formatOutput = true;
|
||||
|
||||
$ownEntityDescriptor->serialize($serializationContext->getDocument(), $serializationContext);
|
||||
|
||||
$xml = $serializationContext->getDocument()->saveXML();
|
||||
|
||||
$response = new Response($xml);
|
||||
|
||||
$contentType = 'text/xml';
|
||||
$acceptableContentTypes = array_flip($context->getHttpRequest()->getAcceptableContentTypes());
|
||||
foreach ($this->supportedContextTypes as $supportedContentType) {
|
||||
if (isset($acceptableContentTypes[$supportedContentType])) {
|
||||
$contentType = $supportedContentType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$response->headers->replace(['Content-Type' => $contentType]);
|
||||
|
||||
$context->getHttpResponseContext()->setResponse($response);
|
||||
}
|
||||
}
|
||||
64
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/FlushRequestStatesAction.php
vendored
Normal file
64
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/FlushRequestStatesAction.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Context\Profile\ProfileContexts;
|
||||
use LightSaml\Context\Profile\RequestStateContext;
|
||||
use LightSaml\Store\Request\RequestStateStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class FlushRequestStatesAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var RequestStateStoreInterface */
|
||||
protected $requestStore;
|
||||
|
||||
public function __construct(LoggerInterface $logger, RequestStateStoreInterface $requestStore)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->requestStore = $requestStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$this->flush($context->getInboundContext()->getSubContext(ProfileContexts::REQUEST_STATE, null));
|
||||
foreach ($context as $child) {
|
||||
if ($child instanceof AssertionContext) {
|
||||
$this->flush($child->getSubContext(ProfileContexts::REQUEST_STATE, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContextInterface|null $requestStateContext
|
||||
*/
|
||||
protected function flush($requestStateContext = null)
|
||||
{
|
||||
if (
|
||||
$requestStateContext instanceof RequestStateContext &&
|
||||
$requestStateContext->getRequestState() &&
|
||||
$requestStateContext->getRequestState()->getId()
|
||||
) {
|
||||
$existed = $this->requestStore->remove($requestStateContext->getRequestState()->getId());
|
||||
|
||||
if ($existed) {
|
||||
$this->logger->debug(
|
||||
sprintf('Removed request state "%s"', $requestStateContext->getRequestState()->getId()),
|
||||
LogHelper::getActionContext($requestStateContext, $this)
|
||||
);
|
||||
} else {
|
||||
$this->logger->warning(
|
||||
sprintf('Request state "%s" does not exist', $requestStateContext->getRequestState()->getId()),
|
||||
LogHelper::getActionContext($requestStateContext, $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Criteria\CriteriaSet;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Model\Metadata\IdpSsoDescriptor;
|
||||
use LightSaml\Model\Metadata\SpSsoDescriptor;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\DescriptorTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\LocationCriteria;
|
||||
use LightSaml\Resolver\Endpoint\EndpointResolverInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
abstract class AbstractDestinationValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var EndpointResolverInterface */
|
||||
protected $endpointResolver;
|
||||
|
||||
public function __construct(LoggerInterface $logger, EndpointResolverInterface $endpointResolver)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->endpointResolver = $endpointResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context->getInboundContext());
|
||||
$destination = $message->getDestination();
|
||||
|
||||
if (null == $destination) {
|
||||
return;
|
||||
}
|
||||
|
||||
$criteriaSet = $this->getCriteriaSet($context, $destination);
|
||||
$endpoints = $this->endpointResolver->resolve($criteriaSet, $context->getOwnEntityDescriptor()->getAllEndpoints());
|
||||
|
||||
if ($endpoints) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = sprintf('Invalid inbound message destination "%s"', $destination);
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
*
|
||||
* @return CriteriaSet
|
||||
*/
|
||||
protected function getCriteriaSet(ProfileContext $context, $location)
|
||||
{
|
||||
$criteriaSet = new CriteriaSet([
|
||||
new DescriptorTypeCriteria(
|
||||
ProfileContext::ROLE_IDP === $context->getOwnRole()
|
||||
? IdpSsoDescriptor::class
|
||||
: SpSsoDescriptor::class
|
||||
),
|
||||
new LocationCriteria($location),
|
||||
]);
|
||||
|
||||
return $criteriaSet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AssertBindingTypeAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var string[] */
|
||||
protected $expectedBindingTypes;
|
||||
|
||||
/**
|
||||
* @param string[] $expectedBindingTypes
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger, array $expectedBindingTypes)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->expectedBindingTypes = $expectedBindingTypes;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
if (false === in_array($context->getInboundContext()->getBindingType(), $this->expectedBindingTypes)) {
|
||||
$message = sprintf(
|
||||
'Unexpected binding type "%s" - expected binding types are: %s',
|
||||
$context->getInboundContext()->getBindingType(),
|
||||
implode(' ', $this->expectedBindingTypes)
|
||||
);
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'actualBindingType' => $context->getInboundContext()->getBindingType(),
|
||||
'expectedBindingTypes' => $this->expectedBindingTypes,
|
||||
]));
|
||||
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Criteria\CriteriaSet;
|
||||
use LightSaml\Model\Metadata\SingleSignOnService;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\ServiceTypeCriteria;
|
||||
|
||||
class DestinationValidatorAuthnRequestAction extends AbstractDestinationValidatorAction
|
||||
{
|
||||
/**
|
||||
* @param string $location
|
||||
*
|
||||
* @return CriteriaSet
|
||||
*/
|
||||
protected function getCriteriaSet(ProfileContext $context, $location)
|
||||
{
|
||||
$result = parent::getCriteriaSet($context, $location);
|
||||
|
||||
$result->add(new ServiceTypeCriteria(SingleSignOnService::class));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Criteria\CriteriaSet;
|
||||
use LightSaml\Model\Metadata\AssertionConsumerService;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\ServiceTypeCriteria;
|
||||
|
||||
class DestinationValidatorResponseAction extends AbstractDestinationValidatorAction
|
||||
{
|
||||
/**
|
||||
* @param string $location
|
||||
*
|
||||
* @return CriteriaSet
|
||||
*/
|
||||
protected function getCriteriaSet(ProfileContext $context, $location)
|
||||
{
|
||||
$result = parent::getCriteriaSet($context, $location);
|
||||
|
||||
$result->add(new ServiceTypeCriteria(AssertionConsumerService::class));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
|
||||
class EntityIdFromMessageIssuerAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context->getInboundContext());
|
||||
if (null == $message->getIssuer()) {
|
||||
throw new LightSamlContextException($context, 'Inbound messages does not have Issuer');
|
||||
}
|
||||
|
||||
$context->getPartyEntityContext()->setEntityId($message->getIssuer()->getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Error\LightSamlValidationException;
|
||||
use LightSaml\Validator\Model\NameId\NameIdValidatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class IssuerValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var NameIdValidatorInterface */
|
||||
protected $nameIdValidator;
|
||||
|
||||
/** @var string */
|
||||
protected $allowedFormat;
|
||||
|
||||
/**
|
||||
* @param string $allowedFormat
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger, NameIdValidatorInterface $nameIdValidator, $allowedFormat)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->nameIdValidator = $nameIdValidator;
|
||||
$this->allowedFormat = $allowedFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context->getInboundContext());
|
||||
|
||||
if (false == $message->getIssuer()) {
|
||||
$message = 'Inbound message must have Issuer element';
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if (
|
||||
$this->allowedFormat &&
|
||||
$message->getIssuer()->getValue() &&
|
||||
$message->getIssuer()->getFormat() &&
|
||||
$message->getIssuer()->getFormat() != $this->allowedFormat
|
||||
) {
|
||||
$message = sprintf(
|
||||
"Response Issuer Format if set must have value '%s' but it was '%s'",
|
||||
$this->allowedFormat,
|
||||
$message->getIssuer()->getFormat()
|
||||
);
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->nameIdValidator->validateNameId($message->getIssuer());
|
||||
} catch (LightSamlValidationException $ex) {
|
||||
throw new LightSamlContextException($context, $ex->getMessage(), 0, $ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Credential\Criteria\MetadataCriteria;
|
||||
use LightSaml\Error\LightSamlModelException;
|
||||
use LightSaml\Model\XmlDSig\AbstractSignatureReader;
|
||||
use LightSaml\Validator\Model\Signature\SignatureValidatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Validates the signature, if any, of the inbound message.
|
||||
*/
|
||||
class MessageSignatureValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var SignatureValidatorInterface */
|
||||
protected $signatureValidator;
|
||||
|
||||
public function __construct(LoggerInterface $logger, SignatureValidatorInterface $signatureValidator)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->signatureValidator = $signatureValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context->getInboundContext());
|
||||
|
||||
$signature = $message->getSignature();
|
||||
if (null === $signature) {
|
||||
$this->logger->debug('Message is not signed', LogHelper::getActionContext($context, $this));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($signature instanceof AbstractSignatureReader) {
|
||||
$metadataType = ProfileContext::ROLE_IDP === $context->getOwnRole() ? MetadataCriteria::TYPE_SP : MetadataCriteria::TYPE_IDP;
|
||||
$credential = $this->signatureValidator->validate($signature, $message->getIssuer()->getValue(), $metadataType);
|
||||
if ($credential) {
|
||||
$keyNames = $credential->getKeyNames();
|
||||
$this->logger->debug(
|
||||
sprintf('Message signature validated with key "%s"', implode(', ', $keyNames)),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'credential' => $credential,
|
||||
])
|
||||
);
|
||||
} else {
|
||||
$this->logger->warning(
|
||||
'Signature verification was not performed',
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$message = 'Expected AbstractSignatureReader';
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlModelException($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Binding\BindingFactoryInterface;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlBindingException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Receives message from HTTP Request into inbound context,
|
||||
* optionally enforces biding type to the one specified in the inbound context.
|
||||
*/
|
||||
class ReceiveMessageAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var BindingFactoryInterface */
|
||||
protected $bindingFactory;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BindingFactoryInterface $bindingFactory)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->bindingFactory = $bindingFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$bindingType = $this->bindingFactory->detectBindingType($context->getHttpRequest());
|
||||
if (null == $bindingType) {
|
||||
$message = 'Unable to resolve binding type, invalid or unsupported http request';
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlBindingException($message);
|
||||
}
|
||||
|
||||
$this->logger->debug(sprintf('Detected binding type: %s', $bindingType), LogHelper::getActionContext($context, $this));
|
||||
|
||||
$binding = $this->bindingFactory->create($bindingType);
|
||||
$binding->receive($context->getHttpRequest(), $context->getInboundContext());
|
||||
$context->getInboundContext()->setBindingType($bindingType);
|
||||
|
||||
$this->logger->info(
|
||||
'Received message',
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'message' => $context->getInboundContext()->getDeserializationContext()->getDocument()->saveXML(),
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Meta\TrustOptions\TrustOptions;
|
||||
use LightSaml\Store\EntityDescriptor\EntityDescriptorStoreInterface;
|
||||
use LightSaml\Store\TrustOptions\TrustOptionsStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Looks up inbound message Issuer in entity descriptor providers and sets it to the party context.
|
||||
*/
|
||||
class ResolvePartyEntityIdAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var EntityDescriptorStoreInterface */
|
||||
private $spEntityDescriptorProvider;
|
||||
|
||||
/** @var EntityDescriptorStoreInterface */
|
||||
private $idpEntityDescriptorProvider;
|
||||
|
||||
/** @var TrustOptionsStoreInterface */
|
||||
protected $trustOptionsProvider;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
EntityDescriptorStoreInterface $spEntityDescriptorProvider,
|
||||
EntityDescriptorStoreInterface $idpEntityDescriptorProvider,
|
||||
TrustOptionsStoreInterface $trustOptionsProvider
|
||||
) {
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->spEntityDescriptorProvider = $spEntityDescriptorProvider;
|
||||
$this->idpEntityDescriptorProvider = $idpEntityDescriptorProvider;
|
||||
$this->trustOptionsProvider = $trustOptionsProvider;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$partyContext = $context->getPartyEntityContext();
|
||||
|
||||
if ($partyContext->getEntityDescriptor() && $partyContext->getTrustOptions()) {
|
||||
$this->logger->debug(
|
||||
sprintf('Party EntityDescriptor and TrustOptions already set for "%s"', $partyContext->getEntityDescriptor()->getEntityID()),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'partyEntityId' => $partyContext->getEntityDescriptor()->getEntityID(),
|
||||
])
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$entityId = $partyContext->getEntityDescriptor() ? $partyContext->getEntityDescriptor()->getEntityID() : null;
|
||||
$entityId = $entityId ? $entityId : $partyContext->getEntityId();
|
||||
if (null == $entityId) {
|
||||
$message = 'EntityID is not set in the party context';
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
if (null == $partyContext->getEntityDescriptor()) {
|
||||
$partyEntityDescriptor = $this->getPartyEntityDescriptor(
|
||||
$context,
|
||||
ProfileContext::ROLE_IDP === $context->getOwnRole()
|
||||
? $this->spEntityDescriptorProvider
|
||||
: $this->idpEntityDescriptorProvider,
|
||||
$context->getPartyEntityContext()->getEntityId()
|
||||
);
|
||||
$partyContext->setEntityDescriptor($partyEntityDescriptor);
|
||||
$this->logger->debug(
|
||||
sprintf('Known issuer resolved: "%s"', $partyEntityDescriptor->getEntityID()),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'partyEntityId' => $partyEntityDescriptor->getEntityID(),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
if (null == $partyContext->getTrustOptions()) {
|
||||
$trustOptions = $this->trustOptionsProvider->get($partyContext->getEntityDescriptor()->getEntityID());
|
||||
if (null === $trustOptions) {
|
||||
$trustOptions = new TrustOptions();
|
||||
}
|
||||
$partyContext->setTrustOptions($trustOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entityId
|
||||
*
|
||||
* @return \LightSaml\Model\Metadata\EntityDescriptor
|
||||
*/
|
||||
protected function getPartyEntityDescriptor(
|
||||
ProfileContext $context,
|
||||
EntityDescriptorStoreInterface $entityDescriptorProvider,
|
||||
$entityId
|
||||
) {
|
||||
$partyEntityDescriptor = $entityDescriptorProvider->get($entityId);
|
||||
if (null === $partyEntityDescriptor) {
|
||||
$message = sprintf("Unknown issuer '%s'", $entityId);
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
return $partyEntityDescriptor;
|
||||
}
|
||||
}
|
||||
62
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/Inbound/Response/AssertionAction.php
vendored
Normal file
62
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/Inbound/Response/AssertionAction.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Response;
|
||||
|
||||
use LightSaml\Action\ActionInterface;
|
||||
use LightSaml\Action\DebugPrintTreeActionInterface;
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\AssertionContext;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AssertionAction extends AbstractProfileAction implements DebugPrintTreeActionInterface
|
||||
{
|
||||
/** @var ActionInterface */
|
||||
private $assertionAction;
|
||||
|
||||
public function __construct(LoggerInterface $logger, ActionInterface $assertionAction)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->assertionAction = $assertionAction;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asResponse($context->getInboundContext());
|
||||
|
||||
foreach ($response->getAllAssertions() as $index => $assertion) {
|
||||
$name = sprintf('assertion_%s', $index);
|
||||
/** @var AssertionContext $assertionContext */
|
||||
$assertionContext = $context->getSubContext($name, AssertionContext::class);
|
||||
$assertionContext
|
||||
->setAssertion($assertion)
|
||||
->setId($name)
|
||||
;
|
||||
|
||||
$this->assertionAction->execute($assertionContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $depth
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function debugPrintTree($depth = 0)
|
||||
{
|
||||
$arr = [];
|
||||
if ($this->assertionAction instanceof DebugPrintTreeActionInterface) {
|
||||
$arr = array_merge($arr, $this->assertionAction->debugPrintTree());
|
||||
} else {
|
||||
$arr[get_class($this->assertionAction)] = [];
|
||||
}
|
||||
|
||||
$result = [
|
||||
static::class => $arr,
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Response;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Credential\CredentialInterface;
|
||||
use LightSaml\Credential\Criteria\EntityIdCriteria;
|
||||
use LightSaml\Credential\Criteria\MetadataCriteria;
|
||||
use LightSaml\Credential\Criteria\UsageCriteria;
|
||||
use LightSaml\Credential\UsageType;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Model\Assertion\EncryptedAssertionReader;
|
||||
use LightSaml\Model\Context\DeserializationContext;
|
||||
use LightSaml\Resolver\Credential\CredentialResolverInterface;
|
||||
use LightSaml\SamlConstants;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class DecryptAssertionsAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var CredentialResolverInterface */
|
||||
protected $credentialResolver;
|
||||
|
||||
public function __construct(LoggerInterface $logger, CredentialResolverInterface $credentialResolver)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->credentialResolver = $credentialResolver;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asResponse($context->getInboundContext());
|
||||
|
||||
if (0 === count($response->getAllEncryptedAssertions())) {
|
||||
$this->logger->debug('Response has no encrypted assertions', LogHelper::getActionContext($context, $this));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$ownEntityDescriptor = $context->getOwnEntityDescriptor();
|
||||
|
||||
$query = $this->credentialResolver->query();
|
||||
$query
|
||||
->add(new EntityIdCriteria($ownEntityDescriptor->getEntityID()))
|
||||
->add(new MetadataCriteria(
|
||||
ProfileContext::ROLE_IDP === $context->getOwnRole()
|
||||
? MetadataCriteria::TYPE_IDP
|
||||
: MetadataCriteria::TYPE_SP,
|
||||
SamlConstants::PROTOCOL_SAML2
|
||||
))
|
||||
->add(new UsageCriteria(UsageType::ENCRYPTION))
|
||||
;
|
||||
$query->resolve();
|
||||
$privateKeys = $query->getPrivateKeys();
|
||||
if (empty($privateKeys)) {
|
||||
$message = 'No credentials resolved for assertion decryption';
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
$this->logger->info('Trusted decryption candidates', LogHelper::getActionContext($context, $this, [
|
||||
'credentials' => array_map(function (CredentialInterface $credential) {
|
||||
return sprintf(
|
||||
"Entity: '%s'; PK X509 Thumb: '%s'",
|
||||
$credential->getEntityId(),
|
||||
$credential->getPublicKey() ? $credential->getPublicKey()->getX509Thumbprint() : ''
|
||||
);
|
||||
}, $privateKeys),
|
||||
]));
|
||||
|
||||
foreach ($response->getAllEncryptedAssertions() as $index => $encryptedAssertion) {
|
||||
if ($encryptedAssertion instanceof EncryptedAssertionReader) {
|
||||
$name = sprintf('assertion_encrypted_%s', $index);
|
||||
/** @var DeserializationContext $deserializationContext */
|
||||
$deserializationContext = $context->getInboundContext()->getSubContext($name, DeserializationContext::class);
|
||||
$assertion = $encryptedAssertion->decryptMultiAssertion($privateKeys, $deserializationContext);
|
||||
$response->addAssertion($assertion);
|
||||
|
||||
$this->logger->info(
|
||||
'Assertion decrypted',
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'assertion' => $deserializationContext->getDocument()->saveXML(),
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Response;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
|
||||
class HasAssertionsValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asResponse($context->getInboundContext());
|
||||
|
||||
if ($response->getAllAssertions()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = 'Response must contain at least one assertion';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Response;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
|
||||
class HasAuthnStatementValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asResponse($context->getInboundContext());
|
||||
|
||||
foreach ($response->getAllAssertions() as $assertion) {
|
||||
if ($assertion->getAllAuthnStatements()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$message = 'Response must have at least one Assertion containing AuthnStatement element';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Response;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
|
||||
class HasBearerAssertionsValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asResponse($context->getInboundContext());
|
||||
|
||||
if ($response->getBearerAssertions()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = 'Response must contain at least one bearer assertion';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\Response;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Resolver\Session\SessionProcessorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class SpSsoStateAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var SessionProcessorInterface */
|
||||
private $sessionProcessor;
|
||||
|
||||
public function __construct(LoggerInterface $logger, SessionProcessorInterface $sessionProcessor)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->sessionProcessor = $sessionProcessor;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asResponse($context->getInboundContext());
|
||||
|
||||
$this->sessionProcessor->processAssertions(
|
||||
$response->getAllAssertions(),
|
||||
$context->getOwnEntityDescriptor()->getEntityID(),
|
||||
$context->getPartyEntityDescriptor()->getEntityID()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\StatusResponse;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Context\Profile\ProfileContexts;
|
||||
use LightSaml\Context\Profile\RequestStateContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\State\Request\RequestStateParameters;
|
||||
use LightSaml\Store\Request\RequestStateStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class InResponseToValidatorAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var RequestStateStoreInterface */
|
||||
protected $requestStore;
|
||||
|
||||
public function __construct(LoggerInterface $logger, RequestStateStoreInterface $requestStore)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->requestStore = $requestStore;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$response = MessageContextHelper::asStatusResponse($context->getInboundContext());
|
||||
$inResponseTo = $response->getInResponseTo();
|
||||
if ($inResponseTo) {
|
||||
$requestState = $this->requestStore->get($inResponseTo);
|
||||
if (null == $requestState) {
|
||||
$message = sprintf("Unknown InResponseTo '%s'", $inResponseTo);
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'in_response_to' => $inResponseTo,
|
||||
]));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
$sentToParty = $requestState->getParameters()->get(RequestStateParameters::PARTY);
|
||||
if ($sentToParty && $response->getIssuer() && $response->getIssuer()->getValue() != $sentToParty) {
|
||||
$message = sprintf('AuthnRequest with id "%s" sent to party "%s" but StatusResponse for that request issued by party "%s"', $inResponseTo, $sentToParty, $response->getIssuer()->getValue());
|
||||
$this->logger->critical($message, LogHelper::getActionErrorContext($context, $this, [
|
||||
'sent_to' => $sentToParty,
|
||||
'received_from' => $response->getIssuer()->getValue(),
|
||||
]));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
/** @var RequestStateContext $requestStateContext */
|
||||
$requestStateContext = $context->getInboundContext()->getSubContext(ProfileContexts::REQUEST_STATE, RequestStateContext::class);
|
||||
$requestStateContext->setRequestState($requestState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Inbound\StatusResponse;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlAuthenticationException;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
|
||||
/**
|
||||
* Throws LightSamlAuthenticationException if status of inbound message is not successful.
|
||||
*/
|
||||
class StatusAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$statusResponse = MessageContextHelper::asStatusResponse($context->getInboundContext());
|
||||
|
||||
if ($statusResponse->getStatus() && $statusResponse->getStatus()->isSuccess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null == $statusResponse->getStatus()) {
|
||||
$message = 'Status response does not have Status set';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
$status = $statusResponse->getStatus()->getStatusCode()->getValue();
|
||||
$status .= "\n" . $statusResponse->getStatus()->getStatusMessage();
|
||||
if ($statusResponse->getStatus()->getStatusCode()->getStatusCode()) {
|
||||
$status .= "\n" . $statusResponse->getStatus()->getStatusCode()->getStatusCode()->getValue();
|
||||
}
|
||||
|
||||
$message = 'Unsuccessful SAML response: ' . $status;
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this, ['status' => $status]));
|
||||
throw new LightSamlAuthenticationException($statusResponse, $message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\AuthnRequest;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Criteria\CriteriaSet;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Model\Metadata\AssertionConsumerService;
|
||||
use LightSaml\Model\Metadata\SpSsoDescriptor;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\BindingCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\DescriptorTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\ServiceTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\EndpointResolverInterface;
|
||||
use LightSaml\SamlConstants;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
// TODO ACSUrlAction not used in profile builder, has to be added
|
||||
class ACSUrlAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var EndpointResolverInterface */
|
||||
private $endpointResolver;
|
||||
|
||||
public function __construct(LoggerInterface $logger, EndpointResolverInterface $endpointResolver)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->endpointResolver = $endpointResolver;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$ownEntityDescriptor = $context->getOwnEntityDescriptor();
|
||||
|
||||
$criteriaSet = new CriteriaSet([
|
||||
new DescriptorTypeCriteria(SpSsoDescriptor::class),
|
||||
new ServiceTypeCriteria(AssertionConsumerService::class),
|
||||
new BindingCriteria([SamlConstants::BINDING_SAML2_HTTP_POST]),
|
||||
]);
|
||||
|
||||
$endpoints = $this->endpointResolver->resolve($criteriaSet, $ownEntityDescriptor->getAllEndpoints());
|
||||
if (empty($endpoints)) {
|
||||
$message = 'Missing ACS Service with HTTP POST binding in own SP SSO Descriptor';
|
||||
$this->logger->error($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
MessageContextHelper::asAuthnRequest($context->getOutboundContext())
|
||||
->setAssertionConsumerServiceURL($endpoints[0]->getEndpoint()->getLocation());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\AuthnRequest;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Model\Protocol\AuthnRequest;
|
||||
|
||||
/**
|
||||
* Creates empty AuthnRequest in outbound context.
|
||||
*/
|
||||
class CreateAuthnRequestAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$context->getOutboundContext()->setMessage(new AuthnRequest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Model\Assertion\Issuer;
|
||||
use LightSaml\SamlConstants;
|
||||
|
||||
/**
|
||||
* Sets the Issuer of the outbound message to the value of own entityID.
|
||||
*/
|
||||
class CreateMessageIssuerAction extends AbstractProfileAction
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$ownEntityDescriptor = $context->getOwnEntityDescriptor();
|
||||
|
||||
$issuer = new Issuer($ownEntityDescriptor->getEntityID());
|
||||
$issuer->setFormat(SamlConstants::NAME_ID_FORMAT_ENTITY);
|
||||
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setIssuer($issuer);
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf('Issuer set to "%s"', $ownEntityDescriptor->getEntityID()),
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
|
||||
/**
|
||||
* Sets destination of the outbound message to the value of location of endpoint from the context.
|
||||
*/
|
||||
class DestinationAction extends AbstractProfileAction
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$endpoint = $context->getEndpoint();
|
||||
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setDestination($endpoint->getLocation());
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf('Destination set to "%s"', $endpoint->getLocation()),
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
|
||||
class ForwardRelayStateAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
if (null == $context->getInboundContext()->getMessage()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($context->getInboundMessage()->getRelayState()) {
|
||||
$this->logger->debug(sprintf('Forwarding relay state from inbound message: "%s"', $context->getInboundMessage()->getRelayState()));
|
||||
$context->getOutboundMessage()->setRelayState(
|
||||
$context->getInboundMessage()->getRelayState()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/Outbound/Message/MessageIdAction.php
vendored
Normal file
27
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/Profile/Outbound/Message/MessageIdAction.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Helper;
|
||||
|
||||
/**
|
||||
* Sets the ID of the message in the outbound context.
|
||||
*/
|
||||
class MessageIdAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$id = Helper::generateID();
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setId($id);
|
||||
|
||||
$this->logger->info(
|
||||
sprintf('Message ID set to "%s"', $id),
|
||||
LogHelper::getActionContext($context, $this, ['message_id' => $id])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Provider\TimeProvider\TimeProviderInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Sets outbound message IssueInstant to the value provided by given time provider.
|
||||
*/
|
||||
class MessageIssueInstantAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var TimeProviderInterface */
|
||||
protected $timeProvider;
|
||||
|
||||
public function __construct(LoggerInterface $logger, TimeProviderInterface $timeProvider)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->timeProvider = $timeProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setIssueInstant($this->timeProvider->getTimestamp());
|
||||
|
||||
$this->logger->info(
|
||||
sprintf('Message IssueInstant set to "%s"', MessageContextHelper::asSamlMessage($context->getOutboundContext())->getIssueInstantString()),
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Sets the Version of the outbound message to the given value.
|
||||
*/
|
||||
class MessageVersionAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var string */
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger, $version)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setVersion($this->version);
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf('Message Version set to "%s"', $this->version),
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Criteria\CriteriaSet;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Model\Metadata\EndpointReference;
|
||||
use LightSaml\Model\Metadata\IdpSsoDescriptor;
|
||||
use LightSaml\Model\Metadata\SpSsoDescriptor;
|
||||
use LightSaml\Model\Protocol\AuthnRequest;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\BindingCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\DescriptorTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\IndexCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\LocationCriteria;
|
||||
use LightSaml\Resolver\Endpoint\Criteria\ServiceTypeCriteria;
|
||||
use LightSaml\Resolver\Endpoint\EndpointResolverInterface;
|
||||
use LightSaml\SamlConstants;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Determines to which endpoint outbound message will be sent.
|
||||
*/
|
||||
abstract class ResolveEndpointBaseAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var EndpointResolverInterface */
|
||||
protected $endpointResolver;
|
||||
|
||||
public function __construct(LoggerInterface $logger, EndpointResolverInterface $endpointResolver)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->endpointResolver = $endpointResolver;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
if ($context->getEndpointContext()->getEndpoint()) {
|
||||
$this->logger->debug(
|
||||
sprintf(
|
||||
'Endpoint already set with location "%s" and binding "%s"',
|
||||
$context->getEndpoint()->getLocation(),
|
||||
$context->getEndpoint()->getBinding()
|
||||
),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'endpointLocation' => $context->getEndpoint()->getLocation(),
|
||||
'endpointBinding' => $context->getEndpoint()->getBinding(),
|
||||
])
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$criteriaSet = $this->getCriteriaSet($context);
|
||||
|
||||
$message = $context->getInboundContext()->getMessage();
|
||||
if ($message instanceof AuthnRequest) {
|
||||
if (null !== $message->getAssertionConsumerServiceIndex()) {
|
||||
$criteriaSet->add(new IndexCriteria($message->getAssertionConsumerServiceIndex()));
|
||||
}
|
||||
if (null !== $message->getAssertionConsumerServiceURL()) {
|
||||
$criteriaSet->add(new LocationCriteria($message->getAssertionConsumerServiceURL()));
|
||||
}
|
||||
}
|
||||
|
||||
$candidates = $this->endpointResolver->resolve($criteriaSet, $context->getPartyEntityDescriptor()->getAllEndpoints());
|
||||
/** @var EndpointReference $endpointReference */
|
||||
$endpointReference = array_shift($candidates);
|
||||
|
||||
if (null == $endpointReference) {
|
||||
$message = sprintf(
|
||||
"Unable to determine endpoint for entity '%s'",
|
||||
$context->getPartyEntityDescriptor()->getEntityID()
|
||||
);
|
||||
$this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
|
||||
throw new LightSamlContextException($context, $message);
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf(
|
||||
'Endpoint resolved to location "%s" and binding "%s"',
|
||||
$endpointReference->getEndpoint()->getLocation(),
|
||||
$endpointReference->getEndpoint()->getBinding()
|
||||
),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'endpointLocation' => $endpointReference->getEndpoint()->getLocation(),
|
||||
'endpointBinding' => $endpointReference->getEndpoint()->getBinding(),
|
||||
])
|
||||
);
|
||||
|
||||
$context->getEndpointContext()->setEndpoint($endpointReference->getEndpoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CriteriaSet
|
||||
*/
|
||||
protected function getCriteriaSet(ProfileContext $context)
|
||||
{
|
||||
$criteriaSet = new CriteriaSet();
|
||||
|
||||
$bindings = $this->getBindings($context);
|
||||
if ($bindings) {
|
||||
$criteriaSet->add(new BindingCriteria($bindings));
|
||||
}
|
||||
|
||||
$descriptorType = $this->getDescriptorType($context);
|
||||
if ($descriptorType) {
|
||||
$criteriaSet->add(new DescriptorTypeCriteria($descriptorType));
|
||||
}
|
||||
|
||||
$serviceType = $this->getServiceType($context);
|
||||
if ($serviceType) {
|
||||
$criteriaSet->add(new ServiceTypeCriteria($serviceType));
|
||||
}
|
||||
|
||||
return $criteriaSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getBindings(ProfileContext $context)
|
||||
{
|
||||
return [
|
||||
SamlConstants::BINDING_SAML2_HTTP_POST,
|
||||
SamlConstants::BINDING_SAML2_HTTP_REDIRECT,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getDescriptorType(ProfileContext $context)
|
||||
{
|
||||
return ProfileContext::ROLE_IDP == $context->getOwnRole()
|
||||
? SpSsoDescriptor::class
|
||||
: IdpSsoDescriptor::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getServiceType(ProfileContext $context)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Model\Metadata\SingleSignOnService;
|
||||
|
||||
class ResolveEndpointIdpSsoAction extends ResolveEndpointBaseAction
|
||||
{
|
||||
protected function getServiceType(ProfileContext $context)
|
||||
{
|
||||
return SingleSignOnService::class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Error\LightSamlContextException;
|
||||
use LightSaml\Model\Metadata\IdpSsoDescriptor;
|
||||
use LightSaml\Model\Metadata\SingleLogoutService;
|
||||
use LightSaml\Model\Metadata\SpSsoDescriptor;
|
||||
|
||||
class ResolveEndpointSloAction extends ResolveEndpointBaseAction
|
||||
{
|
||||
protected function getServiceType(ProfileContext $context)
|
||||
{
|
||||
return SingleLogoutService::class;
|
||||
}
|
||||
|
||||
protected function getDescriptorType(ProfileContext $context)
|
||||
{
|
||||
$ssoSessionState = $context->getLogoutSsoSessionState();
|
||||
$ownEntityId = $context->getOwnEntityDescriptor()->getEntityID();
|
||||
|
||||
if ($ssoSessionState->getIdpEntityId() == $ownEntityId) {
|
||||
return SpSsoDescriptor::class;
|
||||
} elseif ($ssoSessionState->getSpEntityId() == $ownEntityId) {
|
||||
return IdpSsoDescriptor::class;
|
||||
} else {
|
||||
throw new LightSamlContextException($context, 'Unable to resolve logout target descriptor type');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Model\Metadata\AssertionConsumerService;
|
||||
|
||||
class ResolveEndpointSpAcsAction extends ResolveEndpointBaseAction
|
||||
{
|
||||
protected function getServiceType(ProfileContext $context)
|
||||
{
|
||||
return AssertionConsumerService::class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Model\Protocol\LogoutRequest;
|
||||
use LightSaml\State\Request\RequestState;
|
||||
use LightSaml\State\Request\RequestStateParameters;
|
||||
use LightSaml\Store\Request\RequestStateStoreInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class SaveRequestStateAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var RequestStateStoreInterface */
|
||||
protected $requestStore;
|
||||
|
||||
public function __construct(LoggerInterface $logger, RequestStateStoreInterface $requestStore)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->requestStore = $requestStore;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context->getOutboundContext());
|
||||
|
||||
$state = new RequestState();
|
||||
$state->setId($message->getID());
|
||||
|
||||
$partyEntityId = $context->getPartyEntityContext() ? $context->getPartyEntityContext()->getEntityId() : '';
|
||||
if ($context->getPartyEntityContext() && $context->getPartyEntityContext()->getEntityDescriptor()) {
|
||||
$partyEntityId = $context->getPartyEntityContext()->getEntityDescriptor()->getEntityID();
|
||||
}
|
||||
|
||||
$state->getParameters()->add([
|
||||
RequestStateParameters::ID => $message->getID(),
|
||||
RequestStateParameters::TYPE => get_class($message),
|
||||
RequestStateParameters::TIMESTAMP => $message->getIssueInstantTimestamp(),
|
||||
RequestStateParameters::PARTY => $partyEntityId,
|
||||
RequestStateParameters::RELAY_STATE => $message->getRelayState(),
|
||||
]);
|
||||
|
||||
if ($message instanceof LogoutRequest) {
|
||||
$state->getParameters()->add([
|
||||
RequestStateParameters::NAME_ID => $message->getNameID()->getValue(),
|
||||
RequestStateParameters::NAME_ID_FORMAT => $message->getNameID()->getFormat(),
|
||||
RequestStateParameters::SESSION_INDEX => $message->getSessionIndex(),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->requestStore->set($state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Binding\BindingFactoryInterface;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class SendMessageAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var BindingFactoryInterface */
|
||||
protected $bindingFactory;
|
||||
|
||||
public function __construct(LoggerInterface $logger, BindingFactoryInterface $bindingFactory)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->bindingFactory = $bindingFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function doExecute(ProfileContext $context)
|
||||
{
|
||||
$binding = $this->bindingFactory->create($context->getEndpoint()->getBinding());
|
||||
|
||||
$outboundContext = $context->getOutboundContext();
|
||||
|
||||
$context->getHttpResponseContext()->setResponse(
|
||||
$binding->send($outboundContext)
|
||||
);
|
||||
|
||||
$this->logger->info(
|
||||
'Sending message',
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'message' => $outboundContext->getSerializationContext()->getDocument()->saveXML(),
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
|
||||
class SetRelayStateAction extends AbstractProfileAction
|
||||
{
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
if ($context->getRelayState()) {
|
||||
$this->logger->debug(
|
||||
sprintf('RelayState from context set to outbound message: "%s"', $context->getRelayState()),
|
||||
LogHelper::getActionContext($context, $this)
|
||||
);
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setRelayState($context->getRelayState());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action\Profile\Outbound\Message;
|
||||
|
||||
use LightSaml\Action\Profile\AbstractProfileAction;
|
||||
use LightSaml\Context\Profile\Helper\LogHelper;
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\ProfileContext;
|
||||
use LightSaml\Model\Protocol\AuthnRequest;
|
||||
use LightSaml\Model\Protocol\LogoutRequest;
|
||||
use LightSaml\Model\Protocol\Response;
|
||||
use LightSaml\Resolver\Signature\SignatureResolverInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Signs the outbound message, according to TrustOptions settings.
|
||||
*/
|
||||
class SignMessageAction extends AbstractProfileAction
|
||||
{
|
||||
/** @var SignatureResolverInterface */
|
||||
protected $signatureResolver;
|
||||
|
||||
public function __construct(LoggerInterface $logger, SignatureResolverInterface $signatureResolver)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->signatureResolver = $signatureResolver;
|
||||
}
|
||||
|
||||
protected function doExecute(ProfileContext $context)
|
||||
{
|
||||
$shouldSign = $this->shouldSignMessage($context);
|
||||
if ($shouldSign) {
|
||||
$signature = $this->signatureResolver->getSignature($context);
|
||||
if ($signature) {
|
||||
MessageContextHelper::asSamlMessage($context->getOutboundContext())
|
||||
->setSignature($signature)
|
||||
;
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf('Message signed with fingerprint "%s"', $signature->getCertificate()->getFingerprint()),
|
||||
LogHelper::getActionContext($context, $this, [
|
||||
'certificate' => $signature->getCertificate()->getInfo(),
|
||||
])
|
||||
);
|
||||
} else {
|
||||
$this->logger->critical(
|
||||
'No signature resolved, although signing enabled',
|
||||
LogHelper::getActionErrorContext($context, $this, [])
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->logger->debug('Signing disabled', LogHelper::getActionContext($context, $this));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldSignMessage(ProfileContext $context)
|
||||
{
|
||||
$message = $context->getOutboundMessage();
|
||||
|
||||
if ($message instanceof LogoutRequest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$trustOptions = $context->getTrustOptions();
|
||||
|
||||
if ($message instanceof AuthnRequest) {
|
||||
return $trustOptions->getSignAuthnRequest();
|
||||
} elseif ($message instanceof Response) {
|
||||
return $trustOptions->getSignResponse();
|
||||
}
|
||||
|
||||
throw new \LogicException(sprintf('Unexpected message type "%s"', get_class($message)));
|
||||
}
|
||||
}
|
||||
32
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/WrappedAction.php
vendored
Normal file
32
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Action/WrappedAction.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Action;
|
||||
|
||||
use LightSaml\Context\ContextInterface;
|
||||
|
||||
abstract class WrappedAction implements ActionInterface
|
||||
{
|
||||
/**
|
||||
* @var ActionInterface
|
||||
*/
|
||||
protected $action;
|
||||
|
||||
public function __construct(ActionInterface $action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute(ContextInterface $context)
|
||||
{
|
||||
$this->beforeAction($context);
|
||||
$this->action->execute($context);
|
||||
$this->afterAction($context);
|
||||
}
|
||||
|
||||
abstract protected function beforeAction(ContextInterface $context);
|
||||
|
||||
abstract protected function afterAction(ContextInterface $context);
|
||||
}
|
||||
62
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/AbstractBinding.php
vendored
Normal file
62
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/AbstractBinding.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Binding;
|
||||
|
||||
use LightSaml\Context\Profile\MessageContext;
|
||||
use LightSaml\Event\MessageReceived;
|
||||
use LightSaml\Event\MessageSent;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
abstract class AbstractBinding
|
||||
{
|
||||
/** @var EventDispatcherInterface|null */
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* @return AbstractBinding
|
||||
*/
|
||||
public function setEventDispatcher(EventDispatcherInterface $eventDispatcher = null)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventDispatcherInterface|null
|
||||
*/
|
||||
public function getEventDispatcher()
|
||||
{
|
||||
return $this->eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $messageString
|
||||
*/
|
||||
protected function dispatchReceive($messageString)
|
||||
{
|
||||
if ($this->eventDispatcher) {
|
||||
$this->eventDispatcher->dispatch(new MessageReceived($messageString));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $messageString
|
||||
*/
|
||||
protected function dispatchSend($messageString)
|
||||
{
|
||||
if ($this->eventDispatcher) {
|
||||
$this->eventDispatcher->dispatch(new MessageSent($messageString));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $destination
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
abstract public function send(MessageContext $context, $destination = null);
|
||||
|
||||
abstract public function receive(Request $request, MessageContext $context);
|
||||
}
|
||||
133
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/BindingFactory.php
vendored
Normal file
133
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/BindingFactory.php
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Binding;
|
||||
|
||||
use LightSaml\Error\LightSamlBindingException;
|
||||
use LightSaml\SamlConstants;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class BindingFactory implements BindingFactoryInterface
|
||||
{
|
||||
/** @var EventDispatcherInterface|null */
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
*/
|
||||
public function __construct(EventDispatcherInterface $eventDispatcher = null)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BindingFactoryInterface
|
||||
*/
|
||||
public function setEventDispatcher(EventDispatcherInterface $eventDispatcher = null)
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractBinding
|
||||
*/
|
||||
public function getBindingByRequest(Request $request)
|
||||
{
|
||||
$bindingType = $this->detectBindingType($request);
|
||||
|
||||
return $this->create($bindingType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bindingType
|
||||
*
|
||||
* @throws \LogicException
|
||||
* @throws \LightSaml\Error\LightSamlBindingException
|
||||
*
|
||||
* @return AbstractBinding
|
||||
*/
|
||||
public function create($bindingType)
|
||||
{
|
||||
$result = null;
|
||||
switch ($bindingType) {
|
||||
case SamlConstants::BINDING_SAML2_HTTP_REDIRECT:
|
||||
$result = new HttpRedirectBinding();
|
||||
break;
|
||||
|
||||
case SamlConstants::BINDING_SAML2_HTTP_POST:
|
||||
$result = new HttpPostBinding();
|
||||
break;
|
||||
|
||||
case SamlConstants::BINDING_SAML2_HTTP_ARTIFACT:
|
||||
throw new \LogicException('Artifact binding not implemented');
|
||||
case SamlConstants::BINDING_SAML2_SOAP:
|
||||
throw new \LogicException('SOAP binding not implemented');
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$result->setEventDispatcher($this->eventDispatcher);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
throw new LightSamlBindingException(sprintf("Unknown binding type '%s'", $bindingType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function detectBindingType(Request $request)
|
||||
{
|
||||
$requestMethod = trim(strtoupper($request->getMethod()));
|
||||
if ('GET' == $requestMethod) {
|
||||
return $this->processGET($request);
|
||||
} elseif ('POST' == $requestMethod) {
|
||||
return $this->processPOST($request);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
protected function processGET(Request $request)
|
||||
{
|
||||
$get = $request->query->all();
|
||||
if (array_key_exists('SAMLRequest', $get) || array_key_exists('SAMLResponse', $get)) {
|
||||
return SamlConstants::BINDING_SAML2_HTTP_REDIRECT;
|
||||
} elseif (array_key_exists('SAMLart', $get)) {
|
||||
return SamlConstants::BINDING_SAML2_HTTP_ARTIFACT;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
protected function processPOST(Request $request)
|
||||
{
|
||||
$post = $request->request->all();
|
||||
if (array_key_exists('SAMLRequest', $post) || array_key_exists('SAMLResponse', $post)) {
|
||||
return SamlConstants::BINDING_SAML2_HTTP_POST;
|
||||
} elseif (array_key_exists('SAMLart', $post)) {
|
||||
return SamlConstants::BINDING_SAML2_HTTP_ARTIFACT;
|
||||
} else {
|
||||
if ($contentType = $request->headers->get('CONTENT_TYPE')) {
|
||||
// Remove charset
|
||||
if (false !== $pos = strpos($contentType, ';')) {
|
||||
$contentType = substr($contentType, 0, $pos);
|
||||
}
|
||||
|
||||
if ('text/xml' === $contentType) {
|
||||
return SamlConstants::BINDING_SAML2_SOAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
27
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/BindingFactoryInterface.php
vendored
Normal file
27
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/BindingFactoryInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Binding;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
interface BindingFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @return AbstractBinding
|
||||
*/
|
||||
public function getBindingByRequest(Request $request);
|
||||
|
||||
/**
|
||||
* @param string $bindingType
|
||||
*
|
||||
* @throws \LightSaml\Error\LightSamlBindingException
|
||||
*
|
||||
* @return AbstractBinding
|
||||
*/
|
||||
public function create($bindingType);
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function detectBindingType(Request $request);
|
||||
}
|
||||
69
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/HttpPostBinding.php
vendored
Normal file
69
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/HttpPostBinding.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Binding;
|
||||
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\MessageContext;
|
||||
use LightSaml\Error\LightSamlBindingException;
|
||||
use LightSaml\Model\Protocol\AbstractRequest;
|
||||
use LightSaml\Model\Protocol\SamlMessage;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class HttpPostBinding extends AbstractBinding
|
||||
{
|
||||
/**
|
||||
* @param string|null $destination
|
||||
*
|
||||
* @return SamlPostResponse
|
||||
*/
|
||||
public function send(MessageContext $context, $destination = null)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context);
|
||||
$destination = $message->getDestination() ? $message->getDestination() : $destination;
|
||||
|
||||
$serializationContext = $context->getSerializationContext();
|
||||
$message->serialize($serializationContext->getDocument(), $serializationContext);
|
||||
$msgStr = $serializationContext->getDocument()->saveXML();
|
||||
|
||||
$this->dispatchSend($msgStr);
|
||||
|
||||
$msgStr = base64_encode($msgStr);
|
||||
|
||||
$type = $message instanceof AbstractRequest ? 'SAMLRequest' : 'SAMLResponse';
|
||||
|
||||
$data = [$type => $msgStr];
|
||||
if ($message->getRelayState()) {
|
||||
$data['RelayState'] = $message->getRelayState();
|
||||
}
|
||||
|
||||
$result = new SamlPostResponse($destination, $data);
|
||||
$result->renderContent();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function receive(Request $request, MessageContext $context)
|
||||
{
|
||||
$post = $request->request->all();
|
||||
if (array_key_exists('SAMLRequest', $post)) {
|
||||
$msg = $post['SAMLRequest'];
|
||||
} elseif (array_key_exists('SAMLResponse', $post)) {
|
||||
$msg = $post['SAMLResponse'];
|
||||
} else {
|
||||
throw new LightSamlBindingException('Missing SAMLRequest or SAMLResponse parameter');
|
||||
}
|
||||
|
||||
$msg = base64_decode($msg);
|
||||
|
||||
$this->dispatchReceive($msg);
|
||||
|
||||
$deserializationContext = $context->getDeserializationContext();
|
||||
$result = SamlMessage::fromXML($msg, $deserializationContext);
|
||||
|
||||
if (array_key_exists('RelayState', $post)) {
|
||||
$result->setRelayState($post['RelayState']);
|
||||
}
|
||||
|
||||
$context->setMessage($result);
|
||||
}
|
||||
}
|
||||
277
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/HttpRedirectBinding.php
vendored
Normal file
277
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/HttpRedirectBinding.php
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Binding;
|
||||
|
||||
use LightSaml\Context\Profile\Helper\MessageContextHelper;
|
||||
use LightSaml\Context\Profile\MessageContext;
|
||||
use LightSaml\Error\LightSamlBindingException;
|
||||
use LightSaml\Model\Protocol\AbstractRequest;
|
||||
use LightSaml\Model\Protocol\SamlMessage;
|
||||
use LightSaml\Model\XmlDSig\SignatureStringReader;
|
||||
use LightSaml\Model\XmlDSig\SignatureWriter;
|
||||
use LightSaml\SamlConstants;
|
||||
use RobRichards\XMLSecLibs\XMLSecurityKey;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class HttpRedirectBinding extends AbstractBinding
|
||||
{
|
||||
/**
|
||||
* @param string|null $destination
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function send(MessageContext $context, $destination = null)
|
||||
{
|
||||
$destination = $context->getMessage()->getDestination() ? $context->getMessage()->getDestination() : $destination;
|
||||
|
||||
$url = $this->getRedirectURL($context, $destination);
|
||||
|
||||
return new RedirectResponse($url);
|
||||
}
|
||||
|
||||
public function receive(Request $request, MessageContext $context)
|
||||
{
|
||||
$data = $this->parseQuery($request);
|
||||
|
||||
$this->processData($data, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function processData(array $data, MessageContext $context)
|
||||
{
|
||||
$msg = $this->getMessageStringFromData($data);
|
||||
$encoding = $this->getEncodingFromData($data);
|
||||
$msg = $this->decodeMessageString($msg, $encoding);
|
||||
|
||||
$this->dispatchReceive($msg);
|
||||
|
||||
$deserializationContext = $context->getDeserializationContext();
|
||||
$message = SamlMessage::fromXML($msg, $deserializationContext);
|
||||
|
||||
$this->loadRelayState($message, $data);
|
||||
$this->loadSignature($message, $data);
|
||||
|
||||
$context->setMessage($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @throws LightSamlBindingException
|
||||
*/
|
||||
protected function getMessageStringFromData(array $data)
|
||||
{
|
||||
if (array_key_exists('SAMLRequest', $data)) {
|
||||
return $data['SAMLRequest'];
|
||||
} elseif (array_key_exists('SAMLResponse', $data)) {
|
||||
return $data['SAMLResponse'];
|
||||
} else {
|
||||
throw new LightSamlBindingException('Missing SAMLRequest or SAMLResponse parameter');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getEncodingFromData(array $data)
|
||||
{
|
||||
if (array_key_exists('SAMLEncoding', $data)) {
|
||||
return $data['SAMLEncoding'];
|
||||
} else {
|
||||
return SamlConstants::ENCODING_DEFLATE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
* @param string $encoding
|
||||
*
|
||||
* @throws \LightSaml\Error\LightSamlBindingException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeMessageString($msg, $encoding)
|
||||
{
|
||||
$msg = base64_decode($msg);
|
||||
switch ($encoding) {
|
||||
case SamlConstants::ENCODING_DEFLATE:
|
||||
return gzinflate($msg);
|
||||
break;
|
||||
default:
|
||||
throw new LightSamlBindingException(sprintf("Unknown encoding '%s'", $encoding));
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadRelayState(SamlMessage $message, array $data)
|
||||
{
|
||||
if (array_key_exists('RelayState', $data)) {
|
||||
$message->setRelayState($data['RelayState']);
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadSignature(SamlMessage $message, array $data)
|
||||
{
|
||||
if (array_key_exists('Signature', $data)) {
|
||||
if (false == array_key_exists('SigAlg', $data)) {
|
||||
throw new LightSamlBindingException('Missing signature algorithm');
|
||||
}
|
||||
$message->setSignature(
|
||||
new SignatureStringReader($data['Signature'], $data['SigAlg'], $data['SignedQuery'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $destination
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getRedirectURL(MessageContext $context, $destination)
|
||||
{
|
||||
$message = MessageContextHelper::asSamlMessage($context);
|
||||
$signature = $message->getSignature();
|
||||
if ($signature && false == $signature instanceof SignatureWriter) {
|
||||
throw new LightSamlBindingException('Signature must be SignatureWriter');
|
||||
}
|
||||
|
||||
$xml = $this->getMessageEncodedXml($message, $context);
|
||||
$msg = $this->addMessageToUrl($message, $xml);
|
||||
$this->addRelayStateToUrl($msg, $message);
|
||||
$this->addSignatureToUrl($msg, $signature);
|
||||
|
||||
return $this->getDestinationUrl($msg, $message, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getMessageEncodedXml(SamlMessage $message, MessageContext $context)
|
||||
{
|
||||
$message->setSignature(null);
|
||||
|
||||
$serializationContext = $context->getSerializationContext();
|
||||
$message->serialize($serializationContext->getDocument(), $serializationContext);
|
||||
$xml = $serializationContext->getDocument()->saveXML();
|
||||
|
||||
$this->dispatchSend($xml);
|
||||
|
||||
$xml = gzdeflate($xml);
|
||||
$xml = base64_encode($xml);
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function addMessageToUrl(SamlMessage $message, $xml)
|
||||
{
|
||||
if ($message instanceof AbstractRequest) {
|
||||
$msg = 'SAMLRequest=';
|
||||
} else {
|
||||
$msg = 'SAMLResponse=';
|
||||
}
|
||||
$msg .= urlencode($xml);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
*/
|
||||
protected function addRelayStateToUrl(&$msg, SamlMessage $message)
|
||||
{
|
||||
if (null !== $message->getRelayState()) {
|
||||
$msg .= '&RelayState=' . urlencode($message->getRelayState());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
*/
|
||||
protected function addSignatureToUrl(&$msg, SignatureWriter $signature = null)
|
||||
{
|
||||
/** @var $key XMLSecurityKey */
|
||||
$key = $signature ? $signature->getXmlSecurityKey() : null;
|
||||
|
||||
if (null != $key) {
|
||||
$msg .= '&SigAlg=' . urlencode($key->type);
|
||||
$signature = $key->signData($msg);
|
||||
$msg .= '&Signature=' . urlencode(base64_encode($signature));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
* @param string|null $destination
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDestinationUrl($msg, SamlMessage $message, $destination)
|
||||
{
|
||||
$destination = $message->getDestination() ? $message->getDestination() : $destination;
|
||||
if (false === strpos($destination, '?')) {
|
||||
$destination .= '?' . $msg;
|
||||
} else {
|
||||
$destination .= '&' . $msg;
|
||||
}
|
||||
|
||||
return $destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function parseQuery(Request $request)
|
||||
{
|
||||
/*
|
||||
* Parse the query string. We need to do this ourself, so that we get access
|
||||
* to the raw (urlencoded) values. This is required because different software
|
||||
* can urlencode to different values.
|
||||
*/
|
||||
$sigQuery = $relayState = $sigAlg = '';
|
||||
$data = $this->parseQueryString($request->server->get('QUERY_STRING'));
|
||||
$result = [];
|
||||
foreach ($data as $name => $value) {
|
||||
$result[$name] = urldecode($value);
|
||||
switch ($name) {
|
||||
case 'SAMLRequest':
|
||||
case 'SAMLResponse':
|
||||
$sigQuery = $name . '=' . $value;
|
||||
break;
|
||||
case 'RelayState':
|
||||
$relayState = '&RelayState=' . $value;
|
||||
break;
|
||||
case 'SigAlg':
|
||||
$sigAlg = '&SigAlg=' . $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$result['SignedQuery'] = $sigQuery . $relayState . $sigAlg;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $queryString
|
||||
* @return array
|
||||
*/
|
||||
protected function parseQueryString($queryString)
|
||||
{
|
||||
$result = [];
|
||||
foreach (explode('&', $queryString ?: '') as $e) {
|
||||
$tmp = explode('=', $e, 2);
|
||||
$name = $tmp[0];
|
||||
$value = 2 === count($tmp) ? $tmp[1] : '';
|
||||
$name = urldecode($name);
|
||||
$result[$name] = $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
86
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/SamlPostResponse.php
vendored
Normal file
86
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Binding/SamlPostResponse.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Binding;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SamlPostResponse extends Response
|
||||
{
|
||||
/** @var string */
|
||||
protected $destination;
|
||||
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @param string $destination
|
||||
* @param int $status
|
||||
* @param array $headers
|
||||
*/
|
||||
public function __construct($destination, array $data, $status = 200, $headers = [])
|
||||
{
|
||||
parent::__construct('', $status, $headers);
|
||||
|
||||
$this->destination = $destination;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDestination()
|
||||
{
|
||||
return $this->destination;
|
||||
}
|
||||
|
||||
public function renderContent()
|
||||
{
|
||||
$content = <<<'EOT'
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>POST data</title>
|
||||
</head>
|
||||
<body onload="document.getElementById('a-very-unique-input-id#lightSAML').click();">
|
||||
|
||||
<noscript>
|
||||
<p><strong>Note:</strong> Since your browser does not support JavaScript, you must press the button below once to proceed.</p>
|
||||
</noscript>
|
||||
|
||||
<form method="post" action="%s">
|
||||
<input id="a-very-unique-input-id#lightSAML" type="submit" style="display:none;"/>
|
||||
|
||||
%s
|
||||
|
||||
<noscript>
|
||||
<input type="submit" value="Submit" />
|
||||
</noscript>
|
||||
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
EOT;
|
||||
$fields = '';
|
||||
foreach ($this->data as $name => $value) {
|
||||
$fields .= sprintf(
|
||||
'<input type="hidden" name="%s" value="%s" />',
|
||||
htmlspecialchars($name),
|
||||
htmlspecialchars($value)
|
||||
);
|
||||
}
|
||||
|
||||
$content = sprintf($content, htmlspecialchars($this->destination ?? ''), $fields);
|
||||
|
||||
$this->setContent($content);
|
||||
}
|
||||
}
|
||||
24
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/AbstractPimpleContainer.php
vendored
Normal file
24
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/AbstractPimpleContainer.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container;
|
||||
|
||||
use Pimple\Container;
|
||||
|
||||
abstract class AbstractPimpleContainer
|
||||
{
|
||||
/** @var Container */
|
||||
protected $pimple;
|
||||
|
||||
public function __construct(Container $pimple)
|
||||
{
|
||||
$this->pimple = $pimple;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Container
|
||||
*/
|
||||
public function getPimple()
|
||||
{
|
||||
return $this->pimple;
|
||||
}
|
||||
}
|
||||
120
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/BuildContainer.php
vendored
Normal file
120
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/BuildContainer.php
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container;
|
||||
|
||||
use LightSaml\Build\Container\BuildContainerInterface;
|
||||
use LightSaml\Build\Container\CredentialContainerInterface;
|
||||
use LightSaml\Build\Container\OwnContainerInterface;
|
||||
use LightSaml\Build\Container\PartyContainerInterface;
|
||||
use LightSaml\Build\Container\ProviderContainerInterface;
|
||||
use LightSaml\Build\Container\ServiceContainerInterface;
|
||||
use LightSaml\Build\Container\StoreContainerInterface;
|
||||
use LightSaml\Build\Container\SystemContainerInterface;
|
||||
|
||||
class BuildContainer extends AbstractPimpleContainer implements BuildContainerInterface
|
||||
{
|
||||
/** @var SystemContainerInterface */
|
||||
private $systemContainer;
|
||||
|
||||
/** @var PartyContainerInterface */
|
||||
private $partyContainer;
|
||||
|
||||
/** @var StoreContainerInterface */
|
||||
private $storeContainer;
|
||||
|
||||
/** @var ProviderContainerInterface */
|
||||
private $providerContainer;
|
||||
|
||||
/** @var CredentialContainerInterface */
|
||||
private $credentialContainer;
|
||||
|
||||
/** @var ServiceContainerInterface */
|
||||
private $serviceContainer;
|
||||
|
||||
/** @var OwnContainerInterface */
|
||||
private $ownContainer;
|
||||
|
||||
/**
|
||||
* @return SystemContainerInterface
|
||||
*/
|
||||
public function getSystemContainer()
|
||||
{
|
||||
if (null == $this->systemContainer) {
|
||||
$this->systemContainer = new SystemContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->systemContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PartyContainerInterface
|
||||
*/
|
||||
public function getPartyContainer()
|
||||
{
|
||||
if (null == $this->partyContainer) {
|
||||
$this->partyContainer = new PartyContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->partyContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StoreContainerInterface
|
||||
*/
|
||||
public function getStoreContainer()
|
||||
{
|
||||
if (null == $this->storeContainer) {
|
||||
$this->storeContainer = new StoreContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->storeContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProviderContainerInterface
|
||||
*/
|
||||
public function getProviderContainer()
|
||||
{
|
||||
if (null == $this->providerContainer) {
|
||||
$this->providerContainer = new ProviderContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->providerContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CredentialContainerInterface
|
||||
*/
|
||||
public function getCredentialContainer()
|
||||
{
|
||||
if (null == $this->credentialContainer) {
|
||||
$this->credentialContainer = new CredentialContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->credentialContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServiceContainerInterface
|
||||
*/
|
||||
public function getServiceContainer()
|
||||
{
|
||||
if (null == $this->serviceContainer) {
|
||||
$this->serviceContainer = new ServiceContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->serviceContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OwnContainerInterface
|
||||
*/
|
||||
public function getOwnContainer()
|
||||
{
|
||||
if (null == $this->ownContainer) {
|
||||
$this->ownContainer = new OwnContainer($this->pimple);
|
||||
}
|
||||
|
||||
return $this->ownContainer;
|
||||
}
|
||||
}
|
||||
19
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/CredentialContainer.php
vendored
Normal file
19
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/CredentialContainer.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container;
|
||||
|
||||
use LightSaml\Build\Container\CredentialContainerInterface;
|
||||
use LightSaml\Store\Credential\CredentialStoreInterface;
|
||||
|
||||
class CredentialContainer extends AbstractPimpleContainer implements CredentialContainerInterface
|
||||
{
|
||||
public const CREDENTIAL_STORE = 'lightsaml.container.credential_store';
|
||||
|
||||
/**
|
||||
* @return CredentialStoreInterface
|
||||
*/
|
||||
public function getCredentialStore()
|
||||
{
|
||||
return $this->pimple[self::CREDENTIAL_STORE];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Bridge\Pimple\Container\CredentialContainer;
|
||||
use LightSaml\Build\Container\OwnContainerInterface;
|
||||
use LightSaml\Build\Container\PartyContainerInterface;
|
||||
use LightSaml\Credential\CredentialInterface;
|
||||
use LightSaml\Error\LightSamlBuildException;
|
||||
use LightSaml\Store\Credential\Factory\CredentialFactory;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
class CredentialContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/** @var PartyContainerInterface */
|
||||
private $partyContainer;
|
||||
|
||||
/** @var OwnContainerInterface */
|
||||
private $ownContainer;
|
||||
|
||||
/** @var CredentialInterface[] */
|
||||
private $extraCredentials = [];
|
||||
|
||||
public function __construct(PartyContainerInterface $partyContainer, OwnContainerInterface $ownContainer)
|
||||
{
|
||||
$this->ownContainer = $ownContainer;
|
||||
$this->partyContainer = $partyContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CredentialContainerProvider
|
||||
*/
|
||||
public function addExtraCredential(CredentialInterface $credential)
|
||||
{
|
||||
if (null === $credential->getEntityId()) {
|
||||
throw new \InvalidArgumentException('Extra credential must have entityID');
|
||||
}
|
||||
|
||||
$this->extraCredentials[] = $credential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$ownCredentials = $this->ownContainer->getOwnCredentials();
|
||||
if (empty($ownCredentials)) {
|
||||
throw new LightSamlBuildException('There are no own credentials');
|
||||
}
|
||||
|
||||
$pimple[CredentialContainer::CREDENTIAL_STORE] = function () {
|
||||
$factory = new CredentialFactory();
|
||||
|
||||
return $factory->build(
|
||||
$this->partyContainer->getIdpEntityDescriptorStore(),
|
||||
$this->partyContainer->getSpEntityDescriptorStore(),
|
||||
$this->ownContainer->getOwnCredentials(),
|
||||
$this->extraCredentials
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Bridge\Pimple\Container\OwnContainer;
|
||||
use LightSaml\Credential\CredentialInterface;
|
||||
use LightSaml\Error\LightSamlBuildException;
|
||||
use LightSaml\Provider\EntityDescriptor\EntityDescriptorProviderInterface;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
class OwnContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/** @var CredentialInterface[] */
|
||||
private $ownCredentials = [];
|
||||
|
||||
/** @var EntityDescriptorProviderInterface */
|
||||
private $ownEntityDescriptorProvider;
|
||||
|
||||
/**
|
||||
* @param CredentialInterface[] $ownCredentials
|
||||
*/
|
||||
public function __construct(EntityDescriptorProviderInterface $ownEntityDescriptorProvider, array $ownCredentials = null)
|
||||
{
|
||||
$this->ownEntityDescriptorProvider = $ownEntityDescriptorProvider;
|
||||
if ($ownCredentials) {
|
||||
foreach ($ownCredentials as $credential) {
|
||||
$this->addOwnCredential($credential);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OwnContainerProvider
|
||||
*/
|
||||
public function addOwnCredential(CredentialInterface $credential)
|
||||
{
|
||||
if (null == $credential->getPrivateKey()) {
|
||||
throw new LightSamlBuildException('Own credential must have private key');
|
||||
}
|
||||
|
||||
$this->ownCredentials[] = $credential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$pimple[OwnContainer::OWN_CREDENTIALS] = function () {
|
||||
return $this->ownCredentials;
|
||||
};
|
||||
|
||||
$pimple[OwnContainer::OWN_ENTITY_DESCRIPTOR_PROVIDER] = function () {
|
||||
return $this->ownEntityDescriptorProvider;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Bridge\Pimple\Container\PartyContainer;
|
||||
use LightSaml\Meta\TrustOptions\TrustOptions;
|
||||
use LightSaml\Store\EntityDescriptor\FixedEntityDescriptorStore;
|
||||
use LightSaml\Store\TrustOptions\FixedTrustOptionsStore;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
class PartyContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$pimple[PartyContainer::IDP_ENTITY_DESCRIPTOR] = function () {
|
||||
return new FixedEntityDescriptorStore();
|
||||
};
|
||||
|
||||
$pimple[PartyContainer::SP_ENTITY_DESCRIPTOR] = function () {
|
||||
return new FixedEntityDescriptorStore();
|
||||
};
|
||||
|
||||
$pimple[PartyContainer::TRUST_OPTIONS_STORE] = function () {
|
||||
return new FixedTrustOptionsStore(new TrustOptions());
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Bridge\Pimple\Container\ProviderContainer;
|
||||
use LightSaml\Error\LightSamlBuildException;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
class ProviderContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$pimple[ProviderContainer::ATTRIBUTE_VALUE_PROVIDER] = function () {
|
||||
throw new LightSamlBuildException('Attribute value provider not set');
|
||||
};
|
||||
|
||||
$pimple[ProviderContainer::SESSION_INFO_PROVIDER] = function () {
|
||||
throw new LightSamlBuildException('Session info provider not set');
|
||||
};
|
||||
|
||||
$pimple[ProviderContainer::NAME_ID_PROVIDER] = function () {
|
||||
throw new LightSamlBuildException('Name ID provider not set');
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Binding\BindingFactory;
|
||||
use LightSaml\Bridge\Pimple\Container\ServiceContainer;
|
||||
use LightSaml\Build\Container\CredentialContainerInterface;
|
||||
use LightSaml\Build\Container\StoreContainerInterface;
|
||||
use LightSaml\Build\Container\SystemContainerInterface;
|
||||
use LightSaml\Resolver\Credential\Factory\CredentialResolverFactory;
|
||||
use LightSaml\Resolver\Endpoint\BindingEndpointResolver;
|
||||
use LightSaml\Resolver\Endpoint\CompositeEndpointResolver;
|
||||
use LightSaml\Resolver\Endpoint\DescriptorTypeEndpointResolver;
|
||||
use LightSaml\Resolver\Endpoint\IndexEndpointResolver;
|
||||
use LightSaml\Resolver\Endpoint\LocationEndpointResolver;
|
||||
use LightSaml\Resolver\Endpoint\ServiceTypeEndpointResolver;
|
||||
use LightSaml\Resolver\Session\SessionProcessor;
|
||||
use LightSaml\Resolver\Signature\OwnSignatureResolver;
|
||||
use LightSaml\Validator\Model\Assertion\AssertionTimeValidator;
|
||||
use LightSaml\Validator\Model\Assertion\AssertionValidator;
|
||||
use LightSaml\Validator\Model\NameId\NameIdValidator;
|
||||
use LightSaml\Validator\Model\Signature\SignatureValidator;
|
||||
use LightSaml\Validator\Model\Statement\StatementValidator;
|
||||
use LightSaml\Validator\Model\Subject\SubjectValidator;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
class ServiceContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/** @var CredentialContainerInterface */
|
||||
private $credentialContainer;
|
||||
|
||||
/** @var SystemContainerInterface */
|
||||
private $systemContainer;
|
||||
|
||||
/** @var StoreContainerInterface */
|
||||
private $storeContainer;
|
||||
|
||||
public function __construct(
|
||||
CredentialContainerInterface $credentialContainer,
|
||||
StoreContainerInterface $storeContainer,
|
||||
SystemContainerInterface $systemContainer
|
||||
) {
|
||||
$this->credentialContainer = $credentialContainer;
|
||||
$this->storeContainer = $storeContainer;
|
||||
$this->systemContainer = $systemContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$pimple[ServiceContainer::NAME_ID_VALIDATOR] = function () {
|
||||
return new NameIdValidator();
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::ASSERTION_TIME_VALIDATOR] = function () {
|
||||
return new AssertionTimeValidator();
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::ASSERTION_VALIDATOR] = function (Container $c) {
|
||||
$nameIdValidator = $c[ServiceContainer::NAME_ID_VALIDATOR];
|
||||
|
||||
return new AssertionValidator(
|
||||
$nameIdValidator,
|
||||
new SubjectValidator($nameIdValidator),
|
||||
new StatementValidator()
|
||||
);
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::ENDPOINT_RESOLVER] = function () {
|
||||
return new CompositeEndpointResolver([
|
||||
new BindingEndpointResolver(),
|
||||
new DescriptorTypeEndpointResolver(),
|
||||
new ServiceTypeEndpointResolver(),
|
||||
new IndexEndpointResolver(),
|
||||
new LocationEndpointResolver(),
|
||||
]);
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::BINDING_FACTORY] = function () {
|
||||
return new BindingFactory($this->systemContainer->getEventDispatcher());
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::CREDENTIAL_RESOLVER] = function () {
|
||||
$factory = new CredentialResolverFactory($this->credentialContainer->getCredentialStore());
|
||||
|
||||
return $factory->build();
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::SIGNATURE_RESOLVER] = function (Container $c) {
|
||||
$credentialResolver = $c[ServiceContainer::CREDENTIAL_RESOLVER];
|
||||
|
||||
return new OwnSignatureResolver($credentialResolver);
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::SIGNATURE_VALIDATOR] = function (Container $c) {
|
||||
$credentialResolver = $c[ServiceContainer::CREDENTIAL_RESOLVER];
|
||||
|
||||
return new SignatureValidator($credentialResolver);
|
||||
};
|
||||
|
||||
$pimple[ServiceContainer::SESSION_PROCESSOR] = function () {
|
||||
return new SessionProcessor($this->storeContainer->getSsoStateStore(), $this->systemContainer->getTimeProvider());
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Bridge\Pimple\Container\StoreContainer;
|
||||
use LightSaml\Build\Container\SystemContainerInterface;
|
||||
use LightSaml\Store\Id\NullIdStore;
|
||||
use LightSaml\Store\Request\RequestStateSessionStore;
|
||||
use LightSaml\Store\Sso\SsoStateSessionStore;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
class StoreContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/** @var SystemContainerInterface */
|
||||
private $systemContainer;
|
||||
|
||||
public function __construct(SystemContainerInterface $systemContainer)
|
||||
{
|
||||
$this->systemContainer = $systemContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$pimple[StoreContainer::REQUEST_STATE_STORE] = function () {
|
||||
return new RequestStateSessionStore($this->systemContainer->getSession(), 'main');
|
||||
};
|
||||
|
||||
$pimple[StoreContainer::ID_STATE_STORE] = function () {
|
||||
return new NullIdStore();
|
||||
};
|
||||
|
||||
$pimple[StoreContainer::SSO_STATE_STORE] = function () {
|
||||
return new SsoStateSessionStore($this->systemContainer->getSession(), 'samlsso');
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container\Factory;
|
||||
|
||||
use LightSaml\Bridge\Pimple\Container\SystemContainer;
|
||||
use LightSaml\Provider\TimeProvider\SystemTimeProvider;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
|
||||
class SystemContainerProvider implements ServiceProviderInterface
|
||||
{
|
||||
/** @var bool */
|
||||
private $mockSession;
|
||||
|
||||
/** @var EventDispatcherInterface|null */
|
||||
private $eventDispatcher;
|
||||
|
||||
public function __construct($mockSession = false, EventDispatcherInterface $eventDispatcher = null)
|
||||
{
|
||||
$this->mockSession = $mockSession;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Container $pimple A container instance
|
||||
*/
|
||||
public function register(Container $pimple)
|
||||
{
|
||||
$pimple[SystemContainer::REQUEST] = function () {
|
||||
return Request::createFromGlobals();
|
||||
};
|
||||
|
||||
$pimple[SystemContainer::SESSION] = function () {
|
||||
if ($this->mockSession) {
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
} else {
|
||||
$session = new Session();
|
||||
}
|
||||
$session->setName(sprintf('SID%s', mt_rand(1000, 9999)));
|
||||
$session->start();
|
||||
|
||||
return $session;
|
||||
};
|
||||
|
||||
$pimple[SystemContainer::TIME_PROVIDER] = function () {
|
||||
return new SystemTimeProvider();
|
||||
};
|
||||
|
||||
$pimple[SystemContainer::EVENT_DISPATCHER] = function () {
|
||||
return $this->eventDispatcher;
|
||||
};
|
||||
|
||||
$pimple[SystemContainer::LOGGER] = function () {
|
||||
return new NullLogger();
|
||||
};
|
||||
}
|
||||
}
|
||||
29
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/OwnContainer.php
vendored
Normal file
29
qa-tool/htdocs/vendor/litesaml/lightsaml/src/Bridge/Pimple/Container/OwnContainer.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace LightSaml\Bridge\Pimple\Container;
|
||||
|
||||
use LightSaml\Build\Container\OwnContainerInterface;
|
||||
use LightSaml\Credential\CredentialInterface;
|
||||
use LightSaml\Provider\EntityDescriptor\EntityDescriptorProviderInterface;
|
||||
|
||||
class OwnContainer extends AbstractPimpleContainer implements OwnContainerInterface
|
||||
{
|
||||
public const OWN_ENTITY_DESCRIPTOR_PROVIDER = 'lightsaml.container.own_entity_descriptor_provider';
|
||||
public const OWN_CREDENTIALS = 'lightsaml.container.own_credentials';
|
||||
|
||||
/**
|
||||
* @return EntityDescriptorProviderInterface
|
||||
*/
|
||||
public function getOwnEntityDescriptorProvider()
|
||||
{
|
||||
return $this->pimple[self::OWN_ENTITY_DESCRIPTOR_PROVIDER];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CredentialInterface[]
|
||||
*/
|
||||
public function getOwnCredentials()
|
||||
{
|
||||
return $this->pimple[self::OWN_CREDENTIALS];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user