lock exported timesheets (#798)

This commit is contained in:
Kevin Papst
2019-05-22 22:28:29 +02:00
committed by GitHub
parent 871b2e52c7
commit fea3495098
22 changed files with 387 additions and 68 deletions

View File

@@ -616,4 +616,52 @@ class TimesheetController extends BaseApiController
return $this->viewHandler->handle($view);
}
/**
* Switch the export state of a timesheet record to (un-)lock it
*
* @SWG\Response(
* response=200,
* description="Switches the exported state on the record and therefor locks / unlocks it for further updates. Needs edit_export_*_timesheet permission.",
* @SWG\Schema(ref="#/definitions/TimesheetEntity")
* )
* @SWG\Parameter(
* name="id",
* in="path",
* type="integer",
* description="Timesheet record ID to switch export state",
* required=true,
* )
*
* @Security("is_granted('edit_export_own_timesheet') or is_granted('edit_export_other_timesheet')")
*
* @param int $id
* @return Response
*/
public function exportAction($id)
{
/** @var Timesheet $timesheet */
$timesheet = $this->repository->find($id);
if (null === $timesheet) {
throw new NotFoundException();
}
if (!$this->isGranted('edit_export', $timesheet)) {
throw new AccessDeniedHttpException(
sprintf('You are not allowed to %s this timesheet', ($timesheet->isExported() ? 'unlock' : 'lock'))
);
}
$timesheet->setExported(!$timesheet->isExported());
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($timesheet);
$entityManager->flush();
$view = new View($timesheet, 200);
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
return $this->viewHandler->handle($view);
}
}

View File

@@ -18,6 +18,8 @@ use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Command used to create a release package with pre-installed composer, SQLite database and user.
*
* @codeCoverageIgnore
*/
class CreateReleaseCommand extends Command
{

View File

@@ -37,6 +37,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
* Command used to import data from a Kimai v1 installation.
* Getting help in improving this script would be fantastic, it currently only handles the most basic use-cases.
*
* This command is way to messy and complex to be tested ... so we use something, which I actually don't like:
* @codeCoverageIgnore
*/
class KimaiImporterCommand extends Command

View File

@@ -19,6 +19,11 @@ use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Command used to execute all the basic application bootstrapping AFTER "composer install" was executed.
*
* This command is NOT used during runtime and only meant for developers on their local machines.
* I am too lazy to think about how this could be tested ... and this is one of the rare edge cases where I don't
* feel like it is necessary, so I "cheat" with:
* @codeCoverageIgnore
*/
class ResetCommand extends Command
{

View File

@@ -93,6 +93,7 @@ class Extensions extends AbstractExtension
'debug' => 'far fa-file-alt',
'profile-stats' => 'far fa-chart-bar',
'profile' => 'fas fa-user-edit',
'warning' => 'fas fa-exclamation-triangle',
];
/**

View File

@@ -85,12 +85,24 @@ class TimesheetVoter extends AbstractVoter
$permission .= $attribute;
break;
case self::EDIT:
if (!$this->canEdit($user, $subject)) {
return false;
}
$permission .= $attribute;
break;
case self::DELETE:
if (!$this->canDelete($user, $subject)) {
return false;
}
$permission .= $attribute;
break;
case self::VIEW_RATE:
case self::EDIT_RATE:
case self::STOP:
case self::EDIT:
case self::VIEW:
case self::DELETE:
case self::EXPORT:
case self::EDIT_EXPORT:
$permission .= $attribute;
@@ -114,11 +126,7 @@ class TimesheetVoter extends AbstractVoter
return $this->hasRolePermission($user, $permission);
}
/**
* @param Timesheet $timesheet
* @return bool
*/
protected function canStart(Timesheet $timesheet)
protected function canStart(Timesheet $timesheet): bool
{
// possible improvements for the future:
// we could check the amount of active entries (maybe slow)
@@ -142,4 +150,22 @@ class TimesheetVoter extends AbstractVoter
return true;
}
protected function canEdit(User $user, Timesheet $timesheet): bool
{
if ($timesheet->isExported() && !$this->hasRolePermission($user, 'edit_exported_timesheet')) {
return false;
}
return true;
}
protected function canDelete(User $user, Timesheet $timesheet): bool
{
if ($timesheet->isExported() && !$this->hasRolePermission($user, 'edit_exported_timesheet')) {
return false;
}
return true;
}
}