Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.2] [Guided Tours] Fix permission errors when recording user tour state #3284

Open
jgerman-bot opened this issue Sep 19, 2024 · 0 comments · May be fixed by #3287
Open

[5.2] [Guided Tours] Fix permission errors when recording user tour state #3284

jgerman-bot opened this issue Sep 19, 2024 · 0 comments · May be fixed by #3287

Comments

@jgerman-bot
Copy link

New language relevant PR in upstream repo: joomla/joomla-cms#44082 Here are the upstream changes:

Click to expand the diff!
diff --git a/administrator/components/com_guidedtours/src/Controller/AjaxController.php b/administrator/components/com_guidedtours/src/Controller/AjaxController.php
index 0dbf1929e04c..2e6b4416f631 100644
--- a/administrator/components/com_guidedtours/src/Controller/AjaxController.php
+++ b/administrator/components/com_guidedtours/src/Controller/AjaxController.php
@@ -38,87 +38,90 @@ public function fetchUserState()
         $user = $this->app->getIdentity();
 
         $tourId     = $this->app->input->getInt('tid', 0);
-        $stepNumber = $this->app->input->getString('sid', '');
+        $stepNumber = $this->app->input->getInt('sid', 0);
         $context    = $this->app->input->getString('context', '');
 
-        if ($user != null && $user->id > 0) {
-            $actionState = '';
-
-            switch ($context) {
-                case 'tour.complete':
-                    $actionState = 'completed';
-                    break;
-                case 'tour.cancel':
-                    $actionState = 'delayed';
-                    break;
-                case 'tour.skip':
-                    $actionState = 'skipped';
-                    break;
-            }
+        if ($user == null || $user->id <= 0) {
+            echo new JsonResponse(['success' => false, 'tourId' => $tourId], Text::_('COM_GUIDEDTOURS_USERSTATE_CONNECTEDONLY'), true);
+            $this->app->close();
+        }
+
+        if (!\in_array($context, ['tour.complete', 'tour.cancel', 'tour.skip'])) {
+            echo new JsonResponse(['success' => false, 'tourId' => $tourId], Text::_('COM_GUIDEDTOURS_USERSTATE_WRONGCONTEXT'), true);
+            $this->app->close();
+        }
 
-            PluginHelper::importPlugin('guidedtours');
-
-            // event onBeforeTourSaveUserState before save user tour state
-            $beforeEvent = AbstractEvent::create(
-                'onBeforeTourSaveUserState',
-                [
-                    'subject'     => new \stdClass(),
-                    'tourId'      => $tourId,
-                    'actionState' => $actionState,
-                    'stepNumber'  => $stepNumber,
-                ]
-            );
-
-            $this->app->getDispatcher()->dispatch('onBeforeTourSaveUserState', $beforeEvent);
-
-            // Save the tour state only when the tour auto-starts.
-            $tourModel = $this->getModel('Tour', 'Administrator');
-            if ($tourModel->isAutostart($tourId)) {
-                $result = $tourModel->saveTourUserState($tourId, $actionState);
-                if ($result) {
-                    $message = Text::sprintf('COM_GUIDEDTOURS_USERSTATE_STATESAVED', $user->id, $tourId);
-                } else {
-                    $message = Text::sprintf('COM_GUIDEDTOURS_USERSTATE_STATENOTSAVED', $user->id, $tourId);
-                }
+        if ($tourId <= 0) {
+            echo new JsonResponse(['success' => false, 'tourId' => $tourId], Text::_('COM_GUIDEDTOURS_USERSTATE_BADTOURID'), true);
+            $this->app->close();
+        }
+
+        $actionState = '';
+
+        switch ($context) {
+            case 'tour.complete':
+                $actionState = 'completed';
+                break;
+            case 'tour.cancel':
+                $actionState = 'delayed';
+                break;
+            case 'tour.skip':
+                $actionState = 'skipped';
+                break;
+        }
+
+        PluginHelper::importPlugin('guidedtours');
+
+        // event onBeforeTourSaveUserState before save user tour state
+        $beforeEvent = AbstractEvent::create(
+            'onBeforeTourSaveUserState',
+            [
+                'subject'     => new \stdClass(),
+                'tourId'      => $tourId,
+                'actionState' => $actionState,
+                'stepNumber'  => $stepNumber,
+            ]
+        );
+
+        $this->app->getDispatcher()->dispatch('onBeforeTourSaveUserState', $beforeEvent);
+
+        // Save the tour state only when the tour auto-starts.
+        $tourModel = $this->getModel('Tour', 'Administrator');
+        if ($tourModel->isAutostart($tourId)) {
+            $result = $tourModel->saveTourUserState($tourId, $actionState);
+            if ($result) {
+                $message = Text::sprintf('COM_GUIDEDTOURS_USERSTATE_STATESAVED', $user->id, $tourId);
             } else {
-                $result  = false;
                 $message = Text::sprintf('COM_GUIDEDTOURS_USERSTATE_STATENOTSAVED', $user->id, $tourId);
             }
-
-            // event onAfterTourSaveUserState after save user tour state (may override message)
-            $afterEvent = AbstractEvent::create(
-                'onAfterTourSaveUserState',
-                [
-                    'subject'     => new \stdClass(),
-                    'tourId'      => $tourId,
-                    'actionState' => $actionState,
-                    'stepNumber'  => $stepNumber,
-                    'result'      => $result,
-                    'message'     => &$message,
-                ]
-            );
-
-            $this->app->getDispatcher()->dispatch('onAfterTourSaveUserState', $afterEvent);
-
-            // Construct the response data
-            $data = [
-                'tourId'  => $tourId,
-                'stepId'  => $stepNumber,
-                'context' => $context,
-                'state'   => $actionState,
-            ];
-            echo new JsonResponse($data, $message);
-            $this->app->close();
         } else {
-            // Construct the response data
-            $data = [
-                'success' => false,
-                'tourId'  => $tourId,
-            ];
-
-            $message = Text::_('COM_GUIDEDTOURS_USERSTATE_CONNECTEDONLY');
-            echo new JsonResponse($data, $message, true);
-            $this->app->close();
+            $result  = false;
+            $message = Text::sprintf('COM_GUIDEDTOURS_USERSTATE_STATENOTSAVED', $user->id, $tourId);
         }
+
+        // event onAfterTourSaveUserState after save user tour state (may override message)
+        $afterEvent = AbstractEvent::create(
+            'onAfterTourSaveUserState',
+            [
+                'subject'     => new \stdClass(),
+                'tourId'      => $tourId,
+                'actionState' => $actionState,
+                'stepNumber'  => $stepNumber,
+                'result'      => $result,
+                'message'     => &$message,
+            ]
+        );
+
+        $this->app->getDispatcher()->dispatch('onAfterTourSaveUserState', $afterEvent);
+
+        // Construct the response data
+        $data = [
+            'tourId'  => $tourId,
+            'stepId'  => $stepNumber,
+            'context' => $context,
+            'state'   => $actionState,
+        ];
+        echo new JsonResponse($data, $message);
+        $this->app->close();
     }
 }
