Started widening of activity logging

In progress, Need to implement much of the logging in controllers.
Also cleaned up base controller along the way.
This commit is contained in:
Dan Brown
2020-11-18 23:38:44 +00:00
parent 712ccd23c4
commit 3f7180fa99
11 changed files with 115 additions and 60 deletions

View File

@ -1,7 +1,5 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Actions\ActivityType;
use BookStack\Facades\Activity;
use BookStack\Entities\Repos\BookshelfRepo;
use BookStack\Entities\Bookshelf;
use Exception;

View File

@ -2,21 +2,20 @@
namespace BookStack\Http\Controllers;
use BookStack\Facades\Activity;
use BookStack\Interfaces\Loggable;
use BookStack\Ownable;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Validation\ValidationException;
abstract class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
/**
* Controller constructor.
*/
public function __construct()
{
//
@ -43,9 +42,8 @@ abstract class Controller extends BaseController
/**
* Adds the page title into the view.
* @param $title
*/
public function setPageTitle($title)
public function setPageTitle(string $title)
{
view()->share('pageTitle', $title);
}
@ -67,79 +65,59 @@ abstract class Controller extends BaseController
}
/**
* Checks for a permission.
* @param string $permissionName
* @return bool|\Illuminate\Http\RedirectResponse
* Checks that the current user has the given permission otherwise throw an exception.
*/
protected function checkPermission($permissionName)
protected function checkPermission(string $permission): void
{
if (!user() || !user()->can($permissionName)) {
if (!user() || !user()->can($permission)) {
$this->showPermissionError();
}
return true;
}
/**
* Check the current user's permissions against an ownable item.
* @param $permission
* @param Ownable $ownable
* @return bool
* Check the current user's permissions against an ownable item otherwise throw an exception.
*/
protected function checkOwnablePermission($permission, Ownable $ownable)
protected function checkOwnablePermission(string $permission, Ownable $ownable): void
{
if (userCan($permission, $ownable)) {
return true;
if (!userCan($permission, $ownable)) {
$this->showPermissionError();
}
return $this->showPermissionError();
}
/**
* Check if a user has a permission or bypass if the callback is true.
* @param $permissionName
* @param $callback
* @return bool
* Check if a user has a permission or bypass the permission
* check if the given callback resolves true.
*/
protected function checkPermissionOr($permissionName, $callback)
protected function checkPermissionOr(string $permission, callable $callback): void
{
$callbackResult = $callback();
if ($callbackResult === false) {
$this->checkPermission($permissionName);
if ($callback() !== true) {
$this->checkPermission($permission);
}
return true;
}
/**
* Check if the current user has a permission or bypass if the provided user
* id matches the current user.
* @param string $permissionName
* @param int $userId
* @return bool
*/
protected function checkPermissionOrCurrentUser(string $permissionName, int $userId)
protected function checkPermissionOrCurrentUser(string $permission, int $userId): void
{
return $this->checkPermissionOr($permissionName, function () use ($userId) {
$this->checkPermissionOr($permission, function () use ($userId) {
return $userId === user()->id;
});
}
/**
* Send back a json error message.
* @param string $messageText
* @param int $statusCode
* @return mixed
*/
protected function jsonError($messageText = "", $statusCode = 500)
protected function jsonError(string $messageText = "", int $statusCode = 500): JsonResponse
{
return response()->json(['message' => $messageText, 'status' => 'error'], $statusCode);
}
/**
* Create a response that forces a download in the browser.
* @param string $content
* @param string $fileName
* @return \Illuminate\Http\Response
*/
protected function downloadResponse(string $content, string $fileName)
protected function downloadResponse(string $content, string $fileName): Response
{
return response()->make($content, 200, [
'Content-Type' => 'application/octet-stream',
@ -149,31 +127,37 @@ abstract class Controller extends BaseController
/**
* Show a positive, successful notification to the user on next view load.
* @param string $message
*/
protected function showSuccessNotification(string $message)
protected function showSuccessNotification(string $message): void
{
session()->flash('success', $message);
}
/**
* Show a warning notification to the user on next view load.
* @param string $message
*/
protected function showWarningNotification(string $message)
protected function showWarningNotification(string $message): void
{
session()->flash('warning', $message);
}
/**
* Show an error notification to the user on next view load.
* @param string $message
*/
protected function showErrorNotification(string $message)
protected function showErrorNotification(string $message): void
{
session()->flash('error', $message);
}
/**
* Log an activity in the system.
* @param string|Loggable
*/
protected function logActivity(string $type, $detail = ''): void
{
Activity::add($type, $detail);
}
/**
* Get the validation rules for image files.
*/

View File

@ -2,6 +2,7 @@
namespace BookStack\Http\Controllers;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Managers\TrashCan;
use BookStack\Notifications\TestEmail;
use BookStack\Uploads\ImageService;
@ -35,6 +36,7 @@ class MaintenanceController extends Controller
public function cleanupImages(Request $request, ImageService $imageService)
{
$this->checkPermission('settings-manage');
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'cleanup-images');
$checkRevisions = !($request->get('ignore_revisions', 'false') === 'true');
$dryRun = !($request->has('confirm'));
@ -61,6 +63,7 @@ class MaintenanceController extends Controller
public function sendTestEmail()
{
$this->checkPermission('settings-manage');
$this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'send-test-email');
try {
user()->notify(new TestEmail());

View File

@ -1,5 +1,6 @@
<?php namespace BookStack\Http\Controllers;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Deletion;
use BookStack\Entities\Managers\TrashCan;
@ -56,6 +57,7 @@ class RecycleBinController extends Controller
{
/** @var Deletion $deletion */
$deletion = Deletion::query()->findOrFail($id);
$this->logActivity(ActivityType::RECYCLE_BIN_RESTORE, $deletion);
$restoreCount = (new TrashCan())->restoreFromDeletion($deletion);
$this->showSuccessNotification(trans('settings.recycle_bin_restore_notification', ['count' => $restoreCount]));
@ -85,6 +87,7 @@ class RecycleBinController extends Controller
$deletion = Deletion::query()->findOrFail($id);
$deleteCount = (new TrashCan())->destroyFromDeletion($deletion);
$this->logActivity(ActivityType::RECYCLE_BIN_DESTROY, $deletion);
$this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
return redirect($this->recycleBinBaseUrl);
}
@ -97,6 +100,7 @@ class RecycleBinController extends Controller
{
$deleteCount = (new TrashCan())->empty();
$this->logActivity(ActivityType::RECYCLE_BIN_EMPTY);
$this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
return redirect($this->recycleBinBaseUrl);
}

View File

@ -1,5 +1,6 @@
<?php namespace BookStack\Http\Controllers;
use BookStack\Actions\ActivityType;
use BookStack\Auth\User;
use BookStack\Uploads\ImageRepo;
use Illuminate\Http\Request;
@ -47,10 +48,10 @@ class SettingController extends Controller
// Cycles through posted settings and update them
foreach ($request->all() as $name => $value) {
$key = str_replace('setting-', '', trim($name));
if (strpos($name, 'setting-') !== 0) {
continue;
}
$key = str_replace('setting-', '', trim($name));
setting()->put($key, $value);
}
@ -68,8 +69,10 @@ class SettingController extends Controller
setting()->remove('app-logo');
}
$section = $request->get('section', '');
$this->logActivity(ActivityType::SETTINGS_UPDATE, $section);
$this->showSuccessNotification(trans('settings.settings_save_success'));
$redirectLocation = '/settings#' . $request->get('section', '');
$redirectLocation = '/settings#' . $section;
return redirect(rtrim($redirectLocation, '#'));
}
}