parent
758e1344d7
commit
088e997203
@ -0,0 +1,52 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace vierbergenlars\AuthserverExternalAccountBundle\Entity; |
||||||
|
|
||||||
|
use Registration\Entity\TemporaryUser as BaseTemporaryUser; |
||||||
|
|
||||||
|
class TemporaryUser extends BaseTemporaryUser |
||||||
|
{ |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @var ExternalUser |
||||||
|
*/ |
||||||
|
private $externalUser; |
||||||
|
|
||||||
|
public function getExternalUser() |
||||||
|
{ |
||||||
|
return $this->externalUser; |
||||||
|
} |
||||||
|
|
||||||
|
public function setExternalUser(ExternalUser $externalUser) |
||||||
|
{ |
||||||
|
$this->externalUser = $externalUser; |
||||||
|
} |
||||||
|
|
||||||
|
public function getUsername() |
||||||
|
{ |
||||||
|
return '$' . $this->externalUser->getProvider() . '$' . $this->externalUser->getProviderRef() . '$'; |
||||||
|
} |
||||||
|
|
||||||
|
public function getDisplayName() |
||||||
|
{ |
||||||
|
return $this->externalUser->getProviderFriendlyName(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace vierbergenlars\AuthserverExternalAccountBundle\EventListener; |
||||||
|
|
||||||
|
use Registration\Event\RegistrationHandleEvent; |
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||||||
|
use Registration\RegistrationEvents; |
||||||
|
use Registration\Event\RegistrationFormEvent; |
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; |
||||||
|
use vierbergenlars\AuthserverExternalAccountBundle\Entity\TemporaryUser; |
||||||
|
use Doctrine\ORM\EntityManagerInterface; |
||||||
|
|
||||||
|
class RegistrationHandlerListener implements EventSubscriberInterface |
||||||
|
{ |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @var TokenStorageInterface |
||||||
|
*/ |
||||||
|
private $tokenStorage; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @var EntityManagerInterface |
||||||
|
*/ |
||||||
|
private $em; |
||||||
|
|
||||||
|
public static function getSubscribedEvents() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
RegistrationEvents::BUILD_FORM => [ |
||||||
|
'onBuildForm', |
||||||
|
10 |
||||||
|
], |
||||||
|
RegistrationEvents::HANDLE_FORM => [ |
||||||
|
[ |
||||||
|
'onHandleFormSetPasswordEnabled', |
||||||
|
10 |
||||||
|
], |
||||||
|
[ |
||||||
|
'onHandleFormConnectExternal', |
||||||
|
0 |
||||||
|
], |
||||||
|
[ |
||||||
|
'onHandleFormLogoutExternal', |
||||||
|
-250 |
||||||
|
] |
||||||
|
] |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em, TokenStorageInterface $tokenStorage) |
||||||
|
{ |
||||||
|
$this->em = $em; |
||||||
|
$this->tokenStorage = $tokenStorage; |
||||||
|
} |
||||||
|
|
||||||
|
private function getTemporaryUser() |
||||||
|
{ |
||||||
|
$token = $this->tokenStorage->getToken(); |
||||||
|
if (!$token) |
||||||
|
return null; |
||||||
|
$user = $token->getUser(); |
||||||
|
if ($user instanceof TemporaryUser) |
||||||
|
return $user; |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public function onBuildForm(RegistrationFormEvent $event) |
||||||
|
{ |
||||||
|
if ($user = $this->getTemporaryUser()) { |
||||||
|
$event->getFormBuilder()->remove('password'); |
||||||
|
$event->getFormBuilder() |
||||||
|
->getData() |
||||||
|
->setDisplayName($user->getDisplayName()) |
||||||
|
->setPasswordEnabled(2); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function onHandleFormSetPasswordEnabled(RegistrationHandleEvent $event) |
||||||
|
{ |
||||||
|
$user = $event->getForm()->getData(); |
||||||
|
if (!$user) |
||||||
|
return; |
||||||
|
/* @var $user User */ |
||||||
|
$user->setPasswordEnabled(2); |
||||||
|
} |
||||||
|
|
||||||
|
public function onHandleFormConnectExternal(RegistrationHandleEvent $event) |
||||||
|
{ |
||||||
|
$user = $event->getForm()->getData(); |
||||||
|
if (!$user) |
||||||
|
return; |
||||||
|
/* @var $user User */ |
||||||
|
if ($temporaryUser = $this->getTemporaryUser()) { |
||||||
|
$temporaryUser->getExternalUser()->setUser($user); |
||||||
|
$this->em->persist($temporaryUser->getExternalUser()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function onHandleFormLogoutExternal(RegistrationHandleEvent $event) |
||||||
|
{ |
||||||
|
if ($this->getTemporaryUser()) |
||||||
|
$this->tokenStorage->setToken(null); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace Application\Migrations; |
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration; |
||||||
|
use Doctrine\DBAL\Schema\Schema; |
||||||
|
|
||||||
|
class VersionAuthserverExternalAccount20171020080018 extends AbstractMigration |
||||||
|
{ |
||||||
|
|
||||||
|
public function up(Schema $schema) |
||||||
|
{ |
||||||
|
$externalUser = $schema->getTable('vierbergenlars_external_account_external_user'); |
||||||
|
|
||||||
|
foreach ($externalUser->getForeignKeys() as $fk) |
||||||
|
$externalUser->removeForeignKey($fk->getName()); |
||||||
|
|
||||||
|
$externalUser->addForeignKeyConstraint('auth_users', [ |
||||||
|
'user_id' |
||||||
|
], [ |
||||||
|
'id' |
||||||
|
], [ |
||||||
|
'onDelete' => 'CASCADE' |
||||||
|
], 'fk_vl_ea_external_user'); |
||||||
|
} |
||||||
|
|
||||||
|
public function down(Schema $schema) |
||||||
|
{} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,43 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace Application\Migrations; |
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration; |
||||||
|
use Doctrine\DBAL\Schema\Schema; |
||||||
|
|
||||||
|
class VersionAuthserverExternalAccount20171020220239 extends AbstractMigration |
||||||
|
{ |
||||||
|
|
||||||
|
public function up(Schema $schema) |
||||||
|
{ |
||||||
|
$condition = 'WHERE ea1.id > ea2.id AND ea1.provider = ea2.provider AND ea1.provider_ref = ea2.provider_ref'; |
||||||
|
$duplicates = $this->connection->fetchAll('SELECT DISTINCT ea1.id AS id FROM vierbergenlars_external_account_external_user AS ea1 JOIN vierbergenlars_external_account_external_user ea2 ' . $condition); |
||||||
|
$duplicateIds = array_map(function ($row) { |
||||||
|
return $row['id']; |
||||||
|
}, $duplicates); |
||||||
|
$this->connection->executeUpdate('DELETE FROM vierbergenlars_external_account_external_user WHERE id IN(' . implode(',', $duplicateIds) . ')'); |
||||||
|
} |
||||||
|
|
||||||
|
public function down(Schema $schema) |
||||||
|
{ |
||||||
|
$this->throwIrreversibleMigrationException('Duplicate external account references have been cleared.'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,45 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace Application\Migrations; |
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration; |
||||||
|
use Doctrine\DBAL\Schema\Schema; |
||||||
|
|
||||||
|
class VersionAuthserverExternalAccount20171020220751 extends AbstractMigration |
||||||
|
{ |
||||||
|
|
||||||
|
public function up(Schema $schema) |
||||||
|
{ |
||||||
|
$externalUser = $schema->getTable('vierbergenlars_external_account_external_user'); |
||||||
|
|
||||||
|
if ($externalUser->hasIndex('uniq_vl_ea_external_user')) |
||||||
|
$externalUser->dropIndex('uniq_vl_ea_external_user'); |
||||||
|
$externalUser->addUniqueIndex([ |
||||||
|
'provider', |
||||||
|
'provider_ref' |
||||||
|
], 'uniq_vl_ea_external_user'); |
||||||
|
} |
||||||
|
|
||||||
|
public function down(Schema $schema) |
||||||
|
{ |
||||||
|
$this->throwIrreversibleMigrationException('Duplicate values on (provider, provider_ref) are no longer allowed.'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,48 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace vierbergenlars\AuthserverExternalAccountBundle\Security\Core\User; |
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\User\UserProviderInterface; |
||||||
|
use Symfony\Component\Security\Core\User\UserInterface; |
||||||
|
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; |
||||||
|
use vierbergenlars\AuthserverExternalAccountBundle\Entity\TemporaryUser; |
||||||
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; |
||||||
|
|
||||||
|
class TemporaryUserProvider implements UserProviderInterface |
||||||
|
{ |
||||||
|
|
||||||
|
public function supportsClass($class) |
||||||
|
{ |
||||||
|
return $class === TemporaryUser::class; |
||||||
|
} |
||||||
|
|
||||||
|
public function refreshUser(UserInterface $user) |
||||||
|
{ |
||||||
|
if (!$this->supportsClass(get_class($user))) |
||||||
|
throw new UnsupportedUserException(sprintf('Expected instance of %s, got instance of %s', TemporaryUser::class, get_class($user))); |
||||||
|
return $user; |
||||||
|
} |
||||||
|
|
||||||
|
public function loadUserByUsername($username) |
||||||
|
{ |
||||||
|
throw new UsernameNotFoundException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
Reference in new issue