diff --git a/DependencyInjection/AuthserverOAuthAccountExtension.php b/DependencyInjection/AuthserverOAuthAccountExtension.php
index f7512c5..d7b58b7 100644
--- a/DependencyInjection/AuthserverOAuthAccountExtension.php
+++ b/DependencyInjection/AuthserverOAuthAccountExtension.php
@@ -34,14 +34,19 @@ use vierbergenlars\AuthserverOAuthAccountBundle\ResourceOwner\ResourceOwnerConfi
class AuthserverOAuthAccountExtension extends Extension implements PrependExtensionInterface
{
+
const USER_PROVIDER_SERVICE = 'vierbergenlars.authserver_oauth_account.user_provider';
+ const RESOURCE_OWNER_MAP_SERVICE = 'vierbergenlars.authserver_oauth_account.resource_owner_map';
+
public function prepend(ContainerBuilder $container)
{
$container->prependExtensionConfig('hwi_oauth', [
- 'firewall_names' => ['public'],
+ 'firewall_names' => [
+ 'public'
+ ],
'connect' => [
- 'account_connector' => self::USER_PROVIDER_SERVICE,
+ 'account_connector' => self::USER_PROVIDER_SERVICE
]
]);
@@ -50,46 +55,45 @@ class AuthserverOAuthAccountExtension extends Extension implements PrependExtens
$processor = new Processor();
$config = $processor->processConfiguration(new Configuration(), $configs);
$container->prependExtensionConfig('hwi_oauth', [
- 'resource_owners' => array_map(function($resource_owner) {
+ 'resource_owners' => array_map(function ($resource_owner) {
return $resource_owner['config'];
- }, $config['resource_owners']),
+ }, $config['resource_owners'])
]);
$container->loadFromExtension('security', [
'firewalls' => [
'public' => [
'oauth' => [
- 'resource_owners' => array_combine(array_keys($config['resource_owners']), array_map(function($roName) {
- return '/login/oauth/'.$roName;
+ 'resource_owners' => array_combine(array_keys($config['resource_owners']), array_map(function ($roName) {
+ return '/login/oauth/' . $roName;
}, array_keys($config['resource_owners']))),
'login_path' => 'app_login',
'failure_path' => 'app_login',
'oauth_user_provider' => [
- 'service' => self::USER_PROVIDER_SERVICE,
- ],
- ],
+ 'service' => self::USER_PROVIDER_SERVICE
+ ]
+ ]
]
- ],
+ ]
]);
}
public function load(array $configs, ContainerBuilder $container)
{
- $servicesDirectory = __DIR__.'/../Resources/config';
+ $servicesDirectory = __DIR__ . '/../Resources/config';
$fileLocator = new FileLocator($servicesDirectory);
$xmlLoader = new Loader\XmlFileLoader($container, $fileLocator);
$xmlLoader->load('services.xml');
$processor = new Processor();
$config = $processor->processConfiguration(new Configuration(), $configs);
+ $container->getDefinition(self::RESOURCE_OWNER_MAP_SERVICE)->setArgument(0, $config['resource_owners']);
- foreach($config['resource_owners'] as $name => $config)
- {
+ foreach ($config['resource_owners'] as $name => $config) {
$service = new DefinitionDecorator('vierbergenlars.authserver_oauth_account.external_account_provider.abstract');
$service->replaceArgument(0, $name);
- $service->replaceArgument(1, $config);
$service->addTag(AuthserverExternalAccountBundle::EXTERNAL_ACCOUNT_PROVIDER_TAG);
- $container->setDefinition('vierbergenlars.authserver_oauth_account.external_account_provider.impl.'.$name, $service);
+ $container->setDefinition('vierbergenlars.authserver_oauth_account.external_account_provider.impl.' . $name, $service);
}
}
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 0649397..eb10739 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -17,7 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
namespace vierbergenlars\AuthserverOAuthAccountBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@@ -30,15 +29,17 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
*/
class Configuration implements ConfigurationInterface
{
+
/**
- * {@inheritDoc}
+ *
+ * {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('oauth');
-
+ // @formatter:off
$rootNode->children()
->arrayNode('resource_owners')
->useAttributeAsKey('name')
@@ -49,6 +50,7 @@ class Configuration implements ConfigurationInterface
->end()
->scalarNode('service_name')->isRequired()->end()
->scalarNode('icon')->defaultNull()->end()
+ ->booleanNode('trust_email_verification')->defaultFalse()->end()
->arrayNode('login_button')
->addDefaultsIfNotSet()
->children()
@@ -68,7 +70,7 @@ class Configuration implements ConfigurationInterface
->end()
->end()
;
-
+ // @formatter:on
// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
diff --git a/EventListener/RegistrationHandlerListener.php b/EventListener/RegistrationHandlerListener.php
index 6da310a..6029145 100644
--- a/EventListener/RegistrationHandlerListener.php
+++ b/EventListener/RegistrationHandlerListener.php
@@ -27,6 +27,7 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInt
use vierbergenlars\AuthserverOAuthAccountBundle\Entity\TemporaryUser;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\EmailAddress;
+use vierbergenlars\AuthserverOAuthAccountBundle\ResourceOwner\ResourceOwnerMap;
class RegistrationHandlerListener implements EventSubscriberInterface
{
@@ -43,6 +44,12 @@ class RegistrationHandlerListener implements EventSubscriberInterface
*/
private $em;
+ /**
+ *
+ * @var ResourceOwnerMap
+ */
+ private $resourceOwnerMap;
+
public static function getSubscribedEvents()
{
return [
@@ -57,10 +64,11 @@ class RegistrationHandlerListener implements EventSubscriberInterface
];
}
- public function __construct(EntityManagerInterface $em, TokenStorageInterface $tokenStorage)
+ public function __construct(EntityManagerInterface $em, TokenStorageInterface $tokenStorage, ResourceOwnerMap $resourceOwnerMap)
{
$this->em = $em;
$this->tokenStorage = $tokenStorage;
+ $this->resourceOwnerMap = $resourceOwnerMap;
}
private function getTemporaryUser()
@@ -96,6 +104,9 @@ class RegistrationHandlerListener implements EventSubscriberInterface
return;
/* @var $user \App\Entity\User */
if ($temporaryUser = $this->getTemporaryUser()) {
+ if (!$this->resourceOwnerMap->getOwnerFromExternalUser($temporaryUser->getExternalUser())
+ ->isTrustEmailVerification())
+ return;
if ($temporaryUser->getEmail() && $temporaryUser->getEmail() === $user->getPrimaryEmailAddress()->getEmail()) {
$user->getPrimaryEmailAddress()->setVerified(true);
}
diff --git a/ExternalAccount/OAuthExternalAccountProvider.php b/ExternalAccount/OAuthExternalAccountProvider.php
index 46ceec0..8b87dee 100644
--- a/ExternalAccount/OAuthExternalAccountProvider.php
+++ b/ExternalAccount/OAuthExternalAccountProvider.php
@@ -17,41 +17,46 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
namespace vierbergenlars\AuthserverOAuthAccountBundle\ExternalAccount;
-
use HWI\Bundle\OAuthBundle\Security\OAuthUtils;
use Symfony\Component\HttpFoundation\Request;
use vierbergenlars\AuthserverExternalAccountBundle\ExternalAccount\ExternalAccountProviderInterface;
use vierbergenlars\AuthserverExternalAccountBundle\ValueObject\Button;
use vierbergenlars\AuthserverOAuthAccountBundle\ResourceOwner\ResourceOwnerConfig;
+use vierbergenlars\AuthserverOAuthAccountBundle\ResourceOwner\ResourceOwnerMap;
class OAuthExternalAccountProvider implements ExternalAccountProviderInterface
{
+
/**
+ *
* @var ResourceOwnerConfig
*/
private $resourceOwnerConfig;
+
/**
+ *
* @var
*/
private $name;
+
/**
+ *
* @var OAuthUtils
*/
private $OAuthUtils;
- public function __construct($name, $resourceOwnerConfig, OAuthUtils $OAuthUtils)
+ public function __construct($name, ResourceOwnerMap $resourceOwnerMap, OAuthUtils $OAuthUtils)
{
- $this->resourceOwnerConfig = new ResourceOwnerConfig($resourceOwnerConfig);
+ $this->resourceOwnerConfig = $resourceOwnerMap[$name];
$this->name = $name;
$this->OAuthUtils = $OAuthUtils;
}
public function getName()
{
- return 'oauth_'.$this->name;
+ return 'oauth_' . $this->name;
}
public function getServiceName()
@@ -67,15 +72,15 @@ class OAuthExternalAccountProvider implements ExternalAccountProviderInterface
public function getLoginButton()
{
return new Button($this->resourceOwnerConfig->getLoginButton() + [
- 'url' => $this->OAuthUtils->getLoginUrl(new Request(), $this->name),
+ 'url' => $this->OAuthUtils->getLoginUrl(new Request(), $this->name)
]);
}
public function getConnectButton()
{
return new Button($this->resourceOwnerConfig->getConnectButton() + [
- 'url' => $this->OAuthUtils->getLoginUrl(new Request(), $this->name),
- ]);
+ 'url' => $this->OAuthUtils->getLoginUrl(new Request(), $this->name)
+ ]);
}
public function hasConnect()
diff --git a/ResourceOwner/ResourceOwnerConfig.php b/ResourceOwner/ResourceOwnerConfig.php
index e3fd3d0..9b9b5bd 100644
--- a/ResourceOwner/ResourceOwnerConfig.php
+++ b/ResourceOwner/ResourceOwnerConfig.php
@@ -17,20 +17,19 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
namespace vierbergenlars\AuthserverOAuthAccountBundle\ResourceOwner;
-
class ResourceOwnerConfig
{
+
/**
+ *
* @var array
*/
private $config;
public function __construct(array $config)
{
-
$this->config = $config;
}
@@ -39,6 +38,11 @@ class ResourceOwnerConfig
return $this->config['config'];
}
+ public function isTrustEmailVerification()
+ {
+ return $this->config['trust_email_verification'];
+ }
+
public function getServiceName()
{
return $this->config['service_name'];
@@ -52,11 +56,11 @@ class ResourceOwnerConfig
public function getLoginButton()
{
$config = $this->config['login_button'];
- foreach([
- 'icon' => $this->getIcon(),
- 'label' => $this->getServiceName().' Login',
- ] as $k=>$v)
- $config[$k] = $config[$k]?:$v;
+ foreach ([
+ 'icon' => $this->getIcon(),
+ 'label' => $this->getServiceName() . ' Login'
+ ] as $k => $v)
+ $config[$k] = $config[$k] ?: $v;
return $config;
}
@@ -64,13 +68,12 @@ class ResourceOwnerConfig
public function getConnectButton()
{
$config = $this->config['connect_button'];
- foreach([
- 'icon' => $this->getIcon(),
- 'label' => 'Connect with '.$this->getServiceName(),
- ] as $k=>$v)
- $config[$k] = $config[$k]?:$v;
+ foreach ([
+ 'icon' => $this->getIcon(),
+ 'label' => 'Connect with ' . $this->getServiceName()
+ ] as $k => $v)
+ $config[$k] = $config[$k] ?: $v;
return $config;
}
-
}
diff --git a/ResourceOwner/ResourceOwnerMap.php b/ResourceOwner/ResourceOwnerMap.php
index 7af6988..24377dd 100644
--- a/ResourceOwner/ResourceOwnerMap.php
+++ b/ResourceOwner/ResourceOwnerMap.php
@@ -17,11 +17,13 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-
namespace vierbergenlars\AuthserverOAuthAccountBundle\ResourceOwner;
+use vierbergenlars\AuthserverExternalAccountBundle\Entity\ExternalUser;
+
class ResourceOwnerMap implements \ArrayAccess, \IteratorAggregate
{
+
private $config;
public function __construct(array $config)
@@ -29,6 +31,22 @@ class ResourceOwnerMap implements \ArrayAccess, \IteratorAggregate
$this->config = $config;
}
+ /**
+ *
+ * @param ExternalUser $externalUser
+ * @throws \InvalidArgumentException
+ * @return ResourceOwnerConfig
+ */
+ public function getOwnerFromExternalUser(ExternalUser $externalUser)
+ {
+ $provider = $externalUser->getProvider();
+ if (strpos($provider, 'oauth_') !== 0)
+ throw new \InvalidArgumentException(sprintf('External user provider should start with "oauth_", got "%s"', $provider));
+
+ $name = substr($provider, strlen('oauth_'));
+ return $this->offsetGet($name);
+ }
+
public function offsetExists($offset)
{
return isset($this->config[$offset]);
@@ -36,7 +54,9 @@ class ResourceOwnerMap implements \ArrayAccess, \IteratorAggregate
public function offsetGet($offset)
{
- if(!$this->config[$offset] instanceof ResourceOwnerConfig)
+ if (!$this->offsetExists($offset))
+ throw new \OutOfBoundsException(sprintf('Resource owner "%s" does not exist.', $offset));
+ if (!$this->config[$offset] instanceof ResourceOwnerConfig)
$this->config[$offset] = new ResourceOwnerConfig($this->config[$offset]);
return $this->config[$offset];
}
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index ef51dfb..caddaab 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -30,10 +30,21 @@
+
+
+
+
-
+
+
+
+
+
+
+
+