From 72eea2de6659f9745fa9ee10a82e546436a8e07a Mon Sep 17 00:00:00 2001
From: William Hearn <sylus1984@gmail.com>
Date: Fri, 16 Jun 2017 12:36:54 -0400
Subject: [PATCH] Voting API: Getting an access denied or 403 response using
 GET method

---
 src/Entity/Vote.php                    |  1 +
 src/Entity/VoteResult.php              | 13 ++++++++---
 src/VoteAccessControlHandler.php       | 40 ++++++++++++++++++++++++++++++++++
 src/VoteResultAccessControlHandler.php | 40 ++++++++++++++++++++++++++++++++++
 src/VoteResultFunctionManager.php      | 18 +++++++++++++--
 votingapi.services.yml                 |  3 ++-
 6 files changed, 109 insertions(+), 6 deletions(-)
 create mode 100644 src/VoteAccessControlHandler.php
 create mode 100644 src/VoteResultAccessControlHandler.php

diff --git a/src/Entity/Vote.php b/src/Entity/Vote.php
index 7e8ea06..16a1e5d 100644
--- a/src/Entity/Vote.php
+++ b/src/Entity/Vote.php
@@ -27,6 +27,7 @@ use Drupal\votingapi\VoteInterface;
  *   bundle_entity_type = "vote_type",
  *   handlers = {
  *     "storage" = "Drupal\votingapi\VoteStorage",
+ *     "access" = "Drupal\votingapi\VoteAccessControlHandler",
  *     "views_data" = "Drupal\votingapi\Entity\VoteViewsData",
  *   },
  *   base_table = "votingapi_vote",
diff --git a/src/Entity/VoteResult.php b/src/Entity/VoteResult.php
index f418d95..0ab1eb0 100644
--- a/src/Entity/VoteResult.php
+++ b/src/Entity/VoteResult.php
@@ -23,11 +23,13 @@ use Drupal\votingapi\VoteResultInterface;
  *   label = @Translation("Vote Result"),
  *   handlers = {
  *     "storage" = "Drupal\votingapi\VoteResultStorage",
+ *     "access" = "Drupal\votingapi\VoteResultAccessControlHandler",
  *     "views_data" = "Drupal\votingapi\Entity\VoteResultViewsData",
  *   },
  *   base_table = "votingapi_result",
  *   entity_keys = {
- *     "id" = "id"
+ *     "id" = "id",
+ *     "uuid" = "uuid"
  *   }
  * )
  */
@@ -158,6 +160,11 @@ class VoteResult extends ContentEntityBase implements VoteResultInterface {
       ->setReadOnly(TRUE)
       ->setSetting('unsigned', TRUE);
 
+    $fields['uuid'] = BaseFieldDefinition::create('uuid')
+      ->setLabel(t('UUID'))
+      ->setDescription(t('The vote result UUID.'))
+      ->setReadOnly(TRUE);
+
     $fields['type'] = BaseFieldDefinition::create('entity_reference')
       ->setLabel(t('Type'))
       ->setDescription(t('The vote type.'))
@@ -193,7 +200,7 @@ class VoteResult extends ContentEntityBase implements VoteResultInterface {
       ->setLabel(t('Function'))
       ->setDescription(t('Function to apply to the numbers.'))
       ->setSettings(array(
-        'max_length' => 50
+        'max_length' => 100
       ))
       ->setRequired(TRUE);
 
@@ -204,4 +211,4 @@ class VoteResult extends ContentEntityBase implements VoteResultInterface {
 
     return $fields;
   }
-}
\ No newline at end of file
+}
diff --git a/src/VoteAccessControlHandler.php b/src/VoteAccessControlHandler.php
new file mode 100644
index 0000000..521c8be
--- /dev/null
+++ b/src/VoteAccessControlHandler.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\votingapi;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\EntityAccessControlHandler;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Defines the access control handler for the vote entity type.
+ *
+ * @see \Drupal\votingapi\Entity\Vote
+ */
+class VoteAccessControlHandler extends EntityAccessControlHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
+    return AccessResult::allowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return AccessResult::allowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
+    return AccessResult::allowed();
+  }
+
+}
diff --git a/src/VoteResultAccessControlHandler.php b/src/VoteResultAccessControlHandler.php
new file mode 100644
index 0000000..b9d84b4
--- /dev/null
+++ b/src/VoteResultAccessControlHandler.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\votingapi;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\EntityAccessControlHandler;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Defines the access control handler for the vote entity type.
+ *
+ * @see \Drupal\votingapi\Entity\Vote
+ */
+class VoteResultAccessControlHandler extends EntityAccessControlHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
+    return AccessResult::allowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return AccessResult::allowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
+    return AccessResult::allowed();
+  }
+
+}
diff --git a/src/VoteResultFunctionManager.php b/src/VoteResultFunctionManager.php
index 084a79d..658a586 100644
--- a/src/VoteResultFunctionManager.php
+++ b/src/VoteResultFunctionManager.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\votingapi;
 
+use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
@@ -25,6 +26,13 @@ use Drupal\Core\Plugin\DefaultPluginManager;
 class VoteResultFunctionManager extends DefaultPluginManager {
 
   /**
+   * The UUID service.
+   *
+   * @var \Drupal\Component\Uuid\UuidInterface
+   */
+  protected $uuidService;
+
+  /**
    * Constructs a new ImageEffectManager.
    *
    * @param \Traversable $namespaces
@@ -34,9 +42,12 @@ class VoteResultFunctionManager extends DefaultPluginManager {
    *   Cache backend instance to use.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Drupal\Component\Uuid\UuidInterface $uuid_service
+   *   UUID service.
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, UuidInterface $uuid_service) {
     parent::__construct('Plugin/VoteResultFunction', $namespaces, $module_handler, 'Drupal\votingapi\VoteResultFunctionInterface', 'Drupal\votingapi\Annotation\VoteResultFunction');
+    $this->uuidService = $uuid_service;
     $this->alterInfo('vote_result_info');
     $this->setCacheBackend($cache_backend, 'vote_result_plugins');
   }
@@ -133,8 +144,10 @@ class VoteResultFunctionManager extends DefaultPluginManager {
 
     foreach ($this->getDefinitions() as $plugin_id => $definition) {
       $plugin = $this->createInstance($plugin_id);
+      $entity_uuid = $this->uuidService->generate();
       db_insert('votingapi_result')->fields(array(
         'entity_id' => $entity_id,
+        'uuid' => $entity_uuid,
         'entity_type' => $entity_type_id,
         'type' => $vote_type,
         'function' => $plugin_id,
@@ -143,4 +156,5 @@ class VoteResultFunctionManager extends DefaultPluginManager {
       ))->execute();
     }
   }
-}
\ No newline at end of file
+
+}
diff --git a/votingapi.services.yml b/votingapi.services.yml
index ef77010..7d52856 100644
--- a/votingapi.services.yml
+++ b/votingapi.services.yml
@@ -1,4 +1,5 @@
 services:
   plugin.manager.votingapi.resultfunction:
     class: Drupal\votingapi\VoteResultFunctionManager
-    parent: default_plugin_manager
\ No newline at end of file
+    arguments: ['@uuid']
+    parent: default_plugin_manager
-- 
2.5.4 (Apple Git-61)

