From dfb3ddd233758461ca96b9e83f53d3c9feacb200 Mon Sep 17 00:00:00 2001
From: Liam Morland <lkmorlan@uwaterloo.ca>
Date: Thu, 28 Oct 2021 13:40:22 -0400
Subject: [PATCH] ISTWCMS-4907: Implement access control for Webforms

---
 uw_cfg_common.module | 50 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/uw_cfg_common.module b/uw_cfg_common.module
index e5ff0eb8..c5f83d95 100644
--- a/uw_cfg_common.module
+++ b/uw_cfg_common.module
@@ -750,6 +750,56 @@ function uw_cfg_common_block_content_create_access(AccountInterface $account, ar
   return AccessResult::neutral();
 }
 
+/**
+ * Implements hook_ENTITY_TYPE_access() for webform entities.
+ */
+function uw_cfg_common_webform_access(WebformInterface $webform, string $operation, AccountInterface $account): AccessResult {
+  // Always allow access for Form editor so they can see the forms they create.
+  if ($account->hasPermission('create webform')) {
+    return AccessResult::neutral();
+  }
+
+  // Allow access to submissions for Form results access.
+  if ($account->hasPermission('view any webform submission') && $operation === 'submission_view_any') {
+    return AccessResult::neutral();
+  }
+
+  switch ($webform->getThirdPartySetting('uw_cfg_common', 'access_control_method')) {
+    case 'anon':
+      if (!$account->isAnonymous()) {
+        return AccessResult::forbidden();
+      }
+      break;
+
+    case 'auth':
+      if (!$account->isAuthenticated()) {
+        return AccessResult::forbidden();
+      }
+      break;
+
+    case 'group':
+      // Must be authenticated for group auth.
+      if (!$account->isAuthenticated()) {
+        return AccessResult::forbidden();
+      }
+      // Access control by Active Directory group.
+      $user_ad_groups = uw_cfg_common_get_user_ad_groups() ?: [];
+      // Required group. If at least one is provided, the user must be in it.
+      $ad_require_groups = $webform->getThirdPartySetting('uw_cfg_common', 'ad_require_groups');
+      if ($ad_require_groups && !array_intersect($ad_require_groups, $user_ad_groups)) {
+        return AccessResult::forbidden();
+      }
+      // Deny group. If at least one is provided, the user must not be in it.
+      $ad_deny_groups = $webform->getThirdPartySetting('uw_cfg_common', 'ad_deny_groups');
+      if ($ad_deny_groups && array_intersect($ad_deny_groups, $user_ad_groups)) {
+        return AccessResult::forbidden();
+      }
+      break;
+  }
+
+  return AccessResult::neutral();
+}
+
 /**
  * Implements hook_views_plugins_field_alter().
  */
-- 
GitLab