mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 18:54:58 +00:00 
			
		
		
		
	Add audit logging.
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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')); | ||||
|         } | ||||
|   | ||||
							
								
								
									
										23
									
								
								app/Support/Logging/AuditLogger.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/Support/Logging/AuditLogger.php
									
									
									
									
									
										Normal 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); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										28
									
								
								app/Support/Logging/AuditProcessor.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Support/Logging/AuditProcessor.php
									
									
									
									
									
										Normal 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; | ||||
|     } | ||||
| } | ||||
| @@ -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'), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user