Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
77 / 77 |
|
100.00% |
20 / 20 |
CRAP | |
100.00% |
1 / 1 |
AuthorizationProfile | |
100.00% |
77 / 77 |
|
100.00% |
20 / 20 |
38 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getProviderId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getConsumerId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasValidProvider | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
hasValidConsumer | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getProvider | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
getConsumer | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
loadProviderPlugin | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
loadConsumerPlugin | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
getProviderConfig | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getConsumerConfig | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getProviderMappings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getConsumerMappings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setProviderConfig | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setConsumerConfig | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setProviderMappings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setConsumerMappings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getTokens | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
checkConditions | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
grantsAndRevokes | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
8 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Drupal\authorization\Entity; |
6 | |
7 | use Drupal\Core\Config\Entity\ConfigEntityBase; |
8 | use Drupal\Core\StringTranslation\StringTranslationTrait; |
9 | use Drupal\authorization\AuthorizationProfileInterface; |
10 | use Drupal\authorization\AuthorizationResponse; |
11 | use Drupal\authorization\AuthorizationSkipAuthorization; |
12 | use Drupal\authorization\Consumer\ConsumerInterface; |
13 | use Drupal\authorization\Provider\ProviderInterface; |
14 | use Drupal\user\UserInterface; |
15 | |
16 | /** |
17 | * Defines the Authorization profile entity. |
18 | * |
19 | * @ConfigEntityType( |
20 | * id = "authorization_profile", |
21 | * label = @Translation("Authorization profile"), |
22 | * handlers = { |
23 | * "list_builder" = "Drupal\authorization\AuthorizationProfileListBuilder", |
24 | * "form" = { |
25 | * "add" = "Drupal\authorization\Form\AuthorizationProfileAddForm", |
26 | * "edit" = "Drupal\authorization\Form\AuthorizationProfileEditForm", |
27 | * "delete" = "Drupal\authorization\Form\AuthorizationProfileDeleteForm" |
28 | * } |
29 | * }, |
30 | * config_prefix = "authorization_profile", |
31 | * config_export = { |
32 | * "id", |
33 | * "label", |
34 | * "provider", |
35 | * "provider_config", |
36 | * "provider_mappings", |
37 | * "consumer", |
38 | * "consumer_config", |
39 | * "consumer_mappings", |
40 | * "synchronization_modes", |
41 | * "synchronization_actions", |
42 | * }, |
43 | * admin_permission = "administer site configuration", |
44 | * entity_keys = { |
45 | * "id" = "id", |
46 | * "label" = "label", |
47 | * "uuid" = "uuid" |
48 | * }, |
49 | * links = { |
50 | * "edit-form" = "/admin/config/people/authorization/profile/{authorization_profile}", |
51 | * "delete-form" = "/admin/config/people/authorization/profile/{authorization_profile}/delete", |
52 | * "collection" = "/admin/config/people/authorization/profile" |
53 | * } |
54 | * ) |
55 | */ |
56 | class AuthorizationProfile extends ConfigEntityBase implements AuthorizationProfileInterface { |
57 | |
58 | use StringTranslationTrait; |
59 | |
60 | /** |
61 | * The Authorization profile ID. |
62 | * |
63 | * @var string |
64 | */ |
65 | protected $id; |
66 | |
67 | /** |
68 | * The Authorization profile label. |
69 | * |
70 | * @var string |
71 | */ |
72 | protected $label; |
73 | |
74 | /** |
75 | * The id of the Authorization provider. |
76 | * |
77 | * @var string |
78 | */ |
79 | protected $provider; |
80 | |
81 | /** |
82 | * The id of the Authorization consumer. |
83 | * |
84 | * @var string |
85 | */ |
86 | protected $consumer; |
87 | |
88 | /** |
89 | * The provider plugin configuration. |
90 | * |
91 | * @var array |
92 | */ |
93 | protected $provider_config = []; |
94 | |
95 | /** |
96 | * The provider plugin mappings. |
97 | * |
98 | * @var array |
99 | */ |
100 | protected $provider_mappings = []; |
101 | |
102 | /** |
103 | * The provider plugin instance. |
104 | * |
105 | * @var \Drupal\authorization\Provider\ProviderInterface |
106 | */ |
107 | protected $provider_plugin; |
108 | |
109 | /** |
110 | * The consumer plugin configuration. |
111 | * |
112 | * @var array |
113 | */ |
114 | protected $consumer_config = []; |
115 | |
116 | /** |
117 | * The consumer plugin mappings. |
118 | * |
119 | * @var array |
120 | */ |
121 | protected $consumer_mappings = []; |
122 | |
123 | /** |
124 | * The consumer plugin instance. |
125 | * |
126 | * @var \Drupal\authorization\Consumer\ConsumerInterface |
127 | */ |
128 | protected $consumer_plugin; |
129 | |
130 | /** |
131 | * The provider plugin manager. |
132 | * |
133 | * @var \Drupal\authorization\Provider\ProviderPluginManager |
134 | */ |
135 | protected $provider_plugin_manager; |
136 | |
137 | /** |
138 | * The consumer plugin manager. |
139 | * |
140 | * @var \Drupal\authorization\Consumer\ConsumerPluginManager |
141 | */ |
142 | protected $consumer_plugin_manager; |
143 | |
144 | |
145 | /** |
146 | * The authorization logger channel. |
147 | * |
148 | * @var \Psr\Log\LoggerInterface |
149 | */ |
150 | protected $logger; |
151 | |
152 | /** |
153 | * {@inheritdoc} |
154 | */ |
155 | public function __construct($values, $entity_type) { |
156 | parent::__construct($values, $entity_type); |
157 | // Cannot inject those without moving the logic to a controller class, (see |
158 | // https://www.drupal.org/node/2913224). |
159 | $this->provider_plugin_manager = \Drupal::service('plugin.manager.authorization.provider'); |
160 | $this->consumer_plugin_manager = \Drupal::service('plugin.manager.authorization.consumer'); |
161 | $this->logger = \Drupal::service('logger.channel.authorization'); |
162 | } |
163 | |
164 | /** |
165 | * {@inheritdoc} |
166 | */ |
167 | public function getProviderId(): ?string { |
168 | return $this->provider; |
169 | } |
170 | |
171 | /** |
172 | * Get the Consumer ID. |
173 | * |
174 | * @return string |
175 | * Consumer ID. |
176 | */ |
177 | public function getConsumerId(): ?string { |
178 | return $this->consumer; |
179 | } |
180 | |
181 | /** |
182 | * {@inheritdoc} |
183 | */ |
184 | public function hasValidProvider(): bool { |
185 | if ($this->provider_plugin_manager->getDefinition($this->getProviderId(), FALSE)) { |
186 | return TRUE; |
187 | } |
188 | return FALSE; |
189 | } |
190 | |
191 | /** |
192 | * {@inheritdoc} |
193 | */ |
194 | public function hasValidConsumer(): bool { |
195 | if ($this->consumer_plugin_manager->getDefinition($this->getConsumerId(), FALSE)) { |
196 | return TRUE; |
197 | } |
198 | return FALSE; |
199 | } |
200 | |
201 | /** |
202 | * {@inheritdoc} |
203 | */ |
204 | public function getProvider(): ?ProviderInterface { |
205 | if (!$this->provider_plugin || $this->getProviderId() !== $this->provider_plugin->getPluginId()) { |
206 | $this->loadProviderPlugin(); |
207 | } |
208 | return $this->provider_plugin; |
209 | } |
210 | |
211 | /** |
212 | * {@inheritdoc} |
213 | */ |
214 | public function getConsumer(): ?ConsumerInterface { |
215 | if (!$this->consumer_plugin || $this->getConsumerId() !== $this->consumer_plugin->getPluginId()) { |
216 | $this->loadConsumerPlugin(); |
217 | } |
218 | return $this->consumer_plugin; |
219 | } |
220 | |
221 | /** |
222 | * Load the provider plugin. |
223 | */ |
224 | protected function loadProviderPlugin(): void { |
225 | $config = $this->getProviderConfig(); |
226 | $config['profile'] = $this; |
227 | try { |
228 | $this->provider_plugin = $this->provider_plugin_manager->createInstance($this->getProviderId(), $config); |
229 | } |
230 | catch (\Exception $e) { |
231 | $this->logger->critical('The provider with ID "@provider" could not be retrieved for profile %profile.', [ |
232 | '@provider' => $this->getProviderId(), |
233 | '%profile' => $this->label(), |
234 | ] |
235 | ); |
236 | } |
237 | } |
238 | |
239 | /** |
240 | * Load the consumer plugin. |
241 | */ |
242 | protected function loadConsumerPlugin(): void { |
243 | $config = $this->getConsumerConfig(); |
244 | $config['profile'] = $this; |
245 | try { |
246 | $this->consumer_plugin = $this->consumer_plugin_manager->createInstance($this->getConsumerId(), $config); |
247 | } |
248 | catch (\Exception $e) { |
249 | $this->logger->critical('The consumer with ID "@consumer" could not be retrieved for profile %profile.', [ |
250 | '@consumer' => $this->getConsumerId(), |
251 | '%profile' => $this->label(), |
252 | ] |
253 | ); |
254 | } |
255 | } |
256 | |
257 | /** |
258 | * {@inheritdoc} |
259 | */ |
260 | public function getProviderConfig(): array { |
261 | return $this->provider_config; |
262 | } |
263 | |
264 | /** |
265 | * {@inheritdoc} |
266 | */ |
267 | public function getConsumerConfig(): array { |
268 | return $this->consumer_config; |
269 | } |
270 | |
271 | /** |
272 | * {@inheritdoc} |
273 | */ |
274 | public function getProviderMappings(): array { |
275 | return $this->provider_mappings; |
276 | } |
277 | |
278 | /** |
279 | * {@inheritdoc} |
280 | */ |
281 | public function getConsumerMappings(): array { |
282 | return $this->consumer_mappings; |
283 | } |
284 | |
285 | /** |
286 | * {@inheritdoc} |
287 | */ |
288 | public function setProviderConfig(array $provider_config): void { |
289 | $this->provider_config = $provider_config; |
290 | } |
291 | |
292 | /** |
293 | * {@inheritdoc} |
294 | */ |
295 | public function setConsumerConfig(array $consumer_config): void { |
296 | $this->consumer_config = $consumer_config; |
297 | } |
298 | |
299 | /** |
300 | * {@inheritdoc} |
301 | */ |
302 | public function setProviderMappings(array $provider_mappings): void { |
303 | $this->provider_mappings = $provider_mappings; |
304 | } |
305 | |
306 | /** |
307 | * {@inheritdoc} |
308 | */ |
309 | public function setConsumerMappings(array $consumer_mappings): void { |
310 | $this->consumer_mappings = $consumer_mappings; |
311 | } |
312 | |
313 | /** |
314 | * {@inheritdoc} |
315 | */ |
316 | public function getTokens(): array { |
317 | $tokens = []; |
318 | $tokens['@profile_name'] = $this->label; |
319 | return $tokens; |
320 | } |
321 | |
322 | /** |
323 | * {@inheritdoc} |
324 | */ |
325 | public function checkConditions(): bool { |
326 | |
327 | if (!$this->get('status')) { |
328 | return FALSE; |
329 | } |
330 | |
331 | if (!$this->getProvider()) { |
332 | return FALSE; |
333 | } |
334 | |
335 | if (!$this->getConsumer()) { |
336 | return FALSE; |
337 | } |
338 | |
339 | return TRUE; |
340 | } |
341 | |
342 | /** |
343 | * {@inheritdoc} |
344 | */ |
345 | public function grantsAndRevokes(UserInterface $user, $user_save = FALSE): AuthorizationResponse { |
346 | |
347 | $provider = $this->getProvider(); |
348 | $consumer = $this->getConsumer(); |
349 | |
350 | try { |
351 | $proposals = $provider->getProposals($user); |
352 | } |
353 | catch (AuthorizationSkipAuthorization $e) { |
354 | return new AuthorizationResponse((string) $this->t('@name (skipped)', ['@name' => $this->label]), TRUE, []); |
355 | } |
356 | |
357 | $proposals = $provider->sanitizeProposals($proposals); |
358 | |
359 | $applied_grants = []; |
360 | // @todo This could be made more elegant with methods on this class checking |
361 | // for support on this and not checking here the array key directly. |
362 | $create_consumers = $this->get('synchronization_actions')['create_consumers'] ?? FALSE; |
363 | $revoke_provision = $this->get('synchronization_actions')['revoke_provider_provisioned'] ?? FALSE; |
364 | foreach ($this->getProviderMappings() as $provider_key => $provider_mapping) { |
365 | $provider_proposals = $provider->filterProposals($proposals, $provider_mapping); |
366 | $filtered_proposals = $consumer->filterProposals($provider_proposals, $this->getConsumerMappings()[$provider_key]); |
367 | |
368 | if (!empty($filtered_proposals)) { |
369 | foreach ($filtered_proposals as $filtered_proposal) { |
370 | if ($create_consumers) { |
371 | $consumer->createConsumerTarget($filtered_proposal); |
372 | } |
373 | $consumer->grantSingleAuthorization($user, $filtered_proposal, $this->id()); |
374 | $applied_grants[$filtered_proposal] = $filtered_proposal; |
375 | } |
376 | } |
377 | } |
378 | |
379 | if ($revoke_provision) { |
380 | $consumer->revokeGrants($user, $applied_grants, $this->id()); |
381 | } |
382 | |
383 | if ($user_save === TRUE) { |
384 | $user->save(); |
385 | } |
386 | |
387 | return new AuthorizationResponse($this->label, FALSE, $applied_grants); |
388 | } |
389 | |
390 | } |