From f27f67cadb708e3acbba9ae51cfa5cb424d8cdf0 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 15 Jan 2023 09:11:50 -0500 Subject: [PATCH 1/3] build: add Logger aliases --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dad6b4c..fe8a155 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,10 @@ "laravel": { "providers": [ "Sourcetoad\\Logger\\LoggerServiceProvider" - ] + ], + "aliases": { + "Logger": "Sourcetoad\\Logger\\LoggerFacade" + } } }, "require-dev": { From af1250e0ec1e24c1923e6f61a486e72319bc267f Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 15 Jan 2023 09:12:07 -0500 Subject: [PATCH 2/3] refactor: adjust for php8 --- src/Commands/AuditModelResolver.php | 13 +---- src/Helpers/AuditResolver.php | 6 +- src/Listeners/LogExplicitLogout.php | 4 +- src/Listeners/LogFailedLogin.php | 2 +- src/Listeners/LogLockedLogins.php | 2 +- src/Listeners/LogPasswordReset.php | 2 +- src/Listeners/LogSuccessfulLogin.php | 2 +- src/Logger.php | 40 ++++++-------- src/LoggerFacade.php | 2 +- src/LoggerServiceProvider.php | 17 +++--- src/Middleware/LogOutputtedKeys.php | 18 ++---- src/Models/AuditActivity.php | 83 ++++++++++------------------ src/Models/AuditChange.php | 11 ++-- src/Models/AuditKey.php | 2 +- src/Models/AuditModel.php | 9 ++- src/Models/AuditRoute.php | 2 +- src/Traits/HasRelationships.php | 8 +-- src/Traits/Immutable.php | 2 +- src/Traits/Trackable.php | 4 +- 19 files changed, 87 insertions(+), 142 deletions(-) diff --git a/src/Commands/AuditModelResolver.php b/src/Commands/AuditModelResolver.php index 13a8214..77336c4 100644 --- a/src/Commands/AuditModelResolver.php +++ b/src/Commands/AuditModelResolver.php @@ -9,21 +9,10 @@ class AuditModelResolver extends Command { - /** - * The name and signature of the console command. - * - * @var string - */ protected $signature = 'logger:audit-resolver'; - - /** - * The console command description. - * - * @var string - */ protected $description = 'Identifiers users associated with models/changes logged.'; - public function handle() + public function handle(): void { AuditChange::query()->where('processed', false)->chunkById(200, function ($items) { /** @var AuditChange $item */ diff --git a/src/Helpers/AuditResolver.php b/src/Helpers/AuditResolver.php index 9819583..ab7440b 100644 --- a/src/Helpers/AuditResolver.php +++ b/src/Helpers/AuditResolver.php @@ -7,11 +7,7 @@ class AuditResolver { - /** - * @param Model|null $model - * @return int|null - */ - public static function findUserId($model): ?int + public static function findUserId(Model|null $model): ?int { if (empty($model)) { return null; diff --git a/src/Listeners/LogExplicitLogout.php b/src/Listeners/LogExplicitLogout.php index 5fe3996..61335a1 100644 --- a/src/Listeners/LogExplicitLogout.php +++ b/src/Listeners/LogExplicitLogout.php @@ -8,10 +8,8 @@ class LogExplicitLogout { - public function handle(Logout $event) + public function handle(Logout $event): void { resolve(Logger::class)->logExplicitLogout(); - - return true; } } diff --git a/src/Listeners/LogFailedLogin.php b/src/Listeners/LogFailedLogin.php index 76da2df..77b151c 100644 --- a/src/Listeners/LogFailedLogin.php +++ b/src/Listeners/LogFailedLogin.php @@ -8,7 +8,7 @@ class LogFailedLogin { - public function handle(Failed $event) + public function handle(Failed $event): void { resolve(Logger::class)->logFailedLogin(); } diff --git a/src/Listeners/LogLockedLogins.php b/src/Listeners/LogLockedLogins.php index 7345558..59d555b 100644 --- a/src/Listeners/LogLockedLogins.php +++ b/src/Listeners/LogLockedLogins.php @@ -8,7 +8,7 @@ class LogLockedLogins { - public function handle(Lockout $event) + public function handle(Lockout $event): void { resolve(Logger::class)->logLockedLogin(); } diff --git a/src/Listeners/LogPasswordReset.php b/src/Listeners/LogPasswordReset.php index bf88b5a..d9144ca 100644 --- a/src/Listeners/LogPasswordReset.php +++ b/src/Listeners/LogPasswordReset.php @@ -8,7 +8,7 @@ class LogPasswordReset { - public function handle(PasswordReset $passwordReset) + public function handle(PasswordReset $passwordReset): void { resolve(Logger::class)->logPasswordReset(); } diff --git a/src/Listeners/LogSuccessfulLogin.php b/src/Listeners/LogSuccessfulLogin.php index 39cfd10..4a2e3cb 100644 --- a/src/Listeners/LogSuccessfulLogin.php +++ b/src/Listeners/LogSuccessfulLogin.php @@ -8,7 +8,7 @@ class LogSuccessfulLogin { - public function handle(Login $event) + public function handle(Login $event): void { resolve(Logger::class)->logSuccessfulLogin(); } diff --git a/src/Logger.php b/src/Logger.php index 9629040..8b97aba 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -16,12 +16,12 @@ class Logger { /** @var Model[] */ - private static $retrievedModels = []; + private static array $retrievedModels = []; + private static array $changedModels = []; - /** @var array */ - private static $changedModels = []; + public static string $userModel = 'App/User'; - public function logSuccessfulLogin() + public function logSuccessfulLogin(): AuditActivity { $type = ActivityType::SUCCESSFUL_LOGIN; @@ -34,7 +34,7 @@ public function logSuccessfulLogin() return $this->logActivity($type, $keys); } - public function logExplicitLogout() + public function logExplicitLogout(): AuditActivity { $type = ActivityType::LOGOUT; @@ -46,7 +46,7 @@ public function logExplicitLogout() return $this->logActivity($type, $keys); } - public function logFailedLogin() + public function logFailedLogin(): AuditActivity { $type = ActivityType::FAILED_LOGIN; @@ -55,7 +55,7 @@ public function logFailedLogin() return $this->logActivity($type, $keys); } - public function logLockedLogin() + public function logLockedLogin(): AuditActivity { $type = ActivityType::LOCKED_OUT; @@ -64,7 +64,7 @@ public function logLockedLogin() return $this->logActivity($type, $keys); } - public function logPasswordReset() + public function logPasswordReset(): AuditActivity { $type = ActivityType::PASSWORD_CHANGE; @@ -88,7 +88,7 @@ public function logChangedModel(Model $model, array $fields): void ]; } - public function logActivity(int $type, array $keys = []) + public function logActivity(int $type, array $keys = []): AuditActivity { $path = Request::path(); $verb = $this->getHttpVerb(Request::method()); @@ -190,19 +190,13 @@ private function getNumericMorphMap(Model $model): int private function getHttpVerb(string $verb): int { - switch (strtolower($verb)) { - case 'get': - return HttpVerb::GET; - case 'post': - return HttpVerb::POST; - case 'patch': - return HttpVerb::PATCH; - case 'put': - return HttpVerb::PUT; - case 'delete': - return HttpVerb::DELETE; - default: - return HttpVerb::UNKNOWN; - } + return match (strtolower($verb)) { + 'get' => HttpVerb::GET, + 'post' => HttpVerb::POST, + 'patch' => HttpVerb::PATCH, + 'put' => HttpVerb::PUT, + 'delete' => HttpVerb::DELETE, + default => HttpVerb::UNKNOWN, + }; } } diff --git a/src/LoggerFacade.php b/src/LoggerFacade.php index 294123c..6d1ad41 100644 --- a/src/LoggerFacade.php +++ b/src/LoggerFacade.php @@ -7,7 +7,7 @@ class LoggerFacade extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'logger'; } diff --git a/src/LoggerServiceProvider.php b/src/LoggerServiceProvider.php index bef540c..a87d500 100644 --- a/src/LoggerServiceProvider.php +++ b/src/LoggerServiceProvider.php @@ -4,15 +4,16 @@ namespace Sourcetoad\Logger; use Illuminate\Contracts\Http\Kernel; +use Illuminate\Support\Facades\Event; use Illuminate\Support\ServiceProvider; use Sourcetoad\Logger\Commands\AuditModelResolver; use Sourcetoad\Logger\Middleware\LogOutputtedKeys; class LoggerServiceProvider extends ServiceProvider { - public static $morphs = []; + public static array $morphs = []; - protected $listeners = [ + protected array $listeners = [ \Illuminate\Auth\Events\Login::class => [ \Sourcetoad\Logger\Listeners\LogSuccessfulLogin::class, ], @@ -30,7 +31,7 @@ class LoggerServiceProvider extends ServiceProvider ], ]; - public function boot() + public function boot(): void { if ($this->app->runningInConsole()) { $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); @@ -44,7 +45,7 @@ public function boot() ], 'logger'); } - public function register() + public function register(): void { $this->app->singleton(Logger::class, function () { return new Logger(); @@ -57,21 +58,21 @@ public function register() $this->registerMiddleware(); } - private function registerMiddleware() + private function registerMiddleware(): void { app(Kernel::class)->pushMiddleware(LogOutputtedKeys::class); } - private function registerMorphMaps() + private function registerMorphMaps(): void { self::$morphs = config('logger.morphs', []); } - private function registerEventListeners() + private function registerEventListeners(): void { foreach ($this->listeners as $key => $listeners) { foreach ($listeners as $listener) { - \Event::listen($key, $listener); + Event::listen($key, $listener); } } } diff --git a/src/Middleware/LogOutputtedKeys.php b/src/Middleware/LogOutputtedKeys.php index d86cd64..d9790c9 100644 --- a/src/Middleware/LogOutputtedKeys.php +++ b/src/Middleware/LogOutputtedKeys.php @@ -9,28 +9,18 @@ use Illuminate\Http\Response; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Log; use Sourcetoad\Logger\Enums\ActivityType; use Sourcetoad\Logger\Logger; class LogOutputtedKeys { - /** - * Handle an incoming request. - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @return mixed - */ - public function handle($request, Closure $next) + public function handle(Request $request, Closure $next): mixed { return $next($request); } - /** - * @param Request $request - * @param $response - */ - public function terminate(Request $request, $response) + public function terminate(Request $request, $response): void { $leadingStatusCodeNumber = substr((string) $response->getStatusCode(), 0, 1); @@ -48,7 +38,7 @@ public function terminate(Request $request, $response) $data = []; } else { $data = []; - \Log::warning('Could not decode class to extract data keys: ' . get_class($response)); + Log::warning('Could not decode class to extract data keys: ' . get_class($response)); } if ($request->method() === 'GET') { diff --git a/src/Models/AuditActivity.php b/src/Models/AuditActivity.php index cf1f744..91a176a 100644 --- a/src/Models/AuditActivity.php +++ b/src/Models/AuditActivity.php @@ -5,8 +5,11 @@ use App\User; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphTo; use Sourcetoad\Logger\Enums\ActivityType; use Sourcetoad\Logger\Enums\HttpVerb; +use Sourcetoad\Logger\Logger; use Sourcetoad\Logger\Traits\Immutable; /** @@ -43,20 +46,20 @@ class AuditActivity extends BaseModel 'ip_address' ]; - protected $dates = [ - 'created_at' + protected $casts = [ + 'created_at' => 'datetime' ]; //-------------------------------------------------------------------------------------------------------------- // Mutators //-------------------------------------------------------------------------------------------------------------- - protected function setIpAddressAttribute($value) + protected function setIpAddressAttribute(string|null $value): void { - $this->attributes['ip_address'] = inet_pton($value); + $this->attributes['ip_address'] = inet_pton((string)$value); } - protected function getIpAddressAttribute($value) + protected function getIpAddressAttribute($value): string { return strtoupper(inet_ntop($value)); } @@ -68,75 +71,49 @@ public function setUpdatedAtAttribute($value) public function getHumanVerbAttribute(): string { - switch ($this->verb) { - case HttpVerb::GET: - return trans('logger::enums.verb_get'); - - case HttpVerb::POST: - return trans('logger::enums.verb_post'); - - case HttpVerb::PATCH: - case HttpVerb::PUT: - return trans('logger::enums.verb_patch'); - - case HttpVerb::DELETE: - return trans('logger::enums.verb_delete'); - - case HttpVerb::UNKNOWN: - default: - return trans('logger::enums.verb_unknown'); - } + return match ($this->verb) { + HttpVerb::GET => trans('logger::enums.verb_get'), + HttpVerb::POST => trans('logger::enums.verb_post'), + HttpVerb::PATCH, HttpVerb::PUT => trans('logger::enums.verb_patch'), + HttpVerb::DELETE => trans('logger::enums.verb_delete'), + default => trans('logger::enums.verb_unknown'), + }; } public function getHumanActivityAttribute(): string { - switch ($this->type) { - case ActivityType::FAILED_LOGIN: - return trans('logger::enums.activity_type_failed_login'); - - case ActivityType::LOGOUT: - return trans('logger::enums.activity_type_logout'); - - case ActivityType::SUCCESSFUL_LOGIN: - return trans('logger::enums.activity_type_logged_in'); - - case ActivityType::LOCKED_OUT: - return trans('logger::enums.activity_type_locked_out'); - - case ActivityType::PASSWORD_CHANGE: - return trans('logger::enums.activity_type_password_change'); - - case ActivityType::GET_DATA: - return trans('logger::enums.activity_type_get_data'); - - case ActivityType::MODIFY_DATA: - return trans('logger::enums.activity_type_modify_data'); - - default: - throw new \Exception('Unknown enum type: ' . $this->type); - } + return match ($this->type) { + ActivityType::FAILED_LOGIN => trans('logger::enums.activity_type_failed_login'), + ActivityType::LOGOUT => trans('logger::enums.activity_type_logout'), + ActivityType::SUCCESSFUL_LOGIN => trans('logger::enums.activity_type_logged_in'), + ActivityType::LOCKED_OUT => trans('logger::enums.activity_type_locked_out'), + ActivityType::PASSWORD_CHANGE => trans('logger::enums.activity_type_password_change'), + ActivityType::GET_DATA => trans('logger::enums.activity_type_get_data'), + ActivityType::MODIFY_DATA => trans('logger::enums.activity_type_modify_data'), + default => throw new \Exception('Unknown enum type: ' . $this->type), + }; } //-------------------------------------------------------------------------------------------------------------- // Relations //-------------------------------------------------------------------------------------------------------------- - public function route() + public function route(): BelongsTo { return $this->belongsTo(AuditRoute::class); } - public function key() + public function key(): BelongsTo { return $this->belongsTo(AuditKey::class); } - public function user() + public function user(): BelongsTo { - return $this->belongsTo(User::class); + return $this->belongsTo(Logger::$userModel); } - public function entity() + public function entity(): MorphTo { return $this->morphTo(); } diff --git a/src/Models/AuditChange.php b/src/Models/AuditChange.php index f3a56ee..9000445 100644 --- a/src/Models/AuditChange.php +++ b/src/Models/AuditChange.php @@ -5,6 +5,9 @@ use App\User; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphTo; +use Sourcetoad\Logger\Logger; use Sourcetoad\Logger\Traits\Immutable; /** @@ -47,17 +50,17 @@ class AuditChange extends BaseModel // Relations //-------------------------------------------------------------------------------------------------------------- - public function user() + public function user(): BelongsTo { - return $this->belongsTo(User::class); + return $this->belongsTo(Logger::$userModel); } - public function key() + public function key(): BelongsTo { return $this->belongsTo(AuditKey::class); } - public function entity() + public function entity(): MorphTo { return $this->morphTo(); } diff --git a/src/Models/AuditKey.php b/src/Models/AuditKey.php index b0c0c13..cc852ec 100644 --- a/src/Models/AuditKey.php +++ b/src/Models/AuditKey.php @@ -29,7 +29,7 @@ class AuditKey extends BaseModel // Mutators //-------------------------------------------------------------------------------------------------------------- - protected function setRouteAttribute($value) + protected function setRouteAttribute($value): void { $value = Arr::wrap($value); $flattenedKeys = DataArrayParser::dedupe($value); diff --git a/src/Models/AuditModel.php b/src/Models/AuditModel.php index 5fa4601..2ad6c7d 100644 --- a/src/Models/AuditModel.php +++ b/src/Models/AuditModel.php @@ -5,6 +5,9 @@ use App\User; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphTo; +use Sourcetoad\Logger\Logger; use Sourcetoad\Logger\Traits\Immutable; /** @@ -56,12 +59,12 @@ public static function createOrFind(AuditActivity $activity, int $modelType, int // Relations //-------------------------------------------------------------------------------------------------------------- - public function user() + public function user(): BelongsTo { - return $this->belongsTo(User::class); + return $this->belongsTo(Logger::$userModel); } - public function entity() + public function entity(): MorphTo { return $this->morphTo(); } diff --git a/src/Models/AuditRoute.php b/src/Models/AuditRoute.php index 62243c9..15b60e5 100644 --- a/src/Models/AuditRoute.php +++ b/src/Models/AuditRoute.php @@ -27,7 +27,7 @@ class AuditRoute extends BaseModel // Mutators //-------------------------------------------------------------------------------------------------------------- - protected function setRouteAttribute($value) + protected function setRouteAttribute($value): void { $this->attributes['route'] = strtolower(trim($value)); $this->attributes['route_hash'] = md5($this->attributes['route']); diff --git a/src/Traits/HasRelationships.php b/src/Traits/HasRelationships.php index 2bd9e10..b79b743 100644 --- a/src/Traits/HasRelationships.php +++ b/src/Traits/HasRelationships.php @@ -8,13 +8,7 @@ trait HasRelationships { - /** - * Retrieve the actual class name for a given morph class. - * - * @param string $class - * @return string - */ - public static function getActualClassNameForMorph($class) + public static function getActualClassNameForMorph($class): string { return Arr::get(LoggerServiceProvider::$morphs ?: [], $class, $class); } diff --git a/src/Traits/Immutable.php b/src/Traits/Immutable.php index e4da45b..2fdd094 100644 --- a/src/Traits/Immutable.php +++ b/src/Traits/Immutable.php @@ -9,7 +9,7 @@ trait Immutable { - public static function bootImmutable() + public static function bootImmutable(): void { static::updating(function (Model $model) { diff --git a/src/Traits/Trackable.php b/src/Traits/Trackable.php index 304680e..055ea0e 100644 --- a/src/Traits/Trackable.php +++ b/src/Traits/Trackable.php @@ -8,7 +8,7 @@ trait Trackable { - public static function bootTrackable() + public static function bootTrackable(): void { static::retrieved(function (Model $model) { resolve(Logger::class)->logRetrievedModel($model); @@ -27,7 +27,7 @@ public static function bootTrackable() }); } - public function trackableUserResolver() + public function trackableUserResolver(): ?int { throw new \BadMethodCallException('This method (trackableUserResolver) needs ' . 'to be implemented in the implemented class: ' . static::class); From 2f99ade9fa47ce81bb1a60d8bef94dee6f21d930 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 15 Jan 2023 09:13:16 -0500 Subject: [PATCH 3/3] build: stable/sort packages in composer.json --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fe8a155..a4c1b63 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,10 @@ "email": "connor@sourcetoad.com" } ], - "minimum-stability": "dev", + "config": { + "sort-packages": true + }, + "minimum-stability": "stable", "prefer-stable": true, "require": { "ext-json": "*",