diff --git a/lib/SimpleSAML/Auth/Source.php b/lib/SimpleSAML/Auth/Source.php index 349d097df7810f252812418a5523768f45984c0d..44cd69a727cb0788a46837ef38a3725785c69275 100644 --- a/lib/SimpleSAML/Auth/Source.php +++ b/lib/SimpleSAML/Auth/Source.php @@ -1,5 +1,6 @@ <?php +use SimpleSAML\Auth\SourceFactory; /** * This class defines a base class for authentication source. @@ -295,11 +296,26 @@ abstract class SimpleSAML_Auth_Source self::validateSource($config, $authId); - $className = SimpleSAML\Module::resolveClass($config[0], 'Auth_Source', 'SimpleSAML_Auth_Source'); - + $id = $config[0]; $info = array('AuthId' => $authId); + $authSource = null; + unset($config[0]); - return new $className($info, $config); + + try { + // Check whether or not there's a factory responsible for instantiating our Auth Source instance + $factoryClass = SimpleSAML\Module::resolveClass($id, 'Auth_Source_Factory', 'SimpleSAML\Auth\SourceFactory'); + + /** @var SourceFactory $factory */ + $factory = new $factoryClass; + $authSource = $factory->create($info, $config); + } catch (Exception $e) { + // If not, instantiate the Auth Source here + $className = SimpleSAML\Module::resolveClass($id, 'Auth_Source', 'SimpleSAML_Auth_Source'); + $authSource = new $className($info, $config); + } + + return $authSource; } diff --git a/lib/SimpleSAML/Auth/SourceFactory.php b/lib/SimpleSAML/Auth/SourceFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..1cc6a6c9ae1f574399ec22fcc7582a60dd9a4a7e --- /dev/null +++ b/lib/SimpleSAML/Auth/SourceFactory.php @@ -0,0 +1,15 @@ +<?php + +namespace SimpleSAML\Auth; + +use SimpleSAML_Auth_Source; + +interface SourceFactory +{ + /** + * @param array $info + * @param array $config + * @return SimpleSAML_Auth_Source + */ + public function create(array $info, array $config); +} diff --git a/tests/lib/SimpleSAML/Auth/SourceTest.php b/tests/lib/SimpleSAML/Auth/SourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0cbf1e849027d7bf63493d449160591915dad832 --- /dev/null +++ b/tests/lib/SimpleSAML/Auth/SourceTest.php @@ -0,0 +1,42 @@ +<?php + +namespace SimpleSAML\Test\Auth; + +use SimpleSAML\Auth\SourceFactory; +use SimpleSAML\Test\Utils\ClearStateTestCase; + +/** + * Tests for SimpleSAML_Auth_Source + */ +class SourceTest extends ClearStateTestCase +{ + public function testParseAuthSource() + { + $class = new \ReflectionClass('SimpleSAML_Auth_Source'); + $method = $class->getMethod('parseAuthSource'); + $method->setAccessible(true); + + // test direct instantiation of the auth source object + $authSource = $method->invokeArgs(null, ['test', ['SimpleSAML\Test\Auth\TestAuthSource']]); + $this->assertInstanceOf('SimpleSAML\Test\Auth\TestAuthSource', $authSource); + + // test instantiation via an auth source factory + $authSource = $method->invokeArgs(null, ['test', ['SimpleSAML\Test\Auth\TestAuthSourceFactory']]); + $this->assertInstanceOf('SimpleSAML\Test\Auth\TestAuthSource', $authSource); + } +} + +class TestAuthSource extends \SimpleSAML_Auth_Source +{ + public function authenticate(&$state) + { + } +} + +class TestAuthSourceFactory implements SourceFactory +{ + public function create(array $info, array $config) + { + return new TestAuthSource($info, $config); + } +}