Tasks Module Stage 1: RBAC + Validation + Events Fix
- Add canCreate/canEdit/canDelete checks in TasksController - Add input validation in store() and update() methods - Fix events naming: task.* (singular) instead of tasks.* - Add CSRF validation and parameter checks for API endpoints
This commit is contained in:
@@ -216,6 +216,10 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if (!$this->access->canCreate('tasks')) {
|
||||
return $this->forbiddenResponse('Нет прав для создания задач');
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$boardId = (int) ($this->request->getGet('board') ?? 0);
|
||||
|
||||
@@ -263,15 +267,33 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
if (!$this->access->canCreate('tasks')) {
|
||||
return $this->forbiddenResponse('Нет прав для создания задач');
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
// Валидация входных данных
|
||||
$validation = \Config\Services::validation();
|
||||
$validation->setRules([
|
||||
'title' => 'required|min_length[3]|max_length[255]',
|
||||
'board_id' => 'required|integer',
|
||||
'column_id' => 'required|integer',
|
||||
'priority' => 'in_list[low,medium,high,urgent]',
|
||||
'due_date' => 'permit_empty|valid_date[Y-m-d]',
|
||||
]);
|
||||
|
||||
if (!$validation->withRequest($this->request)->run()) {
|
||||
return redirect()->back()->withErrors($validation->getErrors())->withInput();
|
||||
}
|
||||
|
||||
$data = [
|
||||
'organization_id' => $organizationId,
|
||||
'board_id' => $this->request->getPost('board_id'),
|
||||
'column_id' => $this->request->getPost('column_id'),
|
||||
'title' => $this->request->getPost('title'),
|
||||
'description' => $this->request->getPost('description'),
|
||||
'board_id' => (int) $this->request->getPost('board_id'),
|
||||
'column_id' => (int) $this->request->getPost('column_id'),
|
||||
'title' => trim($this->request->getPost('title')),
|
||||
'description' => trim($this->request->getPost('description')) ?: null,
|
||||
'priority' => $this->request->getPost('priority') ?? 'medium',
|
||||
'due_date' => $this->request->getPost('due_date') ?: null,
|
||||
];
|
||||
@@ -314,6 +336,10 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function edit(int $id)
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->forbiddenResponse('Нет прав для редактирования задач');
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$task = $this->taskService->getTask($id, $organizationId);
|
||||
|
||||
@@ -353,14 +379,32 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function update(int $id)
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->forbiddenResponse('Нет прав для редактирования задач');
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
// Валидация входных данных
|
||||
$validation = \Config\Services::validation();
|
||||
$validation->setRules([
|
||||
'title' => 'required|min_length[3]|max_length[255]',
|
||||
'board_id' => 'required|integer',
|
||||
'column_id' => 'required|integer',
|
||||
'priority' => 'in_list[low,medium,high,urgent]',
|
||||
'due_date' => 'permit_empty|valid_date[Y-m-d]',
|
||||
]);
|
||||
|
||||
if (!$validation->withRequest($this->request)->run()) {
|
||||
return redirect()->back()->withErrors($validation->getErrors())->withInput();
|
||||
}
|
||||
|
||||
$data = [
|
||||
'board_id' => $this->request->getPost('board_id'),
|
||||
'column_id' => $this->request->getPost('column_id'),
|
||||
'title' => $this->request->getPost('title'),
|
||||
'description' => $this->request->getPost('description'),
|
||||
'board_id' => (int) $this->request->getPost('board_id'),
|
||||
'column_id' => (int) $this->request->getPost('column_id'),
|
||||
'title' => trim($this->request->getPost('title')),
|
||||
'description' => trim($this->request->getPost('description')) ?: null,
|
||||
'priority' => $this->request->getPost('priority') ?? 'medium',
|
||||
'due_date' => $this->request->getPost('due_date') ?: null,
|
||||
];
|
||||
@@ -383,6 +427,10 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function destroy(int $id)
|
||||
{
|
||||
if (!$this->access->canDelete('tasks')) {
|
||||
return $this->forbiddenResponse('Нет прав для удаления задач');
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
@@ -396,11 +444,25 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function moveColumn()
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Нет прав для изменения задач'
|
||||
]);
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
$taskId = $this->request->getPost('id');
|
||||
$newColumnId = $this->request->getPost('column_id');
|
||||
$taskId = (int) $this->request->getPost('id');
|
||||
$newColumnId = (int) $this->request->getPost('column_id');
|
||||
|
||||
if (!$taskId || !$newColumnId) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Некорректные параметры'
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->taskService->changeColumn($taskId, $newColumnId, $userId);
|
||||
|
||||
@@ -418,6 +480,13 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function complete(int $id)
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Нет прав для изменения задач'
|
||||
]);
|
||||
}
|
||||
|
||||
$userId = $this->getCurrentUserId();
|
||||
$result = $this->taskService->completeTask($id, $userId);
|
||||
|
||||
@@ -429,6 +498,13 @@ class TasksController extends BaseController
|
||||
*/
|
||||
public function reopen(int $id)
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Нет прав для изменения задач'
|
||||
]);
|
||||
}
|
||||
|
||||
$userId = $this->getCurrentUserId();
|
||||
$result = $this->taskService->reopenTask($id, $userId);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class TaskService
|
||||
}
|
||||
|
||||
// Генерируем событие
|
||||
Events::trigger('tasks.created', $taskId, $data, $userId);
|
||||
Events::trigger('task.created', $taskId, $data, $userId);
|
||||
}
|
||||
|
||||
return $taskId;
|
||||
@@ -63,7 +63,7 @@ class TaskService
|
||||
$result = $this->taskModel->update($taskId, $data);
|
||||
|
||||
if ($result) {
|
||||
Events::trigger('tasks.updated', $taskId, $data, $userId);
|
||||
Events::trigger('task.updated', $taskId, $data, $userId);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -96,7 +96,7 @@ class TaskService
|
||||
$result = $this->taskModel->update($taskId, $data);
|
||||
|
||||
if ($result) {
|
||||
Events::trigger('tasks.column_changed', $taskId, $oldColumnId, $newColumnId, $userId);
|
||||
Events::trigger('task.column_changed', $taskId, $oldColumnId, $newColumnId, $userId);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -117,7 +117,7 @@ class TaskService
|
||||
]);
|
||||
|
||||
if ($result) {
|
||||
Events::trigger('tasks.completed', $taskId, $userId);
|
||||
Events::trigger('task.completed', $taskId, $userId);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -138,7 +138,7 @@ class TaskService
|
||||
]);
|
||||
|
||||
if ($result) {
|
||||
Events::trigger('tasks.reopened', $taskId, $userId);
|
||||
Events::trigger('task.reopened', $taskId, $userId);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -157,7 +157,7 @@ class TaskService
|
||||
$result = $this->taskModel->delete($taskId);
|
||||
|
||||
if ($result) {
|
||||
Events::trigger('tasks.deleted', $taskId, $userId);
|
||||
Events::trigger('task.deleted', $taskId, $userId);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
Reference in New Issue
Block a user