Created
April 17, 2017 10:19
-
-
Save sorenmalling/c63f5e80830c3b19e9b65e7bf9cf5c88 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Vendor\Application\Security\Authentication\Oauth\Provider; | |
abstract class AbstractOauthProvider extends AbstractProvider { | |
/** | |
* Oauth manager | |
* | |
* @var OauthManager | |
* @Flow\Inject | |
*/ | |
protected $oauthManager; | |
/** | |
* @Flow\Inject | |
* @var \Neos\Flow\Persistence\PersistenceManagerInterface | |
*/ | |
protected $persistenceManager; | |
/** | |
* @var PropertyMapper | |
* @Flow\Inject | |
*/ | |
protected $propertyMapper; | |
/** | |
* @var HashService | |
* @Flow\Inject | |
*/ | |
protected $hashService; | |
/** | |
* Account repository | |
* | |
* @var AccountRepository | |
* @Flow\Inject | |
*/ | |
protected $accountRepository; | |
/** | |
* User repository | |
* | |
* @var UserRepository | |
* @Flow\Inject | |
*/ | |
protected $userRepository; | |
/** | |
* @Flow\Inject | |
* @var \Neos\Flow\Security\Context | |
*/ | |
protected $securityContext; | |
/** | |
* @return string | |
*/ | |
abstract protected function getResourceOwnerClassName(); | |
/** | |
* Get oauth provider | |
* | |
* @return \League\OAuth2\Client\Provider\AbstractProvider | |
*/ | |
protected function getOauthProvider() { | |
$strategy = $this->oauthManager->getStrategyNameByProviderName($this->name); | |
$provider = $this->oauthManager->getImplementedProviderByStrategyName($strategy); | |
return $provider; | |
} | |
/** | |
* @param TokenInterface $authenticationToken | |
* @return \League\OAuth2\Client\Provider\ResourceOwnerInterface | |
*/ | |
protected function getResourceOwner(TokenInterface $authenticationToken) { | |
$credentials = $authenticationToken->getCredentials(); | |
$provider = $this->getOauthProvider(); | |
$resourceOwner = $provider->getResourceOwner($credentials['accessToken']); | |
return $resourceOwner; | |
} | |
public function authenticate(TokenInterface $authenticationToken) | |
{ | |
$tokens = $this->getTokenClassNames(); | |
$tokenClassName = $tokens[0]; | |
if (!($authenticationToken instanceof $tokenClassName)) { | |
throw new UnsupportedAuthenticationTokenException(sprintf('This provider only supports %s', [$this->getTokenClassNames()[0]])); | |
} | |
$resourceOwner = $this->getResourceOwner($authenticationToken); | |
if (!(get_class($resourceOwner) === $this->getResourceOwnerClassName())) { | |
$authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS); | |
return; | |
} | |
$providerName = $this->name; | |
$accountRepository = $this->accountRepository; | |
$account = NULL; | |
$this->securityContext->withoutAuthorizationChecks(function () use ($resourceOwner, $providerName, $accountRepository , &$account) { | |
$account = $accountRepository->findByAccountIdentifierAndAuthenticationProviderName($resourceOwner->getId(), $providerName); | |
}); | |
if ($account === NULL) { | |
$user = User::signUp( | |
$resourceOwner->getId(), | |
$this->hashService->hashPassword(Algorithms::generateRandomString(32)), | |
$this->name | |
); | |
$this->userRepository->add($user); | |
$account = $user->getAccount(); | |
} | |
$authenticationToken->setAccount($account); | |
$randomPassword = $this->hashService->hashPassword(Algorithms::generateRandomString(32)); | |
$account->setCredentialsSource($randomPassword); | |
$authenticationToken->setAccount($account); | |
$authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL); | |
$this->accountRepository->update($account); | |
$this->persistenceManager->persistAll(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Vendor\Application\Security\Authentication\Oauth\Provider; | |
use League\OAuth2\Client\Provider\FacebookUser; | |
class FacebookProvider extends AbstractOauthProvider { | |
/** | |
* @return array | |
*/ | |
public function getTokenClassNames() | |
{ | |
return [FacebookToken::class]; | |
} | |
/** | |
* @return string | |
*/ | |
protected function getResourceOwnerClassName() | |
{ | |
return FacebookUser::class; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Vendor\Application\Security\Authentication\Token; | |
class FacebookToken extends AbstractToken { | |
/** | |
* Oauth manager | |
* | |
* @var OauthManager | |
* @Flow\Inject | |
*/ | |
protected $oauthManager; | |
/** | |
* Object manager | |
* | |
* @var ObjectManagerInterface | |
* @Flow\Inject | |
*/ | |
protected $objectManager; | |
/** | |
* @param \Neos\Flow\Mvc\ActionRequest $actionRequest | |
* @throws \Neos\Flow\Mvc\Exception\NoSuchArgumentException | |
* @throws \Neos\Flow\Security\Exception\InvalidAuthenticationStatusException | |
*/ | |
public function updateCredentials(\Neos\Flow\Mvc\ActionRequest $actionRequest) | |
{ | |
$strategy = $actionRequest->getInternalArgument('__oauthProvider'); | |
if ($actionRequest->getHttpRequest()->getMethod() !== 'GET' || $this->oauthManager->getProviderNameByStrategyName($strategy) !== $this->authenticationProviderName) { | |
return; | |
} | |
if (!$actionRequest->hasArgument('code')) { | |
$this->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS); | |
return; | |
} | |
if ($actionRequest->hasArgument('code')) { | |
$code = $actionRequest->getArgument('code'); | |
try { | |
$provider = $this->oauthManager->getImplementedProviderByStrategyName($strategy); | |
$token = $provider->getAccessToken('authorization_code', ['code' => $code]); | |
$credentials = ['accessToken' => $token]; | |
$this->credentials = $credentials; | |
$this->setAuthenticationStatus(TokenInterface::AUTHENTICATION_NEEDED); | |
} catch (\Exception $exception) { | |
$this->setAuthenticationProviderName(TokenInterface::WRONG_CREDENTIALS); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment