14 Commits
0.6.1 ... 0.6.2

Author SHA1 Message Date
937a0206a5 Added existing account check to logs 2020-09-08 01:38:56 +01:00
3598a32ecf Added existing account check to logs 2020-09-08 01:37:33 +01:00
ac8b303e2c Update to logauthfailure 2020-09-08 01:34:47 +01:00
e93abd2ab7 Added logging for successful authentication attempts 2020-09-08 01:31:09 +01:00
20ab381076 Added logging for failed authentication attempts 2020-09-08 01:26:27 +01:00
e566e40404 Update target user in logs 2020-09-08 00:07:50 +01:00
b0a935b8b3 Add acceptable "permanent" ban time 2020-09-08 00:06:27 +01:00
0dfb68dba2 Add acceptable "permanent" ban time 2020-09-08 00:05:37 +01:00
24303052ad Ban validation update 2020-09-07 23:57:50 +01:00
178bc31a6e Ban datetime format 2020-09-07 23:44:14 +01:00
98e557a840 Update ban dates 2020-09-07 23:42:09 +01:00
95bf7c239e Update ban time logic 2020-09-07 23:38:25 +01:00
4d2595dd39 Update ban logic 2020-09-07 23:33:35 +01:00
4e81a41210 Updated installation process 2020-09-07 23:22:25 +01:00
9 changed files with 112 additions and 15 deletions

View File

@@ -21,9 +21,6 @@ RECAPTCHA_PRIVATE_KEY=
RECAPTCHA_VERIFY_URL="https://www.google.com/recaptcha/api/siteverify" RECAPTCHA_VERIFY_URL="https://www.google.com/recaptcha/api/siteverify"
# WARNING: Your contact form will be useless if you change this value. Only change this URL if Google updates it. # WARNING: Your contact form will be useless if you change this value. Only change this URL if Google updates it.
IPGEO_API_KEY=""
IPGEO_API_URL=""
MOJANG_STATUS_URL="https://status.mojang.com/check" MOJANG_STATUS_URL="https://status.mojang.com/check"
MOJANG_API_URL="https://api.mojang.com" MOJANG_API_URL="https://api.mojang.com"
@@ -32,7 +29,7 @@ IPGEO_API_URL="https://api.ipgeolocation.io/ipgeo"
ARCANEDEV_LOGVIEWER_MIDDLEWARE=web,auth,can:admin.maintenance.logs.view ARCANEDEV_LOGVIEWER_MIDDLEWARE=web,auth,can:admin.maintenance.logs.view
RELEASE=staffmanagement@0.2.0 RELEASE=staffmanagement@0.6.1
SLACK_INTEGRATION_WEBHOOK= SLACK_INTEGRATION_WEBHOOK=

View File

