Merge pull request #62 from okorpheus/auditionadmin-61
Implement basic logging
This commit is contained in:
commit
03beecf65e
|
|
@ -4,9 +4,12 @@ namespace App\Actions\Entries;
|
||||||
|
|
||||||
use App\Exceptions\ManageEntryException;
|
use App\Exceptions\ManageEntryException;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
|
|
||||||
|
use function auth;
|
||||||
|
|
||||||
class CreateEntry
|
class CreateEntry
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
|
|
@ -46,6 +49,20 @@ class CreateEntry
|
||||||
'for_advancement' => $entry_for->contains('advancement'),
|
'for_advancement' => $entry_for->contains('advancement'),
|
||||||
]);
|
]);
|
||||||
$entry->save();
|
$entry->save();
|
||||||
|
if (auth()->user()) {
|
||||||
|
$message = 'Entered '.$entry->student->full_name().' from '.$entry->student->school->name.' in '.$entry->audition->name.'.';
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'entries' => [$entry->id],
|
||||||
|
'students' => [$entry->student_id],
|
||||||
|
'auditions' => [$entry->audition_id],
|
||||||
|
'schools' => [$entry->student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $entry;
|
return $entry;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,22 @@ namespace App\Actions\Entries;
|
||||||
|
|
||||||
use App\Exceptions\ManageEntryException;
|
use App\Exceptions\ManageEntryException;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
use function auditionSetting;
|
||||||
|
use function auth;
|
||||||
|
use function request;
|
||||||
|
|
||||||
class UpdateEntry
|
class UpdateEntry
|
||||||
{
|
{
|
||||||
protected Entry $entry;
|
protected Entry $entry;
|
||||||
|
|
||||||
|
protected string $log_message = '';
|
||||||
|
|
||||||
|
protected array $log_affected = [];
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -48,8 +56,19 @@ class UpdateEntry
|
||||||
if (array_key_exists('audition', $updateData)) {
|
if (array_key_exists('audition', $updateData)) {
|
||||||
$this->updateAudition($updateData['audition']);
|
$this->updateAudition($updateData['audition']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entry->save();
|
$this->entry->save();
|
||||||
|
if (auth()->user()) {
|
||||||
|
$this->log_affected['auditions'][] = $this->entry->audition_id;
|
||||||
|
$this->log_affected['entries'][] = $this->entry->id;
|
||||||
|
$this->log_affected['students'][] = $this->entry->student_id;
|
||||||
|
$this->log_affected['schools'][] = $this->entry->student->school_id;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $this->log_message,
|
||||||
|
'affected' => $this->log_affected,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -87,16 +106,24 @@ class UpdateEntry
|
||||||
throw new ManageEntryException('Cannot change the audition for an entry with scores');
|
throw new ManageEntryException('Cannot change the audition for an entry with scores');
|
||||||
}
|
}
|
||||||
if ($audition->id !== $this->entry->audition_id &&
|
if ($audition->id !== $this->entry->audition_id &&
|
||||||
Entry::where('student_id', $this->entry->student_id)
|
Entry::where('student_id', $this->entry->student_id)
|
||||||
->where('audition_id', $audition->id)->exists()) {
|
->where('audition_id', $audition->id)->exists()) {
|
||||||
throw new ManageEntryException('That student is already entered in that audition');
|
throw new ManageEntryException('That student is already entered in that audition');
|
||||||
}
|
}
|
||||||
|
// Escape if we're not actually making a change
|
||||||
|
if ($this->entry->audition_id == $audition->id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// OK we're allowed to change the audition
|
// OK we're allowed to change the audition
|
||||||
|
$oldAudition = $this->entry->audition;
|
||||||
$this->entry->audition_id = $audition->id;
|
$this->entry->audition_id = $audition->id;
|
||||||
|
$this->log_message .= 'Changed entry '.$this->entry->id.' from '.$oldAudition->name.' to '.$audition->name.'<br>';
|
||||||
|
$this->log_affected['auditions'][] = $oldAudition->id;
|
||||||
// Deal with our draw number
|
// Deal with our draw number
|
||||||
if ($audition->hasFlag('drawn')) {
|
if ($audition->hasFlag('drawn')) {
|
||||||
$draw_number = $audition->entries()->max('draw_number');
|
$draw_number = $audition->entries()->max('draw_number');
|
||||||
$this->entry->draw_number = $draw_number + 1;
|
$this->entry->draw_number = $draw_number + 1;
|
||||||
|
$this->log_message .= 'Entry '.$this->entry->id.' draw number set to '.$this->entry->draw_number.'<br>';
|
||||||
} else {
|
} else {
|
||||||
$this->entry->draw_number = null;
|
$this->entry->draw_number = null;
|
||||||
}
|
}
|
||||||
|
|
@ -115,11 +142,13 @@ class UpdateEntry
|
||||||
throw new ManageEntryException('Cannot add seating to an entry in an audition where seats are published');
|
throw new ManageEntryException('Cannot add seating to an entry in an audition where seats are published');
|
||||||
}
|
}
|
||||||
$this->entry->for_seating = 1;
|
$this->entry->for_seating = 1;
|
||||||
|
$this->log_message .= 'Entry '.$this->entry->id.' is entered for seating '.'<br>';
|
||||||
} else {
|
} else {
|
||||||
if ($this->entry->audition->hasFlag('seats_published')) {
|
if ($this->entry->audition->hasFlag('seats_published')) {
|
||||||
throw new ManageEntryException('Cannot remove seating from an entry in an audition where seats are published');
|
throw new ManageEntryException('Cannot remove seating from an entry in an audition where seats are published');
|
||||||
}
|
}
|
||||||
$this->entry->for_seating = 0;
|
$this->entry->for_seating = 0;
|
||||||
|
$this->log_message .= 'Entry '.$this->entry->id.' is NOT entered for seating '.'<br>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,11 +165,13 @@ class UpdateEntry
|
||||||
throw new ManageEntryException('Cannot add advancement to an entry in an audition where advancement is published');
|
throw new ManageEntryException('Cannot add advancement to an entry in an audition where advancement is published');
|
||||||
}
|
}
|
||||||
$this->entry->for_advancement = 1;
|
$this->entry->for_advancement = 1;
|
||||||
|
$this->log_message .= 'Entry '.$this->entry->id.' is entered for '.auditionSetting('advanceTo').'<br>';
|
||||||
} else {
|
} else {
|
||||||
if ($this->entry->audition->hasFlag('advancement_published')) {
|
if ($this->entry->audition->hasFlag('advancement_published')) {
|
||||||
throw new ManageEntryException('Cannot remove advancement from an entry in an audition where advancement is published');
|
throw new ManageEntryException('Cannot remove advancement from an entry in an audition where advancement is published');
|
||||||
}
|
}
|
||||||
$this->entry->for_advancement = 0;
|
$this->entry->for_advancement = 0;
|
||||||
|
$this->log_message .= 'Entry '.$this->entry->id.' is NOT entered for '.auditionSetting('advanceTo').'<br>';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,14 @@
|
||||||
|
|
||||||
namespace App\Actions\Fortify;
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
use A6digital\Image\DefaultProfileImage;
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Rules\ValidRegistrationCode;
|
use App\Rules\ValidRegistrationCode;
|
||||||
use App\Settings;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Laravel\Fortify\Contracts\CreatesNewUsers;
|
use Laravel\Fortify\Contracts\CreatesNewUsers;
|
||||||
|
|
||||||
use function mb_substr;
|
use function mb_substr;
|
||||||
|
|
||||||
class CreateNewUser implements CreatesNewUsers
|
class CreateNewUser implements CreatesNewUsers
|
||||||
|
|
@ -41,9 +40,10 @@ class CreateNewUser implements CreatesNewUsers
|
||||||
'password' => $this->passwordRules(),
|
'password' => $this->passwordRules(),
|
||||||
])->validate();
|
])->validate();
|
||||||
|
|
||||||
$profileImageURL = 'https://ui-avatars.com/api/?name=' . mb_substr($input['first_name'],0,1) . '+' . mb_substr($input['last_name'],0,1);
|
$profileImageURL = 'https://ui-avatars.com/api/?name='.mb_substr($input['first_name'], 0,
|
||||||
|
1).'+'.mb_substr($input['last_name'], 0, 1);
|
||||||
|
|
||||||
return User::create([
|
$user = User::create([
|
||||||
'first_name' => $input['first_name'],
|
'first_name' => $input['first_name'],
|
||||||
'last_name' => $input['last_name'],
|
'last_name' => $input['last_name'],
|
||||||
'judging_preference' => $input['judging_preference'],
|
'judging_preference' => $input['judging_preference'],
|
||||||
|
|
@ -52,5 +52,18 @@ class CreateNewUser implements CreatesNewUsers
|
||||||
'profile_image_url' => $profileImageURL,
|
'profile_image_url' => $profileImageURL,
|
||||||
'password' => Hash::make($input['password']),
|
'password' => Hash::make($input['password']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$message = 'New User Registered - '.$input['email']
|
||||||
|
.'<br>Name: '.$input['first_name'].' '.$input['last_name']
|
||||||
|
.'<br>Judging Pref: '.$input['judging_preference']
|
||||||
|
.'<br>Cell Phone: '.$input['cell_phone'];
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => $input['email'],
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['users' => $user->id],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Actions\Fortify;
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
@ -25,5 +26,11 @@ class ResetUserPassword implements ResetsUserPasswords
|
||||||
$user->forceFill([
|
$user->forceFill([
|
||||||
'password' => Hash::make($input['password']),
|
'password' => Hash::make($input['password']),
|
||||||
])->save();
|
])->save();
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => 'Reset Password',
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
|
|
||||||
namespace App\Actions\Fortify;
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
|
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
|
||||||
|
|
||||||
|
use function auth;
|
||||||
|
|
||||||
class UpdateUserPassword implements UpdatesUserPasswords
|
class UpdateUserPassword implements UpdatesUserPasswords
|
||||||
{
|
{
|
||||||
use PasswordValidationRules;
|
use PasswordValidationRules;
|
||||||
|
|
@ -28,5 +31,11 @@ class UpdateUserPassword implements UpdatesUserPasswords
|
||||||
$user->forceFill([
|
$user->forceFill([
|
||||||
'password' => Hash::make($input['password']),
|
'password' => Hash::make($input['password']),
|
||||||
])->save();
|
])->save();
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => 'Changed Password',
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Actions\Fortify;
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
@ -44,6 +45,16 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||||
'email' => $input['email'],
|
'email' => $input['email'],
|
||||||
])->save();
|
])->save();
|
||||||
}
|
}
|
||||||
|
$message = 'Updated user #'.$user->id.' - '.$user->email
|
||||||
|
.'<br>Name: '.$user->full_name()
|
||||||
|
.'<br>Judging Pref: '.$user->judging_preference
|
||||||
|
.'<br>Cell Phone: '.$user->cell_phone;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,6 +64,7 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||||
*/
|
*/
|
||||||
protected function updateVerifiedUser(User $user, array $input): void
|
protected function updateVerifiedUser(User $user, array $input): void
|
||||||
{
|
{
|
||||||
|
$oldEmail = $user->email;
|
||||||
$user->forceFill([
|
$user->forceFill([
|
||||||
'first_name' => $input['first_name'],
|
'first_name' => $input['first_name'],
|
||||||
'last_name' => $input['last_name'],
|
'last_name' => $input['last_name'],
|
||||||
|
|
@ -61,6 +73,18 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||||
'email' => $input['email'],
|
'email' => $input['email'],
|
||||||
'email_verified_at' => null,
|
'email_verified_at' => null,
|
||||||
])->save();
|
])->save();
|
||||||
|
$user->refresh();
|
||||||
|
$message = 'Updated user #'.$user->id.' - '.$oldEmail
|
||||||
|
.'<br>Name: '.$user->full_name()
|
||||||
|
.'<br>Email: '.$user->email
|
||||||
|
.'<br>Judging Pref: '.$user->judging_preference
|
||||||
|
.'<br>Cell Phone: '.$user->cell_phone;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
|
||||||
$user->sendEmailVerificationNotification();
|
$user->sendEmailVerificationNotification();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ use App\Actions\Tabulation\CalculateScoreSheetTotal;
|
||||||
use App\Exceptions\ManageEntryException;
|
use App\Exceptions\ManageEntryException;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use App\Models\School;
|
use App\Models\School;
|
||||||
use App\Models\Seat;
|
use App\Models\Seat;
|
||||||
|
|
@ -202,9 +203,24 @@ class EntryController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($entry->scoreSheets()->count() > 0) {
|
if ($entry->scoreSheets()->count() > 0) {
|
||||||
return redirect()->route('admin.entries.index')->with('error', 'Cannot delete an entry that has been scored');
|
return redirect()->route('admin.entries.index')->with('error',
|
||||||
|
'Cannot delete an entry that has been scored');
|
||||||
|
}
|
||||||
|
if (auth()->user()) {
|
||||||
|
$message = 'Deleted entry '.$entry->id;
|
||||||
|
$affected = [
|
||||||
|
'entries' => [$entry->id],
|
||||||
|
'auditions' => [$entry->audition_id],
|
||||||
|
'schools' => [$entry->student->school_id],
|
||||||
|
'students' => [$entry->student_id],
|
||||||
|
];
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => $affected,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entry->delete();
|
$entry->delete();
|
||||||
|
|
||||||
return redirect()->route('admin.entries.index')->with('success', 'Entry Deleted');
|
return redirect()->route('admin.entries.index')->with('success', 'Entry Deleted');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class LogViewer extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle the incoming request.
|
||||||
|
*/
|
||||||
|
public function __invoke(Request $request)
|
||||||
|
{
|
||||||
|
$log_entries = AuditLogEntry::orderBy('created_at', 'desc')->paginate(20);
|
||||||
|
|
||||||
|
return view('admin.logview', compact('log_entries'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\School;
|
use App\Models\School;
|
||||||
use App\Models\SchoolEmailDomain;
|
use App\Models\SchoolEmailDomain;
|
||||||
use App\Services\Invoice\InvoiceDataService;
|
use App\Services\Invoice\InvoiceDataService;
|
||||||
|
|
@ -69,6 +70,13 @@ class SchoolController extends Controller
|
||||||
'state' => request('state'),
|
'state' => request('state'),
|
||||||
'zip' => request('zip'),
|
'zip' => request('zip'),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Modified school #'.$school->id.' - '.$school->name.' with address <br>'.$school->address.'<br>'.$school->city.', '.$school->state.' '.$school->zip;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['schools' => [$school->id]],
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect()->route('admin.schools.show', ['school' => $school->id])->with('success',
|
return redirect()->route('admin.schools.show', ['school' => $school->id])->with('success',
|
||||||
'School '.$school->name.' updated');
|
'School '.$school->name.' updated');
|
||||||
|
|
@ -100,6 +108,13 @@ class SchoolController extends Controller
|
||||||
'state' => request('state'),
|
'state' => request('state'),
|
||||||
'zip' => request('zip'),
|
'zip' => request('zip'),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Created school #'.$school->id.' - '.$school->name.' with address <br>'.$school->address.'<br>'.$school->city.', '.$school->state.' '.$school->zip;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['schools' => [$school->id]],
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect('/admin/schools')->with('success', 'School '.$school->name.' created');
|
return redirect('/admin/schools')->with('success', 'School '.$school->name.' created');
|
||||||
}
|
}
|
||||||
|
|
@ -110,6 +125,13 @@ class SchoolController extends Controller
|
||||||
return to_route('admin.schools.index')->with('error', 'You cannot delete a school with students.');
|
return to_route('admin.schools.index')->with('error', 'You cannot delete a school with students.');
|
||||||
}
|
}
|
||||||
$name = $school->name;
|
$name = $school->name;
|
||||||
|
$message = 'Delete school #'.$school->id.' - '.$school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['schools' => [$school->id]],
|
||||||
|
]);
|
||||||
$school->delete();
|
$school->delete();
|
||||||
|
|
||||||
return to_route('admin.schools.index')->with('success', 'School '.$school->name.' deleted');
|
return to_route('admin.schools.index')->with('success', 'School '.$school->name.' deleted');
|
||||||
|
|
@ -128,6 +150,12 @@ class SchoolController extends Controller
|
||||||
'school_id' => $school->id,
|
'school_id' => $school->id,
|
||||||
'domain' => request('domain'),
|
'domain' => request('domain'),
|
||||||
]);
|
]);
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => 'Added '.request('domain').' as an email domain for school #'.$school->id.' - '.$school->name,
|
||||||
|
'affected' => ['schools' => [$school->id]],
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect()->route('admin.schools.show', $school)->with('success', 'Domain Added');
|
return redirect()->route('admin.schools.show', $school)->with('success', 'Domain Added');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,14 @@ namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\School;
|
use App\Models\School;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
use function abort;
|
use function abort;
|
||||||
|
use function auth;
|
||||||
|
use function request;
|
||||||
use function to_route;
|
use function to_route;
|
||||||
use function view;
|
use function view;
|
||||||
|
|
||||||
|
|
@ -55,14 +58,24 @@ class StudentController extends Controller
|
||||||
return redirect('/admin/students/create')->with('error', 'This student already exists.');
|
return redirect('/admin/students/create')->with('error', 'This student already exists.');
|
||||||
}
|
}
|
||||||
|
|
||||||
Student::create([
|
$student = Student::create([
|
||||||
'first_name' => request('first_name'),
|
'first_name' => request('first_name'),
|
||||||
'last_name' => request('last_name'),
|
'last_name' => request('last_name'),
|
||||||
'grade' => request('grade'),
|
'grade' => request('grade'),
|
||||||
'school_id' => request('school_id'),
|
'school_id' => request('school_id'),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Created student #'.$student->id.' - '.$student->full_name().'<br>Grade: '.$student->grade.'<br>School: '.$student->school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'students' => [$student->id],
|
||||||
|
'schools' => [$student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect('/admin/students');
|
return redirect('/admin/students')->with('success', 'Created student successfully');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(Student $student)
|
public function edit(Student $student)
|
||||||
|
|
@ -103,7 +116,8 @@ class StudentController extends Controller
|
||||||
->where('school_id', request('school_id'))
|
->where('school_id', request('school_id'))
|
||||||
->where('id', '!=', $student->id)
|
->where('id', '!=', $student->id)
|
||||||
->exists()) {
|
->exists()) {
|
||||||
return redirect('/admin/students/'.$student->id.'/edit')->with('error', 'A student with that name already exists at that school');
|
return redirect('/admin/students/'.$student->id.'/edit')->with('error',
|
||||||
|
'A student with that name already exists at that school');
|
||||||
}
|
}
|
||||||
|
|
||||||
$student->update([
|
$student->update([
|
||||||
|
|
@ -113,7 +127,18 @@ class StudentController extends Controller
|
||||||
'school_id' => request('school_id'),
|
'school_id' => request('school_id'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect('/admin/students');
|
$message = 'Updated student #'.$student->id.'<br>Name: '.$student->full_name().'<br>Grade: '.$student->grade.'<br>School: '.$student->school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'students' => [$student->id],
|
||||||
|
'schools' => [$student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect('/admin/students')->with('success', 'Student updated');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,6 +148,16 @@ class StudentController extends Controller
|
||||||
return to_route('admin.students.index')->with('error', 'You cannot delete a student with entries.');
|
return to_route('admin.students.index')->with('error', 'You cannot delete a student with entries.');
|
||||||
}
|
}
|
||||||
$name = $student->full_name();
|
$name = $student->full_name();
|
||||||
|
$message = 'Deleted student #'.$student->id.'<br>Name: '.$student->full_name().'<br>Grade: '.$student->grade.'<br>School: '.$student->school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'students' => [$student->id],
|
||||||
|
'schools' => [$student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
$student->delete();
|
$student->delete();
|
||||||
|
|
||||||
return to_route('admin.students.index')->with('success', 'Student '.$name.' deleted successfully.');
|
return to_route('admin.students.index')->with('success', 'Student '.$name.' deleted successfully.');
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Mail\NewUserPassword;
|
use App\Mail\NewUserPassword;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\School;
|
use App\Models\School;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -49,7 +50,9 @@ class UserController extends Controller
|
||||||
if (! Auth::user()->is_admin) {
|
if (! Auth::user()->is_admin) {
|
||||||
abort(403);
|
abort(403);
|
||||||
}
|
}
|
||||||
|
$oldEmail = $user->email;
|
||||||
|
$wasAdmin = $user->is_admin;
|
||||||
|
$wasTab = $user->is_tab;
|
||||||
$validData = $request->validate([
|
$validData = $request->validate([
|
||||||
'first_name' => ['required'],
|
'first_name' => ['required'],
|
||||||
'last_name' => ['required'],
|
'last_name' => ['required'],
|
||||||
|
|
@ -70,6 +73,39 @@ class UserController extends Controller
|
||||||
'is_admin' => $validData['is_admin'],
|
'is_admin' => $validData['is_admin'],
|
||||||
'is_tab' => $validData['is_tab'],
|
'is_tab' => $validData['is_tab'],
|
||||||
]);
|
]);
|
||||||
|
$user->refresh();
|
||||||
|
$logged_school = $user->school_id ? $user->school->name : 'No School';
|
||||||
|
$message = 'Updated user #'.$user->id.' - '.$oldEmail
|
||||||
|
.'<br>Name: '.$user->full_name()
|
||||||
|
.'<br>Email: '.$user->email
|
||||||
|
.'<br>Cell Phone: '.$user->cell_phone
|
||||||
|
.'<br>Judging Pref: '.$user->judging_preference
|
||||||
|
.'<br>School: '.$logged_school;
|
||||||
|
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
if ($user->is_admin != $wasAdmin) {
|
||||||
|
$messageStart = $user->is_admin ? 'Granted admin privileges to ' : 'Revoked admin privileges from ';
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $messageStart.$user->full_name().' - '.$user->email,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if ($user->is_tab != $wasTab) {
|
||||||
|
$messageStart = $user->is_tab ? 'Granted tabulation privileges to ' : 'Revoked tabulation privileges from ';
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $messageStart.$user->full_name().' - '.$user->email,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return redirect('/admin/users');
|
return redirect('/admin/users');
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +137,25 @@ class UserController extends Controller
|
||||||
}
|
}
|
||||||
$user->school_id = request('school_id');
|
$user->school_id = request('school_id');
|
||||||
$user->save();
|
$user->save();
|
||||||
|
$message = 'Created user '.$user->email.' - '.$user->full_name().'<br>Cell Phone: '.$user->cell_phone.'<br>Judging Pref: '.$user->judging_preference;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
if ($user->school_id) {
|
||||||
|
$message = 'Set user '.$user->full_name().' ('.$user->email.') as a director at '.$user->school->name.'(#'.$user->school->id.')';
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'users' => [$user->id],
|
||||||
|
'schools' => [$user->id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
Mail::to($user->email)->send(new NewUserPassword($user, $randomPassword));
|
Mail::to($user->email)->send(new NewUserPassword($user, $randomPassword));
|
||||||
|
|
||||||
return redirect('/admin/users');
|
return redirect('/admin/users');
|
||||||
|
|
@ -112,6 +166,13 @@ class UserController extends Controller
|
||||||
if (! Auth::user()->is_admin) {
|
if (! Auth::user()->is_admin) {
|
||||||
abort(403);
|
abort(403);
|
||||||
}
|
}
|
||||||
|
$message = 'Deleted user '.$user->email;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
$user->delete();
|
$user->delete();
|
||||||
|
|
||||||
return redirect()->route('admin.users.index')->with('success', 'User deleted successfully');
|
return redirect()->route('admin.users.index')->with('success', 'User deleted successfully');
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||||
use App\Actions\Entries\CreateEntry;
|
use App\Actions\Entries\CreateEntry;
|
||||||
use App\Exceptions\ManageEntryException;
|
use App\Exceptions\ManageEntryException;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
@ -65,9 +66,25 @@ class EntryController extends Controller
|
||||||
if ($request->user()->cannot('delete', $entry)) {
|
if ($request->user()->cannot('delete', $entry)) {
|
||||||
abort(403);
|
abort(403);
|
||||||
}
|
}
|
||||||
|
if (auth()->user()) {
|
||||||
|
$message = 'Deleted entry '.$entry->id;
|
||||||
|
$affected = [
|
||||||
|
'entries' => [$entry->id],
|
||||||
|
'auditions' => [$entry->audition_id],
|
||||||
|
'schools' => [$entry->student->school_id],
|
||||||
|
'students' => [$entry->student_id],
|
||||||
|
];
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => $affected,
|
||||||
|
]);
|
||||||
|
}
|
||||||
$entry->delete();
|
$entry->delete();
|
||||||
|
|
||||||
return redirect()->route('entries.index')->with('success', 'The '.$entry->audition->name.'entry for '.$entry->student->full_name().'has been deleted.');
|
return redirect()->route('entries.index')->with('success',
|
||||||
|
'The '.$entry->audition->name.'entry for '.$entry->student->full_name().'has been deleted.');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\School;
|
use App\Models\School;
|
||||||
use App\Models\SchoolEmailDomain;
|
use App\Models\SchoolEmailDomain;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
@ -34,16 +35,41 @@ class SchoolController extends Controller
|
||||||
'state' => request('state'),
|
'state' => request('state'),
|
||||||
'zip' => request('zip'),
|
'zip' => request('zip'),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Created school #'.$school->id.' - '.$school->name.' with address <br>'.$school->address.'<br>'.$school->city.', '.$school->state.' '.$school->zip;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['schools' => [$school->id]],
|
||||||
|
]);
|
||||||
|
|
||||||
if (! Auth::user()->school) {
|
if (! Auth::user()->school) {
|
||||||
Auth::user()->update([
|
Auth::user()->update([
|
||||||
'school_id' => $school->id,
|
'school_id' => $school->id,
|
||||||
]);
|
]);
|
||||||
|
$message = 'Set user '.auth()->user()->full_name().' ('.auth()->user()->email.') as a director at '.$school->name.'(#'.$school->id.')';
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'users' => [auth()->user()->id],
|
||||||
|
'schools' => [$school->id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
SchoolEmailDomain::create([
|
SchoolEmailDomain::create([
|
||||||
'school_id' => $school->id,
|
'school_id' => $school->id,
|
||||||
'domain' => Auth::user()->emailDomain(),
|
'domain' => Auth::user()->emailDomain(),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Added '.auth()->user()->emailDomain().' as an email domain for '.$school->name.' (#'.$school->id.')';
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'schools' => [$school->id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect('/schools/'.$school->id);
|
return redirect('/schools/'.$school->id);
|
||||||
|
|
@ -96,6 +122,13 @@ class SchoolController extends Controller
|
||||||
'state' => request('state'),
|
'state' => request('state'),
|
||||||
'zip' => request('zip'),
|
'zip' => request('zip'),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Modified school #'.$school->id.' - '.$school->name.' with address <br>'.$school->address.'<br>'.$school->city.', '.$school->state.' '.$school->zip;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => ['schools' => [$school->id]],
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect()->route('schools.show', $school->id)->with('success', 'School details updated');
|
return redirect()->route('schools.show', $school->id)->with('success', 'School details updated');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Rules\UniqueFullNameAtSchool;
|
use App\Rules\UniqueFullNameAtSchool;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -58,10 +59,18 @@ class StudentController extends Controller
|
||||||
'grade' => request('grade'),
|
'grade' => request('grade'),
|
||||||
'school_id' => Auth::user()->school_id,
|
'school_id' => Auth::user()->school_id,
|
||||||
]);
|
]);
|
||||||
|
$message = 'Created student #'.$student->id.' - '.$student->full_name().'<br>Grade: '.$student->grade.'<br>School: '.$student->school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'students' => [$student->id],
|
||||||
|
'schools' => [$student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
$request->session()->put('auditionMessages', ['success', 'I did it again ma']);
|
return redirect('/students')->with('success', 'Student Created');
|
||||||
|
|
||||||
return redirect('/students');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,7 +113,8 @@ class StudentController extends Controller
|
||||||
->where('school_id', Auth::user()->school_id)
|
->where('school_id', Auth::user()->school_id)
|
||||||
->where('id', '!=', $student->id)
|
->where('id', '!=', $student->id)
|
||||||
->exists()) {
|
->exists()) {
|
||||||
return redirect()->route('students.edit', $student)->with('error', 'A student with that name already exists at your school.');
|
return redirect()->route('students.edit', $student)->with('error',
|
||||||
|
'A student with that name already exists at your school.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$student->update([
|
$student->update([
|
||||||
|
|
@ -112,6 +122,16 @@ class StudentController extends Controller
|
||||||
'last_name' => request('last_name'),
|
'last_name' => request('last_name'),
|
||||||
'grade' => request('grade'),
|
'grade' => request('grade'),
|
||||||
]);
|
]);
|
||||||
|
$message = 'Updated student #'.$student->id.'<br>Name: '.$student->full_name().'<br>Grade: '.$student->grade.'<br>School: '.$student->school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'students' => [$student->id],
|
||||||
|
'schools' => [$student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect('/students')->with('success', 'Student updated successfully.');
|
return redirect('/students')->with('success', 'Student updated successfully.');
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +144,16 @@ class StudentController extends Controller
|
||||||
if ($request->user()->cannot('delete', $student)) {
|
if ($request->user()->cannot('delete', $student)) {
|
||||||
abort(403);
|
abort(403);
|
||||||
}
|
}
|
||||||
|
$message = 'Deleted student #'.$student->id.'<br>Name: '.$student->full_name().'<br>Grade: '.$student->grade.'<br>School: '.$student->school->name;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
'affected' => [
|
||||||
|
'students' => [$student->id],
|
||||||
|
'schools' => [$student->school_id],
|
||||||
|
],
|
||||||
|
]);
|
||||||
$student->delete();
|
$student->delete();
|
||||||
|
|
||||||
return redirect(route('students.index'));
|
return redirect(route('students.index'));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Events\Login;
|
||||||
|
|
||||||
|
class LogLogin
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*/
|
||||||
|
public function handle(Login $event): void
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $event->user;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => $user->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => 'Logged In',
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Events\Logout;
|
||||||
|
|
||||||
|
class LogLogout
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*/
|
||||||
|
public function handle(Logout $event): void
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $event->user;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => $user->email,
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => 'Logged Out',
|
||||||
|
'affected' => ['users' => [$user->id]],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Models\AuditLogEntry;
|
||||||
|
use Illuminate\Mail\Events\MessageSending;
|
||||||
|
|
||||||
|
use function request;
|
||||||
|
|
||||||
|
class LogSendingEmail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*/
|
||||||
|
public function handle(MessageSending $event): void
|
||||||
|
{
|
||||||
|
$email_to = ($event->message->getTo()[0]->getAddress());
|
||||||
|
$subject = $event->message->getSubject();
|
||||||
|
$message = 'Sent email to '.$email_to.'<br>Subject: '.$subject;
|
||||||
|
AuditLogEntry::create([
|
||||||
|
'user' => auth()->user()->email ?? 'none',
|
||||||
|
'ip_address' => request()->ip(),
|
||||||
|
'message' => $message,
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class AuditLogEntry extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
protected $casts = ['affected' => 'json'];
|
||||||
|
|
||||||
|
public function getCreatedAtAttribute($value)
|
||||||
|
{
|
||||||
|
return \Carbon\Carbon::parse($value)
|
||||||
|
->setTimezone('America/Chicago')
|
||||||
|
->format('M j, Y H:i:s');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('audit_log_entries', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('user');
|
||||||
|
$table->ipAddress('ip_address')->nullable();
|
||||||
|
$table->string('message');
|
||||||
|
$table->json('affected')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('audit_log_entries');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<x-layout.app>
|
||||||
|
<x-slot:page_title>AuditionAdmin Logs</x-slot:page_title>
|
||||||
|
<x-card.card>
|
||||||
|
<div class="px-4 sm:px-6 lg:px-8">
|
||||||
|
<div class="mt-4 flow-root">
|
||||||
|
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||||
|
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
||||||
|
<table class="min-w-full divide-y divide-gray-300">
|
||||||
|
<thead>
|
||||||
|
<tr class="divide-x divide-gray-200">
|
||||||
|
<th scope="col"
|
||||||
|
class="py-3.5 pl-4 pr-4 text-left text-sm font-semibold text-gray-900 sm:pl-0">
|
||||||
|
Timestamp
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-4 py-3.5 text-left text-sm font-semibold text-gray-900">User
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-4 py-3.5 text-left text-sm font-semibold text-gray-900">IP
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="py-3.5 pl-4 pr-4 text-left text-sm font-semibold text-gray-900 sm:pr-0">
|
||||||
|
Message
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
|
@foreach($log_entries as $entry)
|
||||||
|
@php($message = strip_tags($entry->message, '<br>'))
|
||||||
|
<tr class="divide-x divide-gray-200">
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-4 text-sm font-medium text-gray-900 sm:pl-0">{{ $entry->created_at }}</td>
|
||||||
|
<td class="whitespace-nowrap p-4 text-sm text-gray-500">{{ $entry->user }}</td>
|
||||||
|
<td class="whitespace-nowrap p-4 text-sm text-gray-500">{{ $entry->ip_address }}</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-4 text-sm text-gray-500 sm:pr-0">{!! $message !!}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
<!-- More people... -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="py-6 border-t">
|
||||||
|
{{ $log_entries->links() }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-card.card>
|
||||||
|
|
||||||
|
</x-layout.app>
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="/admin/schools" class="block p-2 hover:text-indigo-600">Schools</a>
|
<a href="/admin/schools" class="block p-2 hover:text-indigo-600">Schools</a>
|
||||||
<a href="/admin/students" class="block p-2 hover:text-indigo-600">Students</a>
|
<a href="/admin/students" class="block p-2 hover:text-indigo-600">Students</a>
|
||||||
<a href="/admin/entries" class="block p-2 hover:text-indigo-600">Entries</a>
|
<a href="/admin/entries" class="block p-2 hover:text-indigo-600">Entries</a>
|
||||||
|
<a href="{{route('admin.view_logs')}}" class="block p-2 hover:text-indigo-600">View Logs</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')->group(function () {
|
Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')->group(function () {
|
||||||
Route::view('/', 'admin.dashboard')->name('admin.dashboard');
|
Route::view('/', 'admin.dashboard')->name('admin.dashboard');
|
||||||
|
Route::get('/logs', App\Http\Controllers\Admin\LogViewer::class)->name('admin.view_logs');
|
||||||
|
|
||||||
Route::post('/auditions/roomUpdate', [
|
Route::post('/auditions/roomUpdate', [
|
||||||
AuditionController::class, 'roomUpdate',
|
AuditionController::class, 'roomUpdate',
|
||||||
|
|
@ -31,8 +32,7 @@ Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')->
|
||||||
[AuditionSettings::class, 'save'])->name('audition-settings-save');
|
[AuditionSettings::class, 'save'])->name('audition-settings-save');
|
||||||
|
|
||||||
// Admin Bonus Scores Routes
|
// Admin Bonus Scores Routes
|
||||||
Route::prefix('bonus-scores')->controller(BonusScoreDefinitionController::class)->group(function (
|
Route::prefix('bonus-scores')->controller(BonusScoreDefinitionController::class)->group(function () {
|
||||||
) {
|
|
||||||
Route::get('/', 'index')->name('admin.bonus-scores.index');
|
Route::get('/', 'index')->name('admin.bonus-scores.index');
|
||||||
Route::post('/', 'store')->name('admin.bonus-scores.store');
|
Route::post('/', 'store')->name('admin.bonus-scores.store');
|
||||||
Route::post('/assign_auditions', 'assignAuditions')->name('admin.bonus-scores.addAuditions');
|
Route::post('/assign_auditions', 'assignAuditions')->name('admin.bonus-scores.addAuditions');
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,6 @@ Route::middleware(['auth', 'verified'])->controller(SchoolController::class)->gr
|
||||||
Route::get('/schools/create', 'create')->name('schools.create');
|
Route::get('/schools/create', 'create')->name('schools.create');
|
||||||
Route::post('/schools', 'store')->name('schools.store');
|
Route::post('/schools', 'store')->name('schools.store');
|
||||||
Route::get('/schools/{school}/edit', 'edit')->name('schools.edit');
|
Route::get('/schools/{school}/edit', 'edit')->name('schools.edit');
|
||||||
Route::get('/schools/{school}', 'show')->name('schools.show')->name('schools.show');
|
Route::get('/schools/{school}', 'show')->name('schools.show');
|
||||||
Route::patch('/schools/{school}', 'update')->name('schools.update');
|
Route::patch('/schools/{school}', 'update')->name('schools.update');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ it('has a field with forms for each audition setting', function () {
|
||||||
'name' => 'school_fee',
|
'name' => 'school_fee',
|
||||||
'value' => number_format(auditionSetting('school_fee') / 100, 2),
|
'value' => number_format(auditionSetting('school_fee') / 100, 2),
|
||||||
])
|
])
|
||||||
->containsInput([
|
->containsTextarea([
|
||||||
'name' => 'payment_address',
|
'name' => 'payment_address',
|
||||||
'value' => auditionSetting('payment_address'),
|
'value' => auditionSetting('payment_address'),
|
||||||
])
|
])
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue