Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ protected function getListQuery(): QueryInterface
$db->quoteName('a.priority'),
$db->quoteName('a.ordering'),
$db->quoteName('a.note'),
$db->quoteName('a.created_by'),
$db->quoteName('a.checked_out'),
$db->quoteName('a.checked_out_time'),
]
Expand Down
28 changes: 28 additions & 0 deletions administrator/components/com_scheduler/src/Scheduler/Scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\User\User;
use Joomla\Component\Scheduler\Administrator\Extension\SchedulerComponent;
use Joomla\Component\Scheduler\Administrator\Model\TaskModel;
use Joomla\Component\Scheduler\Administrator\Model\TasksModel;
Expand Down Expand Up @@ -325,4 +326,31 @@ public function fetchTaskRecords(array $filters, array $listConfig): array

return $model->getItems() ?: [];
}

/**
* Determine whether a {@see User} is allowed to run a task record. Expects a task as an object from
* {@see fetchTaskRecords}.
*
* @param object $taskRecord The task record to check authorization against.
* @param User $user The user to check authorization for.
*
* @return boolean True if the user is authorized to run the task.
*
* @since __DEPLOY_VERSION__
*/
public static function isAuthorizedToRun(object $taskRecord, User $user): bool
{
/**
* We allow the user to run a task if they have the permission or if they created the task & still have the authority
* to create tasks.
*/
if (
$user->authorise('core.testrun', 'com_scheduler.task.' . $taskRecord->id)
|| ($user->id == $taskRecord->created_by && $user->authorise('core.create', 'com_scheduler'))
) {
return true;
}

return false;
}
}
25 changes: 18 additions & 7 deletions administrator/components/com_scheduler/tmpl/tasks/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler;
use Joomla\Component\Scheduler\Administrator\Task\Status;
use Joomla\Component\Scheduler\Administrator\View\Tasks\HtmlView;

Expand Down Expand Up @@ -257,13 +258,23 @@ class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="

<!-- Test task -->
<td class="small d-none d-md-table-cell">
<button type="button" class="btn btn-sm btn-warning" <?php echo $item->state < 0 ? 'disabled' : ''; ?>
data-scheduler-run
data-id="<?php echo (int) $item->id; ?>" data-title="<?php echo htmlspecialchars($item->title); ?>"
data-url="<?php echo Route::_('index.php?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=' . (int) $item->id); ?>">
<span class="fa fa-play fa-sm me-2"></span>
<?php echo Text::_('COM_SCHEDULER_TEST_RUN'); ?>
</button>
<div id="run-task-btn-wrapper"
<?php
$disabled = ($item->state < 0 || !Scheduler::isAuthorizedToRun($item, $user));
if ($disabled) :
$reason = Text::_($item->state < 0 ? "COM_SCHEDULER_MANAGER_TOOLTIP_TASK_TRASHED" : "COM_SCHEDULER_MANAGER_TOOLTIP_NOT_AUTHORIZED");
echo ' data-toggle="tooltip" data-placement="top" title="' . $reason . '"';
endif;
?>
>
<button type="button" class="btn btn-sm btn-warning" <?php echo $disabled ? 'disabled' : ''; ?>
data-scheduler-run
data-id="<?php echo (int) $item->id; ?>" data-title="<?php echo htmlspecialchars($item->title); ?>"
data-url="<?php echo Route::_('index.php?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=' . (int) $item->id); ?>">
<span class="fa fa-play fa-sm me-2"></span>
<?php echo Text::_('COM_SCHEDULER_TEST_RUN'); ?>
</button>
</div>
</td>

<!-- Priority -->
Expand Down
2 changes: 2 additions & 0 deletions administrator/language/en-GB/com_scheduler.ini
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ COM_SCHEDULER_LAST_RUN_DESC="Last Run descending"
COM_SCHEDULER_MANAGER_TASKS="Scheduled Tasks"
COM_SCHEDULER_MANAGER_TASK_EDIT="Edit Task"
COM_SCHEDULER_MANAGER_TASK_NEW="New Task"
COM_SCHEDULER_MANAGER_TOOLTIP_NOT_AUTHORIZED="Not authorized"
COM_SCHEDULER_MANAGER_TOOLTIP_TASK_FAILING="Task failed. Exit code: %1$d"
COM_SCHEDULER_MANAGER_TOOLTIP_TASK_TRASHED="Task has been trashed"
COM_SCHEDULER_MSG_DUETASKS="There is at least one due task which should have already run. Please make sure that at least one cron scheduler is enabled and running."
COM_SCHEDULER_MSG_MANAGE_NO_TASK_PLUGINS="There are no task types matching your query."
COM_SCHEDULER_NEW_TASK="New Task"
Expand Down
12 changes: 9 additions & 3 deletions plugins/system/schedulerunner/src/Extension/ScheduleRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,15 @@ public function runTestCron(Event $event)
$id = (int) $this->getApplication()->getInput()->getInt('id');
$allowConcurrent = $this->getApplication()->getInput()->getBool('allowConcurrent', false);

$user = $this->getApplication()->getIdentity();
if (empty($id)) {
throw new \Exception($this->getApplication()->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403);
}

$scheduler = new Scheduler();
$taskRecord = $scheduler->fetchTaskRecord($id, true);
$user = $this->getApplication()->getIdentity();

if (empty($id) || !$user->authorise('core.testrun', 'com_scheduler.task.' . $id)) {
if (empty($taskRecord) || !Scheduler::isAuthorizedToRun($taskRecord, $user)) {
throw new \Exception($this->getApplication()->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403);
}

Expand All @@ -245,7 +251,7 @@ public function runTestCron(Event $event)
* We will allow CLI exclusive tasks to be fetched and executed, it's left to routines to do a runtime check
* if they want to refuse normal operation.
*/
$task = (new Scheduler())->getTask(
$task = $scheduler->getTask(
[
'id' => $id,
'allowDisabled' => true,
Expand Down