@@ -8,7 +8,7 @@ class Ban extends Model
{ {
public $fillable = [ public $fillable = [
'userID', 'userID',
'reason', 'reason',
'bannedUntil', 'bannedUntil',
@@ -16,7 +16,11 @@ class Ban extends Model
'authorUserID' 'authorUserID'
]; ];
public $dates = [
'bannedUntil'
];
public function user() public function user()
{ {
return $this->belongsTo('App\User', 'userID', 'id'); return $this->belongsTo('App\User', 'userID', 'id');

View File

@@ -99,12 +99,16 @@ class Install extends Command
$settings['MAIL_PASSWORD'] = $this->secret('SMTP Password (Input won\'t be seen)'); $settings['MAIL_PASSWORD'] = $this->secret('SMTP Password (Input won\'t be seen)');
$settings['MAIL_PORT'] = $this->ask('SMTP Server Port'); $settings['MAIL_PORT'] = $this->ask('SMTP Server Port');
$settings['MAIL_HOST'] = $this->ask('SMTP Server Hostname'); $settings['MAIL_HOST'] = $this->ask('SMTP Server Hostname');
$settings['MAIL_FROM'] = $this->ask('E-mail address to send from: ');
$this->info('== Notification Settings (5/6) (Slack) =='); $this->info('== Notification Settings (5/6) (Slack) ==');
$settings['SLACK_INTEGRATION_WEBHOOK'] = $this->ask('Integration webhook URL'); $settings['SLACK_INTEGRATION_WEBHOOK'] = $this->ask('Integration webhook URL');
$this->info('== Web Settings (6/6) =='); $this->info('== Web Settings (6/6) ==');
$settings['APP_URL'] = $this->ask('Application\'s URL'); $settings['APP_URL'] = $this->ask('Application\'s URL (ex. https://where.you.installed.theapp.com): ');
$settings['APP_LOGO'] = $this->ask('App logo (Link to an image): ');
$settings['APP_SITEHOMEPAGE'] = $this->ask('Site homepage (appears in the main header): ');
} while(!$this->confirm('Are you sure you want to save these settings? You can always go back and try again.')); } while(!$this->confirm('Are you sure you want to save these settings? You can always go back and try again.'));

View File

@@ -15,7 +15,7 @@ class BanController extends Controller
public function insert(BanUserRequest $request, User $user) public function insert(BanUserRequest $request, User $user)
{ {
$this->authorize('create', Ban::class); $this->authorize('create', [Ban::class, $user]);
if (is_null($user->bans)) if (is_null($user->bans))
{ {
@@ -50,13 +50,13 @@ class BanController extends Controller
else else
{ {
// Essentially permanent // Essentially permanent
$expiryDate->addYears(100); $expiryDate->addYears(5);
} }
$ban = Ban::create([ $ban = Ban::create([
'userID' => $user->id, 'userID' => $user->id,
'reason' => $reason, 'reason' => $reason,
'bannedUntil' => $expiryDate->toDateTimeString() ?? null, 'bannedUntil' => $expiryDate->format('Y-m-d H:i:s'),
'userAgent' => "Unknown", 'userAgent' => "Unknown",
'authorUserID' => Auth::user()->id 'authorUserID' => Auth::user()->id
]); ]);

View File

@@ -27,7 +27,7 @@ class BanUserRequest extends FormRequest
{ {
return [ return [
'reason' => 'required|string', 'reason' => 'required|string',
'durationOperand' => 'nullable|integer', 'durationOperand' => 'nullable|string',
'durationOperator' => 'nullable|string' 'durationOperator' => 'nullable|string'
]; ];
} }

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
class LogAuthenticationFailure
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
$targetAccountID = 0;
$originalIP = "0.0.0.0";
if (isset($event->user->id))
{
$targetAccountID = $event->user->id;
}
Log::alert('SECURITY (login): Detected failed authentication attempt!', [
'targetAccountID' => $targetAccountID,
'existingAccount' => ($targetAccountID == 0) ? false : true,
'sourceIP' => request()->ip(),
'matchesAccountLastIP' => request()->ip() == $originalIP,
'sourceUserAgent' => request()->userAgent(),
]);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
class LogAuthenticationSuccess
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
Log::info('SECURITY (postauth-pre2fa): Detected successful login attempt', [
'accountID' => $event->user->id,
'sourceIP' => request()->ip(),
'matchesAccountLastIP' => request()->ip() == $event->user->originalIP,
'sourceUserAgent' => request()->userAgent(),
]);
}
}

View File

@@ -38,18 +38,19 @@ class BanPolicy
/** /**
* Determine whether the user can create models. * Determine whether the user can create models.
* *
* @param \App\User $user * @param \App\User $user
* @param User $targetUser
* @return mixed * @return mixed
*/ */
public function create(User $user) public function create(User $user, User $targetUser)
{ {
Log::debug("Authorization check started", [ Log::debug("Authorization check started", [
'requiredRoles' => 'admin', 'requiredRoles' => 'admin',
'currentRoles' => $user->roles(),
'hasRequiredRole' => $user->hasRole('admin'), 'hasRequiredRole' => $user->hasRole('admin'),
'targetUser' => $targetUser->username,
'isCurrentUser' => Auth::user()->is($user) 'isCurrentUser' => Auth::user()->is($user)
]); ]);
return $user->hasRole('admin') && Auth::user()->isNot($user); return $user->hasRole('admin') && $user->isNot($targetUser);
} }
/** /**

View File

@@ -2,7 +2,11 @@
namespace App\Providers; namespace App\Providers;
use App\Listeners\LogAuthenticationFailure;
use App\Listeners\LogAuthenticationSuccess;
use App\Listeners\OnUserRegistration; use App\Listeners\OnUserRegistration;
use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -20,6 +24,12 @@ class EventServiceProvider extends ServiceProvider
SendEmailVerificationNotification::class, SendEmailVerificationNotification::class,
OnUserRegistration::class OnUserRegistration::class
], ],
Failed::class => [
LogAuthenticationFailure::class
],
Login::class => [
LogAuthenticationSuccess::class
],
'App\Events\ApplicationApprovedEvent' => [ 'App\Events\ApplicationApprovedEvent' => [
'App\Listeners\PromoteUser' 'App\Listeners\PromoteUser'
], ],