Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176

This commit is contained in:
Pantheon Automation 2015-08-17 17:00:26 -07:00 committed by Greg Anderson
commit 9921556621
13277 changed files with 1459781 additions and 0 deletions

View file

@ -0,0 +1,248 @@
<?php
/**
* @file
* Contains \Drupal\Core\Authentication\AuthenticationManager.
*/
namespace Drupal\Core\Authentication;
use Drupal\Core\Routing\RouteMatch;
use Symfony\Component\HttpFoundation\Request;
/**
* Manager for authentication.
*
* On each request, let all authentication providers try to authenticate the
* user. The providers are iterated according to their priority and the first
* provider detecting credentials for its method wins. No further provider will
* get triggered.
*
* If no provider set an active user then the user is set to anonymous.
*/
class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface, AuthenticationManagerInterface {
/**
* Array of all registered authentication providers, keyed by ID.
*
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
*/
protected $providers;
/**
* Array of all providers and their priority.
*
* @var array
*/
protected $providerOrders = array();
/**
* Sorted list of registered providers.
*
* @var \Drupal\Core\Authentication\AuthenticationProviderInterface[]
*/
protected $sortedProviders;
/**
* List of providers which implement the filter interface.
*
* @var \Drupal\Core\Authentication\AuthenticationProviderFilterInterface[]
*/
protected $filters;
/**
* List of providers which implement the challenge interface.
*
* @var \Drupal\Core\Authentication\AuthenticationProviderChallengeInterface[]
*/
protected $challengers;
/**
* List of providers which are allowed on routes with no _auth option.
*
* @var string[]
*/
protected $globalProviders;
/**
* {@inheritdoc}
*/
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE) {
$this->providers[$provider_id] = $provider;
$this->providerOrders[$priority][$provider_id] = $provider;
// Force the builders to be re-sorted.
$this->sortedProviders = NULL;
if ($provider instanceof AuthenticationProviderFilterInterface) {
$this->filters[$provider_id] = $provider;
}
if ($provider instanceof AuthenticationProviderChallengeInterface) {
$this->challengers[$provider_id] = $provider;
}
if ($global) {
$this->globalProviders[$provider_id] = TRUE;
}
}
/**
* {@inheritdoc}
*/
public function applies(Request $request) {
return (bool) $this->getProvider($request);
}
/**
* {@inheritdoc}
*/
public function authenticate(Request $request) {
$provider_id = $this->getProvider($request);
return $this->providers[$provider_id]->authenticate($request);
}
/**
* {@inheritdoc}
*/
public function appliesToRoutedRequest(Request $request, $authenticated) {
$result = FALSE;
if ($authenticated) {
$result = $this->applyFilter($request, $authenticated, $this->getProvider($request));
}
else {
foreach ($this->getSortedProviders() as $provider_id => $provider) {
if ($this->applyFilter($request, $authenticated, $provider_id)) {
$result = TRUE;
break;
}
}
}
return $result;
}
/**
* {@inheritdoc}
*/
public function challengeException(Request $request, \Exception $previous) {
$provider_id = $this->getChallenger($request);
if ($provider_id) {
return $this->challengers[$provider_id]->challengeException($request, $previous);
}
}
/**
* Returns the id of the authentication provider for a request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*
* @return string|NULL
* The id of the first authentication provider which applies to the request.
* If no application detects appropriate credentials, then NULL is returned.
*/
protected function getProvider(Request $request) {
foreach ($this->getSortedProviders() as $provider_id => $provider) {
if ($provider->applies($request)) {
return $provider_id;
}
}
}
/**
* Returns the id of the challenge provider for a request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*
* @return string|NULL
* The id of the first authentication provider which applies to the request.
* If no application detects appropriate credentials, then NULL is returned.
*/
protected function getChallenger(Request $request) {
if (!empty($this->challengers)) {
foreach ($this->getSortedProviders($request, FALSE) as $provider_id => $provider) {
if (isset($this->challengers[$provider_id]) && !$provider->applies($request) && $this->applyFilter($request, FALSE, $provider_id)) {
return $provider_id;
}
}
}
}
/**
* Checks whether a provider is allowed on the given request.
*
* If no filter is registered for the given provider id, the default filter
* is applied.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
* @param bool $authenticated
* Whether or not the request is authenticated.
* @param string $provider_id
* The id of the authentication provider to check access for.
*
* @return bool
* TRUE if provider is allowed, FALSE otherwise.
*/
protected function applyFilter(Request $request, $authenticated, $provider_id) {
if (isset($this->filters[$provider_id])) {
$result = $this->filters[$provider_id]->appliesToRoutedRequest($request, $authenticated);
}
else {
$result = $this->defaultFilter($request, $provider_id);
}
return $result;
}
/**
* Default implementation of the provider filter.
*
* Checks whether a provider is allowed as per the _auth option on a route. If
* the option is not set or if the request did not match any route, only
* providers from the global provider set are allowed.
*
* If no filter is registered for the given provider id, the default filter
* is applied.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
* @param string $provider_id
* The id of the authentication provider to check access for.
*
* @return bool
* TRUE if provider is allowed, FALSE otherwise.
*/
protected function defaultFilter(Request $request, $provider_id) {
$route = RouteMatch::createFromRequest($request)->getRouteObject();
$has_auth_option = isset($route) && $route->hasOption('_auth');
if ($has_auth_option) {
return in_array($provider_id, $route->getOption('_auth'));
}
else {
return isset($this->globalProviders[$provider_id]);
}
}
/**
* Returns the sorted array of authentication providers.
*
* @return \Drupal\Core\Authentication\AuthenticationProviderInterface[]
* An array of authentication provider objects.
*/
protected function getSortedProviders() {
if (!isset($this->sortedProviders)) {
// Sort the builders according to priority.
krsort($this->providerOrders);
// Merge nested providers from $this->providers into $this->sortedProviders.
$this->sortedProviders = array();
foreach ($this->providerOrders as $providers) {
$this->sortedProviders = array_merge($this->sortedProviders, $providers);
}
}
return $this->sortedProviders;
}
}