diff --git a/administrator/components/com_guidedtours/src/Dispatcher/Dispatcher.php b/administrator/components/com_guidedtours/src/Dispatcher/Dispatcher.php
new file mode 100644
index 000000000000..31a2470d6aa5
--- /dev/null
+++ b/administrator/components/com_guidedtours/src/Dispatcher/Dispatcher.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @package     Joomla.Administrator
+ * @subpackage  com_guidedtours
+ *
+ * @copyright   (C) 2024 Open Source Matters, Inc. <https://www.joomla.org>
+ * @license     GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+namespace Joomla\Component\Guidedtours\Administrator\Dispatcher;
+
+use Joomla\CMS\Access\Exception\NotAllowed;
+use Joomla\CMS\Dispatcher\ComponentDispatcher;
+
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
+
+/**
+ * ComponentDispatcher class for com_guidedtours
+ *
+ * @since  __DEPLOY_VERSION__
+ */
+class Dispatcher extends ComponentDispatcher
+{
+    /**
+     * Method to check component access permission
+     *
+     * @return  void
+     *
+     * @throws  \Exception|NotAllowed
+     */
+    protected function checkAccess()
+    {
+        $command = $this->input->getCmd('task', 'display');
+        if ($this->app->isClient('administrator') && $command == 'ajax.fetchUserState') {
+            return;
+        }
+
+        parent::checkAccess();
+    }
+}
diff --git a/administrator/language/en-GB/com_guidedtours.ini b/administrator/language/en-GB/com_guidedtours.ini
index 465e8c30a082..9e8a9aef29e7 100644
--- a/administrator/language/en-GB/com_guidedtours.ini
+++ b/administrator/language/en-GB/com_guidedtours.ini
@@ -94,8 +94,10 @@ COM_GUIDEDTOURS_TYPE_REDIRECT_URL_DESC="Enter the relative URL of the page you w
 COM_GUIDEDTOURS_TYPE_REDIRECT_URL_LABEL="Relative URL"
 COM_GUIDEDTOURS_URL_LABEL="Relative URL"
 COM_GUIDEDTOURS_URL_DESC="Enter the relative URL of the page from where you want to Start the tour, e.g administrator/index.php?option=com_guidedtours&view=tours for the tours' list page."
+COM_GUIDEDTOURS_USERSTATE_BADTOURID="The Tour needs to have a positive id."
 ; 'Tour User states' are conditions in which a guided tour user leaves a tour, either by cancelling, completing or skipping a tour.
 COM_GUIDEDTOURS_USERSTATE_CONNECTEDONLY="The recording of User states for a tour is only available to logged-in users."
 COM_GUIDEDTOURS_USERSTATE_STATENOTSAVED="The User state was not saved for user %1$s tour %2$s."
 COM_GUIDEDTOURS_USERSTATE_STATESAVED="The User state was saved for user %1$s tour %2$s."
+COM_GUIDEDTOURS_USERSTATE_WRONGCONTEXT="The Tour User state context is incorrect."
 COM_GUIDEDTOURS_XML_DESCRIPTION="Component for managing Guided Tours functionality."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

4 participants