Mercurial > hg > isophonics-drupal-site
comparison core/modules/jsonapi/src/Access/RelationshipFieldAccess.php @ 18:af1871eacc83
Update to Drupal core 8.7.1
author | Chris Cannam |
---|---|
date | Thu, 09 May 2019 15:33:08 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
17:129ea1e6d783 | 18:af1871eacc83 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\jsonapi\Access; | |
4 | |
5 use Drupal\Core\Access\AccessResult; | |
6 use Drupal\Core\Access\AccessResultReasonInterface; | |
7 use Drupal\Core\Cache\CacheableMetadata; | |
8 use Drupal\Core\Entity\FieldableEntityInterface; | |
9 use Drupal\Core\Http\Exception\CacheableAccessDeniedHttpException; | |
10 use Drupal\Core\Routing\Access\AccessInterface; | |
11 use Drupal\Core\Session\AccountInterface; | |
12 use Drupal\jsonapi\ResourceType\ResourceType; | |
13 use Drupal\jsonapi\Routing\Routes; | |
14 use Symfony\Component\HttpFoundation\Request; | |
15 use Symfony\Component\Routing\Route; | |
16 | |
17 /** | |
18 * Defines a class to check access to related and relationship routes. | |
19 * | |
20 * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class | |
21 * may change at any time and could break any dependencies on it. | |
22 * | |
23 * @see https://www.drupal.org/project/jsonapi/issues/3032787 | |
24 * @see jsonapi.api.php | |
25 */ | |
26 class RelationshipFieldAccess implements AccessInterface { | |
27 | |
28 /** | |
29 * The route requirement key for this access check. | |
30 * | |
31 * @var string | |
32 */ | |
33 const ROUTE_REQUIREMENT_KEY = '_jsonapi_relationship_field_access'; | |
34 | |
35 /** | |
36 * The JSON:API entity access checker. | |
37 * | |
38 * @var \Drupal\jsonapi\Access\EntityAccessChecker | |
39 */ | |
40 protected $entityAccessChecker; | |
41 | |
42 /** | |
43 * RelationshipFieldAccess constructor. | |
44 * | |
45 * @param \Drupal\jsonapi\Access\EntityAccessChecker $entity_access_checker | |
46 * The JSON:API entity access checker. | |
47 */ | |
48 public function __construct(EntityAccessChecker $entity_access_checker) { | |
49 $this->entityAccessChecker = $entity_access_checker; | |
50 } | |
51 | |
52 /** | |
53 * Checks access to the relationship field on the given route. | |
54 * | |
55 * @param \Symfony\Component\HttpFoundation\Request $request | |
56 * The incoming HTTP request object. | |
57 * @param \Symfony\Component\Routing\Route $route | |
58 * The route to check against. | |
59 * @param \Drupal\Core\Session\AccountInterface $account | |
60 * The currently logged in account. | |
61 * | |
62 * @return \Drupal\Core\Access\AccessResultInterface | |
63 * The access result. | |
64 */ | |
65 public function access(Request $request, Route $route, AccountInterface $account) { | |
66 $relationship_field_name = $route->getRequirement(static::ROUTE_REQUIREMENT_KEY); | |
67 $field_operation = $request->isMethodCacheable() ? 'view' : 'edit'; | |
68 $entity_operation = $request->isMethodCacheable() ? 'view' : 'update'; | |
69 if ($resource_type = $request->get(Routes::RESOURCE_TYPE_KEY)) { | |
70 assert($resource_type instanceof ResourceType); | |
71 $entity = $request->get('entity'); | |
72 $internal_name = $resource_type->getInternalName($relationship_field_name); | |
73 if ($entity instanceof FieldableEntityInterface && $entity->hasField($internal_name)) { | |
74 $entity_access = $this->entityAccessChecker->checkEntityAccess($entity, $entity_operation, $account); | |
75 $field_access = $entity->get($internal_name)->access($field_operation, $account, TRUE); | |
76 // Ensure that access is respected for different entity revisions. | |
77 $access_result = $entity_access->andIf($field_access); | |
78 if (!$access_result->isAllowed()) { | |
79 $reason = "The current user is not allowed to {$field_operation} this relationship."; | |
80 $access_reason = $access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : NULL; | |
81 $detailed_reason = empty($access_reason) ? $reason : $reason . " {$access_reason}"; | |
82 $access_result->setReason($detailed_reason); | |
83 if ($request->isMethodCacheable()) { | |
84 throw new CacheableAccessDeniedHttpException(CacheableMetadata::createFromObject($access_result), $detailed_reason); | |
85 } | |
86 } | |
87 return $access_result; | |
88 } | |
89 } | |
90 return AccessResult::neutral(); | |
91 } | |
92 | |
93 } |