athenahr/app/Services/AccountSuspensionService.php
miguel456 b89d71b371
Revert "Revert "merge 1""
This reverts commit 0c463d1f10145bf99dd63fd7128f992ab2371ffb.
2022-10-24 01:04:22 +01:00

155 lines
4.1 KiB
PHP
Executable File

<?php declare(strict_types=1);
namespace App\Services;
use App\Ban;
use App\Notifications\AccountLocked;
use App\Notifications\AccountUnlocked;
use App\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class AccountSuspensionService
{
/**
* Suspends a user account, with given $reason.
* Permanent if no duration given.
*
* @param User $target Who to suspend.
* @param string $reason Suspension reason.
* @param int|null $duration Duration in days
* @return Ban The ban itself
*/
public function suspend(User $target, string $reason, int $duration = null): Ban {
Log::alert("An user account has just been suspended.", [
'taget_email' => $target->email,
'suspended_by' => Auth::user()->email,
'reason' => $reason
]);
if ($duration > 0) {
$expiryDate = now()->addDays($duration);
}
return Ban::create([
'userID' => $target->id,
'reason' => $reason,
'bannedUntil' => ($duration > 0) ? $expiryDate->format('Y-m-d H:i:s') : null,
'authorUserID' => Auth::user()->id,
'isPermanent' => ($duration == 0) ? true : false
]);
}
/**
* Lifts someone's suspension
*
* @param User $user The user to unsuspend
*/
public function unsuspend(User $user): void {
Log::alert("A suspension has just been lifted.", [
'target_email' => $user->email,
]);
$user->bans->delete();
}
/**
* Checks whether a user is suspended
*
* @param User $user The user to check
* @return bool Whether the mentioned user is suspended
*/
public function isSuspended(User $user): bool {
return !is_null($user->bans);
}
/**
* Sets an administrative lock on a user account.
* Used to prevent logins after a deletion process is initiated, but may be used for
* other things where a suspension is not necessary/warranted, such as a security breach event.
* These locks cannot be overridden manually be administrators.
*
* @param User $user The account to lock
* @return bool
*/
public function lockAccount(User $user): bool
{
Log::alert('User account locked!', [
'email' => $user->email
]);
$user->administratively_locked = 1;
$user->notify(new AccountLocked);
return $user->save();
}
/**
* Unlocks a user account. Reverse of lockAccount().
*
* @param User $user
* @return bool
*/
public function unlockAccount(User $user): bool
{
Log::alert('User account unlocked!', [
'email' => $user->email
]);
$user->administratively_locked = 0;
$user->notify(new AccountUnlocked);
return $user->save();
}
/**
* Checks whether an account is locked
*
* @param User $user The user to check
* @return bool Whether the mentioned account is locked
*/
public function isLocked(User $user): bool {
return $user->administratively_locked == 1;
}
/**
* Retrieves the reason for the user's suspension.
*
* @param User $user The user account to check
* @return string|bool Reason for the suspension, false if not suspended
*/
public function getSuspensionReason(User $user): string|bool {
return ($this->isSuspended($user)) ? $user->bans->reason : false;
}
public function getSuspensionDuration(User $user): string|null {
if ($this->isSuspended($user) && !is_null($user->bans->bannedUntil)) {
return $user->bans->bannedUntil->diffForHumans();
}
return null;
}
/**
* Purges old, expired suspensions from the database
*
* @return bool Whether any suspensions were lifted
*/
public function purgeExpired()
{
// Unban on the last day, not on the exact time (with Carbon::now()).
return (bool) Ban::whereDate('bannedUntil', '=', Carbon::today())->delete();
}
}