View file

@ -0,0 +1,30 @@
<?php
/**
* @file
* Contains \Drupal\Core\Authentication\AuthenticationManagerInterface.
*/
namespace Drupal\Core\Authentication;
/**
* Defines an interface for authentication managers.
*/
interface AuthenticationManagerInterface {
/**
* Adds a provider to the array of registered providers.
*
* @param \Drupal\Core\Authentication\AuthenticationProviderInterface $provider
* The provider object.
* @param string $provider_id
* Identifier of the provider.
* @param int $priority
* (optional) The provider's priority.
* @param bool $global
* (optional) TRUE if the provider is to be applied globally on all routes.
* Defaults to FALSE.
*/
public function addProvider(AuthenticationProviderInterface $provider, $provider_id, $priority = 0, $global = FALSE);
}

View file

@ -0,0 +1,34 @@
<?php
/**
* @file
* Contains \Drupal\Core\Authentication\AuthenticationProviderChallengeInterface.
*/
namespace Drupal\Core\Authentication;
use Symfony\Component\HttpFoundation\Request;
/**
* Generate a challenge when access is denied for unauthenticated users.
*
* On a 403 (access denied), if there are no credentials on the request, some
* authentication methods (e.g. basic auth) require that a challenge is sent to
* the client.
*/
interface AuthenticationProviderChallengeInterface {
/**
* Constructs an exception which is used to generate the challenge.
*
* @var \Symfony\Component\HttpFoundation\Request
* The request.
* @var \Exception $exception
* The previous exception.
*
* @return \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface|NULL
* An exception to be used in order to generate an authentication challenge.
*/
public function challengeException(Request $request, \Exception $previous);
}

View file

@ -0,0 +1,39 @@
<?php
/**
* @file
* Contains \Drupal\Core\Authentication\AuthenticationProviderFilterInterface.
*/
namespace Drupal\Core\Authentication;
use Symfony\Component\HttpFoundation\Request;
/**
* Restrict authentication methods to a subset of the site.
*
* Some authentication methods should not be available throughout a whole site.
* E.g., there are good reasons to restrict insecure methods like HTTP basic
* auth or an URL token authentication method to API-only routes.
*/
interface AuthenticationProviderFilterInterface {
/**
* Checks whether the authentication method is allowed on a given route.
*
* While authentication itself is run before routing, this method is called
* after routing, hence RouteMatch is available and can be used to inspect
* route options.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param bool $authenticated
* Whether or not the request is authenticated.
*
* @return bool
* TRUE if an authentication method is allowed on the request, otherwise
* FALSE.
*/
public function appliesToRoutedRequest(Request $request, $authenticated);
}

View file

@ -0,0 +1,41 @@
<?php
/**
* @file
* Contains \Drupal\Core\Authentication\AuthenticationProviderInterface.
*/
namespace Drupal\Core\Authentication;
use Symfony\Component\HttpFoundation\Request;
/**
* Interface for authentication providers.
*/
interface AuthenticationProviderInterface {
/**
* Checks whether suitable authentication credentials are on the request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*
* @return bool
* TRUE if authentication credentials suitable for this provider are on the
* request, FALSE otherwise.
*/
public function applies(Request $request);
/**
* Authenticates the user.
*
* @param \Symfony\Component\HttpFoundation\Request|NULL $request
* The request object.
*
* @return \Drupal\Core\Session\AccountInterface|NULL
* AccountInterface - in case of a successful authentication.
* NULL - in case where authentication failed.
*/
public function authenticate(Request $request);
}