Compare commits

..

24 Commits

Author SHA1 Message Date
85c719c24d Fix bad key name 2020-12-19 01:33:59 +00:00
5df3f965ef Merged in revert-pr-6 (pull request #7)
Revert "Apply fixes from StyleCI (pull request #6)"
2020-10-21 00:31:11 +00:00
4eb115d165 Revert "Apply fixes from StyleCI (pull request #6)"
This reverts pull request #6.

> This pull request applies code style fixes from an analysis carried out by [StyleCI](https://bitbucket.styleci.io).
> 
> For more information, click [here](https://bitbucket.styleci.io/analyses/a2Jl7D).
2020-10-21 00:29:50 +00:00
0433ce7693 Merged in analysis-a2Jl7D (pull request #6)
Apply fixes from StyleCI
2020-10-21 00:24:54 +00:00
773ec570d9 Apply fixes from StyleCI 2020-10-21 00:01:41 +00:00
53c23f3698 Changed branding for the repo 2020-10-21 00:01:32 +00:00
f1db159eee
Update SECURITY.md 2020-09-08 17:44:56 +01:00
0d14a65ee5
Create SECURITY.md 2020-09-08 17:32:56 +01:00
2942157603
Update README.md 2020-09-08 06:16:27 +01:00
11f3fb90d0
Update README.md 2020-09-08 06:16:14 +01:00
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
11 changed files with 141 additions and 17 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

@ -1,6 +1,6 @@
# Raspberry Teams - The Simple Staff Application Manager v 0.5.2 [![Crowdin](https://badges.crowdin.net/raspberry-staff-manager/localized.svg)](https://crowdin.com/project/raspberry-staff-manager) # RB Recruiter v 0.6.2 [![Crowdin](https://badges.crowdin.net/raspberry-staff-manager/localized.svg)](https://crowdin.com/project/raspberry-staff-manager)
## The quick and pain-free staff application manager ## The quick and pain-free form management solution for communities
Have you ever gotten tired of managing your Minecraft server/network's applications through Discord (or anything else) and having to scroll through hundreds of new messages just to find that one applicant's username? Have you ever gotten tired of managing your Minecraft server/network's applications through Discord (or anything else) and having to scroll through hundreds of new messages just to find that one applicant's username?
@ -47,6 +47,14 @@ Tech stack:
- AdminLTE / Bootstrap 4 - AdminLTE / Bootstrap 4
- jQuery / Plain Javascript - jQuery / Plain Javascript
- vueJS (in the future) - vueJS (in the future)
# Stability
Currently, the ``master`` branch is highly unstable, since it's under active development. Expect it to break with each commit. Even though I make an effort to make sure each commit is good to go before pushing, things might still break unexpectedly, and you may find a lot of bugs (which you should report).
Every released version is currently pre-release. If you really want to run this before version ``1.0.0`` comes out, always stay on the latest version, as those will always be tested before release, ensuring less chaos.
*Note: This application is NOT production ready! It won't be until the first stable release comes out, which might take a bit longer.
# Operating System Requirements # Operating System Requirements

19
SECURITY.md Normal file
View File

@ -0,0 +1,19 @@
# Security Policy
## Supported Versions
The following versions are currently supported:
| Version | Supported |
| ------- | ------------------ |
| 0.1.x | :x: |
| 0.5.x | :x: |
| 0.6.x | :white_check_mark: |
## Reporting a Vulnerability
To securely report a vulnerability, you may send me an email directly containing the details of said vulnerability: ``me@nogueira.codes``.
You may optionally encrypt your message with my [public PGP key](http://pool.sks-keyservers.net/pks/lookup?op=get&search=0x48DF709E7405702B).
Use this free [online encryption tool](https://www.igolder.com/pgp/encryption/) if you don't know how to use PGP on your desktop.

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_ADDRESS'] = $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'
], ],