Add audit logging.

This commit is contained in:
James Cole 2019-02-08 07:13:59 +01:00
parent f1e83f240e
commit d63c9c9aea
6 changed files with 93 additions and 9 deletions

View File

@ -111,7 +111,7 @@ class CreateController extends Controller
$this->rememberPreviousUri('accounts.create.uri');
}
$request->session()->forget('accounts.create.fromStore');
Log::channel('audit')->info('Create new account.');
return view('accounts.create', compact('subTitleIcon', 'what', 'interestPeriods', 'subTitle', 'roles', 'liabilityTypes'));
}
@ -131,7 +131,7 @@ class CreateController extends Controller
$request->session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name]));
app('preferences')->mark();
Log::channel('audit')->info('Store new account.', $data);
// update preferences if necessary:
$frontPage = app('preferences')->get('frontPageAccounts', [])->data;

View File

@ -91,6 +91,8 @@ class CurrencyController extends Controller
}
$request->session()->forget('currencies.create.fromStore');
Log::channel('audit')->info('Create new currency.');
return view('currencies.create', compact('subTitleIcon', 'subTitle'));
}
@ -107,6 +109,8 @@ class CurrencyController extends Controller
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
Log::channel('audit')->info(sprintf('Make %s the default currency.', $currency->code));
$this->repository->enable($currency);
$request->session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
@ -128,6 +132,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@ -135,6 +140,7 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
$request->session()->flash('error', (string)trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but currency is in use.', $currency->code));
return redirect(route('currencies.index'));
}
@ -142,6 +148,7 @@ class CurrencyController extends Controller
// put previous url in session
$this->rememberPreviousUri('currencies.delete.uri');
$subTitle = (string)trans('form.delete_currency', ['name' => $currency->name]);
Log::channel('audit')->info(sprintf('Visit page to delete currency %s.', $currency->code));
return view('currencies.delete', compact('currency', 'subTitle'));
}
@ -161,6 +168,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
Log::channel('audit')->info(sprintf('Tried to delete currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@ -168,11 +176,13 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
$request->session()->flash('error', (string)trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
Log::channel('audit')->info(sprintf('Tried to delete currency %s but is in use.', $currency->code));
return redirect(route('currencies.index'));
}
Log::channel('audit')->info(sprintf('Deleted currency %s.', $currency->code));
$this->repository->destroy($currency);
$request->session()->flash('success', (string)trans('firefly.deleted_currency', ['name' => $currency->name]));
return redirect($this->getPreviousUri('currencies.delete.uri'));
@ -193,6 +203,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
Log::channel('audit')->info(sprintf('Tried to disable currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@ -200,20 +211,23 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
$request->session()->flash('error', (string)trans('firefly.cannot_disable_currency', ['name' => $currency->name]));
Log::channel('audit')->info(sprintf('Tried to disable currency %s but is in use.', $currency->code));
return redirect(route('currencies.index'));
}
$this->repository->disable($currency);
Log::channel('audit')->info(sprintf('Disabled currency %s.', $currency->code));
// if no currencies are enabled, enable the first one in the DB (usually the EUR)
if (0 === $this->repository->get()->count()) {
/** @var TransactionCurrency $first */
$first = $this->repository->getAll()->first();
if (null === $first) {
throw new FireflyException('No currencies found.');
}
Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $first->code));
$this->repository->enable($first);
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->set('currencyPreference', $first->code);
app('preferences')->mark();
}
@ -237,6 +251,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
Log::channel('audit')->info(sprintf('Tried to edit currency %s but is not owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@ -275,6 +290,7 @@ class CurrencyController extends Controller
$this->repository->enable($currency);
session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
Log::channel('audit')->info(sprintf('Enabled currency %s.', $currency->code));
return redirect(route('currencies.index'));
}
@ -329,21 +345,23 @@ class CurrencyController extends Controller
{
/** @var User $user */
$user = auth()->user();
$data = $request->getCurrencyData();
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
Log::error('User ' . auth()->user()->id . ' is not admin, but tried to store a currency.');
Log::channel('audit')->info('Tried to create (POST) currency without admin rights.', $data);
return redirect($this->getPreviousUri('currencies.create.uri'));
// @codeCoverageIgnoreEnd
}
$data = $request->getCurrencyData();
$data['enabled'] = true;
$currency = $this->repository->store($data);
$redirect = redirect($this->getPreviousUri('currencies.create.uri'));
if (null !== $currency) {
$request->session()->flash('success', (string)trans('firefly.created_currency', ['name' => $currency->name]));
Log::channel('audit')->info('Created (POST) currency.', $data);
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
$request->session()->put('currencies.create.fromStore', true);
@ -353,6 +371,7 @@ class CurrencyController extends Controller
}
}
if (null === $currency) {
Log::channel('audit')->info('Could not store (POST) currency without admin rights.', $data);
$request->session()->flash('error', (string)trans('firefly.could_not_store_currency'));
}
@ -372,16 +391,19 @@ class CurrencyController extends Controller
{
/** @var User $user */
$user = auth()->user();
$data = $request->getCurrencyData();
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
Log::channel('audit')->info('Tried to update (POST) currency without admin rights.', $data);
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
}
$data = $request->getCurrencyData();
$currency = $this->repository->update($currency, $data);
Log::channel('audit')->info('Updated (POST) currency.', $data);
$request->session()->flash('success', (string)trans('firefly.updated_currency', ['name' => $currency->name]));
app('preferences')->mark();

View File

@ -67,6 +67,7 @@ class HomeController extends Controller
Log::debug('Received dateRange', ['start' => $request->get('start'), 'end' => $request->get('end'), 'label' => $request->get('label')]);
// check if the label is "everything" or "Custom range" which will betray
// a possible problem with the budgets.
if ($label === (string)trans('firefly.everything') || $label === (string)trans('firefly.customRange')) {
@ -103,6 +104,8 @@ class HomeController extends Controller
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
Log::channel('audit')->info('User visits homepage.');
if (0 === $count) {
return redirect(route('new-user.index'));
}

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Support\Logging;
/**
* Class AuditLogger
*/
class AuditLogger
{
/**
* Customize the given logger instance.
*
* @param \Illuminate\Log\Logger $logger
*
* @return void
*/
public function __invoke($logger)
{
$processor = new AuditProcessor();
$logger->pushProcessor($processor);
}
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Support\Logging;
/**
* Class AuditProcessor
*/
class AuditProcessor
{
/**
* @param array $record
*
* @return array
*/
public function __invoke(array $record): array
{
$record['extra']['path'] = request()->method() . ':' . request()->url();
$record['extra']['IP'] = app('request')->ip();
if (auth()->check()) {
$record['extra']['user'] = auth()->user()->email;
}
return $record;
}
}

View File

@ -19,7 +19,9 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
use FireflyIII\Support\Logging\AuditLogger;
return [
@ -66,13 +68,19 @@ return [
'path' => 'php://stdout',
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/ff3-' . PHP_SAPI . '.log'),
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'days' => 7,
],
'audit' => [
'driver' => 'daily',
'path' => storage_path('logs/ff3-audit.log'),
'tap' => [AuditLogger::class],
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'days' => 90,
],
'dailytest' => [
'driver' => 'daily',
'path' => storage_path('logs/test-ff3-' . PHP_SAPI . '.log'),