Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Core / Authentication / AuthenticationManager.php
1 <?php
2
3 namespace Drupal\Core\Authentication;
4
5 use Drupal\Core\Routing\RouteMatch;
6 use Symfony\Component\HttpFoundation\Request;
7
8 /**
9  * Manager for authentication.
10  *
11  * On each request, let all authentication providers try to authenticate the
12  * user. The providers are iterated according to their priority and the first
13  * provider detecting credentials for its method wins. No further provider will
14  * get triggered.
15  *
16  * If no provider set an active user then the user is set to anonymous.
17  */
18 class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface {
19
20   /**
21    * The authentication provider collector.
22    *
23    * @var \Drupal\Core\Authentication\AuthenticationCollectorInterface
24    */
25   protected $authCollector;
26
27   /**
28    * Creates a new authentication manager instance.
29    *
30    * @param \Drupal\Core\Authentication\AuthenticationCollectorInterface $auth_collector
31    *   The authentication provider collector.
32    */
33   public function __construct(AuthenticationCollectorInterface $auth_collector) {
34     $this->authCollector = $auth_collector;
35   }
36
37   /**
38    * {@inheritdoc}
39    */
40   public function applies(Request $request) {
41     return (bool) $this->getProvider($request);
42   }
43
44   /**
45    * {@inheritdoc}
46    */
47   public function authenticate(Request $request) {
48     $provider_id = $this->getProvider($request);
49     $provider = $this->authCollector->getProvider($provider_id);
50
51     if ($provider) {
52       return $provider->authenticate($request);
53     }
54
55     return NULL;
56   }
57
58   /**
59    * {@inheritdoc}
60    */
61   public function appliesToRoutedRequest(Request $request, $authenticated) {
62     $result = FALSE;
63
64     if ($authenticated) {
65       $result = $this->applyFilter($request, $authenticated, $this->getProvider($request));
66     }
67     else {
68       foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
69         if ($this->applyFilter($request, $authenticated, $provider_id)) {
70           $result = TRUE;
71           break;
72         }
73       }
74     }
75
76     return $result;
77   }
78
79   /**
80    * {@inheritdoc}
81    */
82   public function challengeException(Request $request, \Exception $previous) {
83     $provider_id = $this->getChallenger($request);
84
85     if ($provider_id) {
86       $provider = $this->authCollector->getProvider($provider_id);
87       return $provider->challengeException($request, $previous);
88     }
89   }
90
91   /**
92    * Returns the id of the authentication provider for a request.
93    *
94    * @param \Symfony\Component\HttpFoundation\Request $request
95    *   The incoming request.
96    *
97    * @return string|null
98    *   The id of the first authentication provider which applies to the request.
99    *   If no application detects appropriate credentials, then NULL is returned.
100    */
101   protected function getProvider(Request $request) {
102     foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
103       if ($provider->applies($request)) {
104         return $provider_id;
105       }
106     }
107   }
108
109   /**
110    * Returns the ID of the challenge provider for a request.
111    *
112    * @param \Symfony\Component\HttpFoundation\Request $request
113    *   The incoming request.
114    *
115    * @return string|null
116    *   The ID of the first authentication provider which applies to the request.
117    *   If no application detects appropriate credentials, then NULL is returned.
118    */
119   protected function getChallenger(Request $request) {
120     foreach ($this->authCollector->getSortedProviders() as $provider_id => $provider) {
121       if (($provider instanceof AuthenticationProviderChallengeInterface) && !$provider->applies($request) && $this->applyFilter($request, FALSE, $provider_id)) {
122         return $provider_id;
123       }
124     }
125   }
126
127   /**
128    * Checks whether a provider is allowed on the given request.
129    *
130    * If no filter is registered for the given provider id, the default filter
131    * is applied.
132    *
133    * @param \Symfony\Component\HttpFoundation\Request $request
134    *   The incoming request.
135    * @param bool $authenticated
136    *   Whether or not the request is authenticated.
137    * @param string $provider_id
138    *   The id of the authentication provider to check access for.
139    *
140    * @return bool
141    *   TRUE if provider is allowed, FALSE otherwise.
142    */
143   protected function applyFilter(Request $request, $authenticated, $provider_id) {
144     $provider = $this->authCollector->getProvider($provider_id);
145
146     if ($provider && ($provider instanceof AuthenticationProviderFilterInterface)) {
147       $result = $provider->appliesToRoutedRequest($request, $authenticated);
148     }
149     else {
150       $result = $this->defaultFilter($request, $provider_id);
151     }
152
153     return $result;
154   }
155
156   /**
157    * Default implementation of the provider filter.
158    *
159    * Checks whether a provider is allowed as per the _auth option on a route. If
160    * the option is not set or if the request did not match any route, only
161    * providers from the global provider set are allowed.
162    *
163    * If no filter is registered for the given provider id, the default filter
164    * is applied.
165    *
166    * @param \Symfony\Component\HttpFoundation\Request $request
167    *   The incoming request.
168    * @param string $provider_id
169    *   The id of the authentication provider to check access for.
170    *
171    * @return bool
172    *   TRUE if provider is allowed, FALSE otherwise.
173    */
174   protected function defaultFilter(Request $request, $provider_id) {
175     $route = RouteMatch::createFromRequest($request)->getRouteObject();
176     $has_auth_option = isset($route) && $route->hasOption('_auth');
177
178     if ($has_auth_option) {
179       return in_array($provider_id, $route->getOption('_auth'));
180     }
181     else {
182       return $this->authCollector->isGlobal($provider_id);
183     }
184   }
185
186 }