diff --git a/app/CustomFacades/IP.php b/app/CustomFacades/IP.php index 89478c3..2b04064 100644 --- a/app/CustomFacades/IP.php +++ b/app/CustomFacades/IP.php @@ -16,11 +16,6 @@ class IP public function lookup(string $IP): object { - if (empty($IP)) - { - throw new LogicException(__METHOD__ . 'is missing parameter IP!'); - } - $params = [ 'apiKey' => config('general.keys.ipapi.apikey'), 'ip' => $IP diff --git a/app/Helpers/ContextAwareValidator.php b/app/Helpers/ContextAwareValidator.php index fe4ed97..f2ffb55 100644 --- a/app/Helpers/ContextAwareValidator.php +++ b/app/Helpers/ContextAwareValidator.php @@ -7,6 +7,29 @@ use Illuminate\Support\Collection; class ContextAwareValidator { + + /** + * The excludedNames array will make the validator ignore any of these names when including names into the rules. + * @var array + */ + private $excludedNames = [ + '_token', + '_method', + 'formName' + ]; + + + /** + * Utility wrapper for json_encode. + * + * @param array $value The array to be converted. + * @return string The JSON representation of $value + */ + private function encode(array $value) : string + { + return json_encode($value); + } + /** * The getValidator() method will take an array of fields from the request body, iterates through them, * and dynamically adds validation rules for them. Depending on parameters, it may or may not generate @@ -30,12 +53,6 @@ class ContextAwareValidator $formStructure = []; $validator = []; - $excludedNames = [ - '_token', - '_method', - 'formName' - ]; - if ($includeFormName) { $validator['formName'] = 'required|string|max:100'; @@ -43,7 +60,7 @@ class ContextAwareValidator foreach ($fields as $fieldName => $field) { - if(!in_array($fieldName, $excludedNames)) + if(!in_array($fieldName, $this->excludedNames)) { $validator[$fieldName . ".0"] = 'required|string'; $validator[$fieldName . ".1"] = 'required|string'; @@ -62,11 +79,60 @@ class ContextAwareValidator return ($generateStructure) ? collect([ 'validator' => $validatorInstance, - 'structure' => json_encode($formStructure) + 'structure' => $this->encode($formStructure) ]) : $validatorInstance; } + /** + * The getResponseValidator method is similar to the getValidator method; It basically takes + * an array of fields from a previous form (that probably went through the other method) and adds validation + * to the field names. + * + * Also generates the storable response structure if you tell it to. + * + * @param array $fields The received fields + * @param array $formStructure The form structure - You must supply this if you want the response structure + * @param bool $generateResponseStructure Whether to generate the response structure + * @return Validator|Collection A collection or a validator, depending on the args. Will return validatior if only fields are supplied. + */ + public function getResponseValidator(array $fields, array $formStructure = [], bool $generateResponseStructure = true) + { + + $responseStructure = []; + $validator = []; + + if (empty($formStructure) && $generateResponseStructure) + { + throw new \InvalidArgumentException('Illegal combination of arguments supplied! Please check the method\'s documentation.'); + } + + foreach($fields as $fieldName => $value) + { + if(!in_array($fieldName, $this->excludedNames)) + { + $validator[$fieldName] = 'required|string'; + + if ($generateResponseStructure) + { + $responseStructure['responses'][$fieldName]['type'] = $formStructure['fields'][$fieldName]['type'] ?? 'Unavailable'; + $responseStructure['responses'][$fieldName]['title'] = $formStructure['fields'][$fieldName]['title']; + $responseStructure['responses'][$fieldName]['response'] = $value; + } + } + } + + $validatorInstance = Validator::make($fields, $validator); + + return ($generateResponseStructure) ? + collect([ + 'validator' => $validatorInstance, + 'responseStructure' => $this->encode($responseStructure) + ]) + : $validatorInstance; + + } + } diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index aaa5dc3..0895da4 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -18,8 +18,11 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Log; +use ContextAwareValidator; + class ApplicationController extends Controller { + private function canVote($votes) { $allvotes = collect([]); @@ -45,11 +48,8 @@ class ApplicationController extends Controller } - public function showUserApp(Request $request, $applicationID) + public function showUserApp(Request $request, Application $application) { - // TODO: Inject it instead (do this where there is no injection, not just here) - $application = Application::find($applicationID); - $this->authorize('view', $application); if (!is_null($application)) @@ -78,6 +78,8 @@ class ApplicationController extends Controller public function showAllApps() { + $this->authorize('viewAny', Application::class); + return view('dashboard.appmanagement.all') ->with('applications', Application::paginate(6)); } @@ -186,36 +188,16 @@ class ApplicationController extends Controller Log::info('Processing new application!'); $formStructure = json_decode($vacancy->first()->forms->formStructure, true); - $responseStructure = []; - - $excludedNames = [ - '_token', - ]; - - $validator = []; - - foreach($request->all() as $fieldName => $value) - { - if(!in_array($fieldName, $excludedNames)) - { - $validator[$fieldName] = 'required|string'; - - $responseStructure['responses'][$fieldName]['type'] = $formStructure['fields'][$fieldName]['type'] ?? 'Unavailable'; - $responseStructure['responses'][$fieldName]['title'] = $formStructure['fields'][$fieldName]['title']; - $responseStructure['responses'][$fieldName]['response'] = $value; - } - } + $responseValidation = ContextAwareValidator::getResponseValidator($request->all(), $formStructure); Log::info('Built response & validator structure!'); - $validation = Validator::make($request->all(), $validator); - - if (!$validation->fails()) + if (!$responseValidation->get('validator')->fails()) { $response = Response::create([ 'responseFormID' => $vacancy->first()->forms->id, 'associatedVacancyID' => $vacancy->first()->id, // Since a form can be used by multiple vacancies, we can only know which specific vacancy this response ties to by using a vacancy ID - 'responseData' => json_encode($responseStructure) + 'responseData' => $responseValidation->get('responseStructure') ]); Log::info('Registered form response for user ' . Auth::user()->name . ' for vacancy ' . $vacancy->first()->vacancyName); @@ -249,35 +231,27 @@ class ApplicationController extends Controller return redirect()->back(); } - public function updateApplicationStatus(Request $request, $applicationID, $newStatus) + public function updateApplicationStatus(Request $request, $application, $newStatus) { - $application = Application::find($applicationID); $this->authorize('update', Application::class); - if (!is_null($application)) + switch ($newStatus) { - switch ($newStatus) - { - case 'deny': + case 'deny': - event(new ApplicationDeniedEvent($application)); - break; + event(new ApplicationDeniedEvent($application)); + break; - case 'interview': - Log::info('User ' . Auth::user()->name . ' has moved application ID ' . $application->id . 'to interview stage'); - $request->session()->flash('success', 'Application moved to interview stage! (:'); - $application->setStatus('STAGE_INTERVIEW'); + case 'interview': + Log::info('User ' . Auth::user()->name . ' has moved application ID ' . $application->id . 'to interview stage'); + $request->session()->flash('success', 'Application moved to interview stage! (:'); + $application->setStatus('STAGE_INTERVIEW'); - $application->user->notify(new ApplicationMoved()); - break; + $application->user->notify(new ApplicationMoved()); + break; - default: - $request->session()->flash('error', 'There are no suitable statuses to update to. Do not mess with the URL.'); - } - } - else - { - $request->session()->flash('The application you\'re trying to update does not exist.'); + default: + $request->session()->flash('error', 'There are no suitable statuses to update to. Do not mess with the URL.'); } return redirect()->back(); @@ -291,7 +265,7 @@ class ApplicationController extends Controller $request->session()->flash('success', 'Application deleted. Comments, appointments and responses have also been deleted.'); return redirect()->back(); - + } } diff --git a/app/Http/Controllers/AppointmentController.php b/app/Http/Controllers/AppointmentController.php index 1a97819..ad07012 100644 --- a/app/Http/Controllers/AppointmentController.php +++ b/app/Http/Controllers/AppointmentController.php @@ -24,84 +24,56 @@ class AppointmentController extends Controller ]; - public function saveAppointment(Request $request, $applicationID) + public function saveAppointment(Request $request, Application $application) { - // Unrelated TODO: change if's in application page to a switch statement, & have the row encompass it - $this->authorize('create', Appointment::class); + $appointmentDate = Carbon::parse($request->appointmentDateTime); - $app = Application::find($applicationID); - - if (!is_null($app)) - { - // make sure this is a valid date by parsing it first - $appointmentDate = Carbon::parse($request->appointmentDateTime); + $appointment = Appointment::create([ + 'appointmentDescription' => $request->appointmentDescription, + 'appointmentDate' => $appointmentDate->toDateTimeString(), + 'applicationID' => $application->id, + 'appointmentLocation' => (in_array($request->appointmentLocation, $this->allowedPlatforms)) ? $request->appointmentLocation : 'DISCORD', + ]); + $application->setStatus('STAGE_INTERVIEW_SCHEDULED'); - $appointment = Appointment::create([ - 'appointmentDescription' => $request->appointmentDescription, - 'appointmentDate' => $appointmentDate->toDateTimeString(), - 'applicationID' => $applicationID, - 'appointmentLocation' => (in_array($request->appointmentLocation, $this->allowedPlatforms)) ? $request->appointmentLocation : 'DISCORD', - ]); - $app->setStatus('STAGE_INTERVIEW_SCHEDULED'); + Log::info('User ' . Auth::user()->name . ' has scheduled an appointment with ' . $application->user->name . ' for application ID' . $application->id, [ + 'datetime' => $appointmentDate->toDateTimeString(), + 'scheduled' => now() + ]); + $application->user->notify(new AppointmentScheduled($appointment)); + $request->session()->flash('success', 'Appointment successfully scheduled @ ' . $appointmentDate->toDateTimeString()); - Log::info('User ' . Auth::user()->name . ' has scheduled an appointment with ' . $app->user->name . ' for application ID' . $app->id, [ - 'datetime' => $appointmentDate->toDateTimeString(), - 'scheduled' => now() - ]); - - $app->user->notify(new AppointmentScheduled($appointment)); - $request->session()->flash('success', 'Appointment successfully scheduled @ ' . $appointmentDate->toDateTimeString()); - - } - else - { - $request->session()->flash('error', 'Cant\'t schedule an appointment for an application that doesn\'t exist.'); - } return redirect()->back(); } - public function updateAppointment(Request $request, $applicationID, $status) + public function updateAppointment(Request $request, Application $application, $status) { + $this->authorize('update', $application->appointment); - - $application = Application::find($applicationID); $validStatuses = [ 'SCHEDULED', 'CONCLUDED' ]; - $this->authorize('update', $application->appointment); + // NOTE: This is a little confusing, refactor + $application->appointment->appointmentStatus = (in_array($status, $validStatuses)) ? strtoupper($status) : 'SCHEDULED'; + $application->appointment->save(); + + $application->setStatus('STAGE_PEERAPPROVAL'); + $application->user->notify(new ApplicationMoved()); - - if (!is_null($application)) - { - // NOTE: This is a little confusing, refactor - $application->appointment->appointmentStatus = (in_array($status, $validStatuses)) ? strtoupper($status) : 'SCHEDULED'; - $application->appointment->save(); - - $application->setStatus('STAGE_PEERAPPROVAL'); - $application->user->notify(new ApplicationMoved()); - - $request->session()->flash('success', 'Interview finished! Staff members can now vote on it.'); - } - else - { - $request->session()->flash('error', 'The application you\'re trying to update doesn\'t exist or have an appointment.'); - } - + $request->session()->flash('success', 'Interview finished! Staff members can now vote on it.'); return redirect()->back(); } // also updates - public function saveNotes(SaveNotesRequest $request, $applicationID) + public function saveNotes(SaveNotesRequest $request, $application) { - $application = Application::find($applicationID); - if (!is_null($application)) { $application->appointment->meetingNotes = $request->noteText; @@ -111,7 +83,7 @@ class AppointmentController extends Controller } else { - $request->session()->flash('error', 'Sanity check failed: There\'s no appointment to save notes to!'); + $request->session()->flash('error', 'There\'s no appointment to save notes to!'); } return redirect()->back(); diff --git a/app/Http/Controllers/BanController.php b/app/Http/Controllers/BanController.php index a0182bd..e9aefd1 100644 --- a/app/Http/Controllers/BanController.php +++ b/app/Http/Controllers/BanController.php @@ -15,11 +15,7 @@ class BanController extends Controller public function insert(BanUserRequest $request, User $user) { - if ($user->is(Auth::user())) - { - $request->session()->flash('error', 'You can\'t ban yourself!'); - return redirect()->back(); - } + $this->authorize('create', Ban::class); if (is_null($user->bans)) { diff --git a/app/Http/Controllers/CommentController.php b/app/Http/Controllers/CommentController.php index a26cb37..09d2aa2 100644 --- a/app/Http/Controllers/CommentController.php +++ b/app/Http/Controllers/CommentController.php @@ -22,7 +22,7 @@ class CommentController extends Controller public function insert(NewCommentRequest $request, Application $application) { $this->authorize('create', Comment::class); - + $comment = Comment::create([ 'authorID' => Auth::user()->id, 'applicationID' => $application->id, @@ -32,14 +32,6 @@ class CommentController extends Controller if ($comment) { - foreach (User::all() as $user) - { - if ($user->isStaffMember()) - { - $user->notify(new NewComment($comment, $application)); - } - } - $request->session()->flash('success', 'Comment posted! (:'); } else diff --git a/app/Http/Controllers/ContactController.php b/app/Http/Controllers/ContactController.php index 1e61eab..7a2923f 100644 --- a/app/Http/Controllers/ContactController.php +++ b/app/Http/Controllers/ContactController.php @@ -4,11 +4,23 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; use GuzzleHttp; +use App\Notifications\NewContact; use Illuminate\Support\Facades\Http; +use App\User; + class ContactController extends Controller { + protected $users; + + + public function __construct(User $users) + { + $this->users = $users; + } + + public function create(Request $request) { $name = $request->name; @@ -18,12 +30,14 @@ class ContactController extends Controller $challenge = $request->input('captcha'); + // TODO: now: add middleware for this verification, move to invisible captcha $verifyrequest = Http::asForm()->post(config('recaptcha.verify.apiurl'), [ 'secret' => config('recaptcha.keys.secret'), 'response' => $challenge, - 'remoteip' => $_SERVER['REMOTE_ADDR'] + 'remoteip' => $request->ip() ]); + $response = json_decode($verifyrequest->getBody(), true); if (!$response['success']) @@ -32,7 +46,18 @@ class ContactController extends Controller return redirect()->back(); } - // TODO: Send mail + + foreach(User::all() as $user) + { + if ($user->hasRole('admin')) + { + $user->notify(new NewContact(collect([ + 'message' => $msg, + 'ip' => $request->ip(), + 'email' => $email + ]))); + } + } $request->session()->flash('success', 'Message sent successfully! We usually respond within 48 hours.'); return redirect()->back(); diff --git a/app/Http/Controllers/DevToolsController.php b/app/Http/Controllers/DevToolsController.php index ecac0e3..5c82d26 100644 --- a/app/Http/Controllers/DevToolsController.php +++ b/app/Http/Controllers/DevToolsController.php @@ -6,16 +6,30 @@ use App\Application; use App\Events\ApplicationApprovedEvent; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; + class DevToolsController extends Controller { + + // The use case for Laravel's gate and/or validation Requests is so tiny here that a full-blown policy would be overkill. + protected function isolatedAuthorise() + { + if (!Auth::user()->can('admin.developertools.use')) + { + abort(403, 'You\'re not authorized to access this page.'); + } + } + public function index() { + $this->isolatedAuthorise(); return view('dashboard.administration.devtools') ->with('applications', Application::where('applicationStatus', 'STAGE_PEERAPPROVAL')->get()); } public function forceVoteCount(Request $request) { + $this->isolatedAuthorise(); $application = Application::find($request->application); if (!is_null($application)) diff --git a/app/Http/Controllers/FormController.php b/app/Http/Controllers/FormController.php index 3b1a7f4..27d40dd 100644 --- a/app/Http/Controllers/FormController.php +++ b/app/Http/Controllers/FormController.php @@ -55,10 +55,8 @@ class FormController extends Controller return redirect()->back(); } - public function destroy(Request $request, $id) + public function destroy(Request $request, Form $form) { - - $form = Form::find($id); $this->authorize('delete', $form); $deletable = true; @@ -85,6 +83,8 @@ class FormController extends Controller public function preview(Request $request, Form $form) { + $this->authorize('viewAny', Form::class); + return view('dashboard.administration.formpreview') ->with('form', json_decode($form->formStructure, true)) ->with('title', $form->formName) @@ -93,6 +93,8 @@ class FormController extends Controller public function edit(Request $request, Form $form) { + $this->authorize('update', $form); + return view('dashboard.administration.editform') ->with('formStructure', json_decode($form->formStructure, true)) ->with('title', $form->formName) @@ -101,6 +103,8 @@ class FormController extends Controller public function update(Request $request, Form $form) { + $this->authorize('update', $form); + $contextValidation = ContextAwareValidator::getValidator($request->all(), true); $this->authorize('update', $form); diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 7a35d1c..0fc063d 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -87,7 +87,6 @@ class ProfileController extends Controller public function saveProfile(ProfileSave $request) { - // TODO: Switch to route model binding $profile = User::find(Auth::user()->id)->profile; $social = []; @@ -120,19 +119,6 @@ class ProfileController extends Controller $request->session()->flash('success', 'Profile settings saved successfully.'); } - else - { - $gm = 'Guru Meditation #' . rand(0, 1000); - Log::alert('[GURU MEDITATION]: Could not find profile for authenticated user ' . Auth::user()->name . 'whilst trying to update it! Please verify that profiles are being created automatically during signup.', - [ - 'uuid' => Auth::user()->uuid, - 'timestamp' => now(), - 'route' => $request->route()->getName(), - 'gmcode' => $gm // If this error is reported, the GM code, denoting a severe error, will help us find this entry in the logs - - ]); - $request->session()->flash('error', 'A technical error has occurred whilst trying to save your profile. Incident details have been recorded. Please report this incident to administrators with the following case number: ' . $gm); - } return redirect()->back(); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 2cb19e9..fcb860e 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -189,6 +189,9 @@ class UserController extends Controller public function delete(DeleteUserRequest $request, User $user) { + + $this->authorize('delete', $user); + if ($request->confirmPrompt == 'DELETE ACCOUNT') { $user->delete(); @@ -206,6 +209,8 @@ class UserController extends Controller public function update(UpdateUserRequest $request, User $user) { + $this->authorize('adminEdit', $user); + // Mass update would not be possible here without extra code, making route model binding useless $user->email = $request->email; $user->name = $request->name; diff --git a/app/Http/Controllers/VacancyController.php b/app/Http/Controllers/VacancyController.php index 3674d9c..89eacce 100644 --- a/app/Http/Controllers/VacancyController.php +++ b/app/Http/Controllers/VacancyController.php @@ -64,10 +64,9 @@ class VacancyController extends Controller } - public function updatePositionAvailability(Request $request, $status, $id) + public function updatePositionAvailability(Request $request, $status, Vacancy $vacancy) { - $vacancy = Vacancy::find($id); $this->authorize('update', $vacancy); if (!is_null($vacancy)) diff --git a/app/Http/Controllers/VoteController.php b/app/Http/Controllers/VoteController.php index 31b8acd..8674dcf 100644 --- a/app/Http/Controllers/VoteController.php +++ b/app/Http/Controllers/VoteController.php @@ -13,33 +13,23 @@ use Illuminate\Support\Facades\Log; class VoteController extends Controller { - public function vote(VoteRequest $voteRequest, $applicationID) + public function vote(VoteRequest $voteRequest, Application $application) { - $application = Application::find($applicationID); $this->authorize('create', Vote::class); - if (!is_null($application)) - { - $vote = Vote::create([ - 'userID' => Auth::user()->id, - 'allowedVoteType' => $voteRequest->voteType, - ]); + $vote = Vote::create([ + 'userID' => Auth::user()->id, + 'allowedVoteType' => $voteRequest->voteType, + ]); + $vote->application()->attach($applicationID); - $vote->application()->attach($applicationID); - Log::info('User ' . Auth::user()->name . ' has voted in applicant ' . $application->user->name . '\'s application', [ - 'voteType' => $voteRequest->voteType - ]); - - $voteRequest->session()->flash('success', 'Your vote has been registered! You will now be notified about the outcome of this application.'); - } - else - { - $voteRequest->session()->flash('error', 'Can\t vote a non existant application!'); - } + Log::info('User ' . Auth::user()->name . ' has voted in applicant ' . $application->user->name . '\'s application', [ + 'voteType' => $voteRequest->voteType + ]); + $voteRequest->session()->flash('success', 'Your vote has been registered!'); // Cron job will run command that processes votes - return redirect()->back(); } } diff --git a/app/Notifications/ApplicationDenied.php b/app/Notifications/ApplicationDenied.php index 82993ce..03a4382 100644 --- a/app/Notifications/ApplicationDenied.php +++ b/app/Notifications/ApplicationDenied.php @@ -52,7 +52,7 @@ class ApplicationDenied extends Notification implements ShouldQueue ->line('Your most recent application has been denied.') ->line('Our review team denies applications for several reasons, including poor answers.') ->line('Please review your application and try again in 30 days.') - ->action('Review application', url(route('showUserApp', ['id' => $this->application->id]))) + ->action('Review application', url(route('showUserApp', ['application' => $this->application->id]))) ->line('Better luck next time!'); } diff --git a/app/Notifications/NewApplicant.php b/app/Notifications/NewApplicant.php index 8bf34c4..d054b34 100644 --- a/app/Notifications/NewApplicant.php +++ b/app/Notifications/NewApplicant.php @@ -55,7 +55,7 @@ class NewApplicant extends Notification implements ShouldQueue ->subject(config('app.name') . ' - New application') ->line('Someone has just applied for a position. Check it out!') ->line('You are receiving this because you\'re a staff member at ' . config('app.name') . '.') - ->action('View Application', url(route('showUserApp', ['id' => $this->application->id]))) + ->action('View Application', url(route('showUserApp', ['application' => $this->application->id]))) ->line('Thank you!'); } @@ -67,7 +67,7 @@ class NewApplicant extends Notification implements ShouldQueue $vacancyDetails['name'] = $this->vacancy->vacancyName; $vacancyDetails['slots'] = $this->vacancy->vacancyCount; - $url = route('showUserApp', ['id' => $this->application->id]); + $url = route('showUserApp', ['application' => $this->application->id]); $applicant = $this->application->user->name; return (new SlackMessage) diff --git a/app/Notifications/NewComment.php b/app/Notifications/NewComment.php index f23a338..2f6d875 100644 --- a/app/Notifications/NewComment.php +++ b/app/Notifications/NewComment.php @@ -50,7 +50,7 @@ class NewComment extends Notification implements ShouldQueue ->subject(config('app.name') . ' - New comment') ->line('Someone has just posted a new comment on an application you follow.') ->line('You\'re receiving this email because you\'ve voted/commented on this application.') - ->action('Check it out', url(route('showUserApp', ['id' => $this->application->id]))) + ->action('Check it out', url(route('showUserApp', ['application' => $this->application->id]))) ->line('Thank you!'); } diff --git a/app/Notifications/NewContact.php b/app/Notifications/NewContact.php new file mode 100644 index 0000000..761f27c --- /dev/null +++ b/app/Notifications/NewContact.php @@ -0,0 +1,78 @@ +message = $message; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['mail']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + if ($this->message->has([ + 'message', + 'ip', + 'email' + ])) + { + return (new MailMessage) + ->line('We\'ve received a new contact form submission in the StaffManagement app center.') + ->line('This is what they sent: ') + ->line('') + ->line($this->message->get('message')) + ->line('') + ->line('This message was received from ' . $this->message->get('ip') . ' and submitted by ' . $this->message->get('email') . '.') + ->action('Sign in', url(route('login'))) + ->line('Thank you!'); + } + + throw new \InvalidArgumentException("Invalid arguments supplied to NewContact!"); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + // + ]; + } +} diff --git a/app/Policies/BanPolicy.php b/app/Policies/BanPolicy.php index d93adab..962cad2 100644 --- a/app/Policies/BanPolicy.php +++ b/app/Policies/BanPolicy.php @@ -41,7 +41,7 @@ class BanPolicy */ public function create(User $user) { - // + return $user->hasRole('admin') && $user->isNot(Auth::user()); } /** @@ -53,7 +53,7 @@ class BanPolicy */ public function update(User $user, Ban $ban) { - // + return $user->hasRole('admin'); } /** diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php index 8c861bc..b98f105 100644 --- a/app/Policies/UserPolicy.php +++ b/app/Policies/UserPolicy.php @@ -24,6 +24,12 @@ class UserPolicy return $authUser->is($user) || $authUser->hasRole('admin'); } + // This refers to the admin tools that let staff update more information than users themselves can + public function adminEdit(User $authUser, User $user) + { + return $authUser->hasRole('admin') && $authUser->isNot($user); + } + public function viewStaff(User $user) { return $user->can('admin.stafflist'); @@ -38,4 +44,9 @@ class UserPolicy { return $authUser->hasRole('admin'); } + + public function delete(User $authUser, User $subject) + { + return $authUser->hasRole('admin') && $authUser->isNot($subject); + } } diff --git a/resources/views/dashboard/administration/editposition.blade.php b/resources/views/dashboard/administration/editposition.blade.php index e5276b0..b0b5eb2 100644 --- a/resources/views/dashboard/administration/editposition.blade.php +++ b/resources/views/dashboard/administration/editposition.blade.php @@ -133,7 +133,7 @@ @if($vacancy->vacancyStatus == 'OPEN') -
+ @method('PATCH') @csrf diff --git a/resources/views/dashboard/administration/forms.blade.php b/resources/views/dashboard/administration/forms.blade.php index 1ce1af1..246383b 100644 --- a/resources/views/dashboard/administration/forms.blade.php +++ b/resources/views/dashboard/administration/forms.blade.php @@ -54,7 +54,7 @@ {{$form->created_at}} {{ $form->updated_at }} - + @method('DELETE') @csrf diff --git a/resources/views/dashboard/administration/positions.blade.php b/resources/views/dashboard/administration/positions.blade.php index 703e62f..5b03ac5 100644 --- a/resources/views/dashboard/administration/positions.blade.php +++ b/resources/views/dashboard/administration/positions.blade.php @@ -195,7 +195,7 @@ @if ($vacancy->vacancyStatus == 'OPEN') - + @csrf @method('PATCH') @@ -203,7 +203,7 @@ @else - + @csrf @method('PATCH') diff --git a/resources/views/dashboard/appmanagement/all.blade.php b/resources/views/dashboard/appmanagement/all.blade.php index 158f68e..16322ac 100644 --- a/resources/views/dashboard/appmanagement/all.blade.php +++ b/resources/views/dashboard/appmanagement/all.blade.php @@ -191,7 +191,7 @@ {{ $application->created_at }} - + diff --git a/resources/views/dashboard/appmanagement/interview.blade.php b/resources/views/dashboard/appmanagement/interview.blade.php index e290753..7b704a5 100644 --- a/resources/views/dashboard/appmanagement/interview.blade.php +++ b/resources/views/dashboard/appmanagement/interview.blade.php @@ -77,7 +77,7 @@ {{$application->user->name}} {{($application->applicationStatus == 'STAGE_INTERVIEW') ? 'Pending Interview' : 'Unknown Status'}} - + @@ -151,7 +151,7 @@ {{ucfirst(strtolower($upcomingApp->appointment->appointmentLocation))}} @endif - + diff --git a/resources/views/dashboard/appmanagement/outstandingapps.blade.php b/resources/views/dashboard/appmanagement/outstandingapps.blade.php index 5712a56..5fba004 100644 --- a/resources/views/dashboard/appmanagement/outstandingapps.blade.php +++ b/resources/views/dashboard/appmanagement/outstandingapps.blade.php @@ -70,7 +70,7 @@ {{$application->created_at}} {{$application->updated_at}} - + diff --git a/resources/views/dashboard/appmanagement/peerreview.blade.php b/resources/views/dashboard/appmanagement/peerreview.blade.php index 2de751b..10d4968 100644 --- a/resources/views/dashboard/appmanagement/peerreview.blade.php +++ b/resources/views/dashboard/appmanagement/peerreview.blade.php @@ -66,7 +66,7 @@ {{$application->created_at}} {{($application->applicationStatus == 'STAGE_PEERAPPROVAL') ? 'Peer Review' : 'Unknown'}} - + @endforeach diff --git a/resources/views/dashboard/user/applications.blade.php b/resources/views/dashboard/user/applications.blade.php index 98ca7da..30f514a 100644 --- a/resources/views/dashboard/user/applications.blade.php +++ b/resources/views/dashboard/user/applications.blade.php @@ -109,7 +109,7 @@ - + diff --git a/resources/views/dashboard/user/viewapp.blade.php b/resources/views/dashboard/user/viewapp.blade.php index 1a25864..640478a 100644 --- a/resources/views/dashboard/user/viewapp.blade.php +++ b/resources/views/dashboard/user/viewapp.blade.php @@ -38,7 +38,7 @@ - + @csrf @method('PATCH') @@ -62,7 +62,7 @@ - + @csrf @method('PATCH') @@ -200,7 +200,7 @@
- + @csrf @method('PATCH') @@ -230,7 +230,7 @@ - + @csrf @@ -286,7 +286,7 @@ @can('appointments.schedule.edit') - + @csrf @method('PATCH') @@ -322,12 +322,12 @@ @if($canVote) - + @csrf -
+ @csrf diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index f8c59d8..d6fb015 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -270,7 +270,7 @@
- +
diff --git a/routes/web.php b/routes/web.php index 49598b4..a6614f6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -40,7 +40,7 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ ->name('showUserApps') ->middleware('eligibility'); - Route::get('/view/{id}', 'ApplicationController@showUserApp') + Route::get('/view/{application}', 'ApplicationController@showUserApp') ->name('showUserApp'); Route::post('/{application}/comments', 'CommentController@insert') @@ -54,7 +54,7 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ ->name('saveNotes'); - Route::patch('/update/{id}/{newStatus}', 'ApplicationController@updateApplicationStatus') + Route::patch('/update/{application}/{newStatus}', 'ApplicationController@updateApplicationStatus') ->name('updateApplicationStatus'); Route::delete('{application}/delete', 'ApplicationController@delete') @@ -78,7 +78,7 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ - Route::post('{id}/staff/vote', 'VoteController@vote') + Route::post('{application}/staff/vote', 'VoteController@vote') ->name('voteApplication'); @@ -86,10 +86,10 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ Route::group(['prefix' => 'appointments'], function (){ - Route::post('schedule/appointments/{applicationID}', 'AppointmentController@saveAppointment') + Route::post('schedule/appointments/{application}', 'AppointmentController@saveAppointment') ->name('scheduleAppointment'); - Route::patch('update/appointments/{applicationID}/{status}', 'AppointmentController@updateAppointment') + Route::patch('update/appointments/{application}/{status}', 'AppointmentController@updateAppointment') ->name('updateAppointment'); }); @@ -156,6 +156,8 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ Route::delete('players/unban/{user}', 'BanController@delete') ->name('unbanUser'); + + Route::delete('players/delete/{user}', 'UserController@delete') ->name('deleteUser'); @@ -178,7 +180,7 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ ->name('updatePosition'); - Route::patch('positions/availability/{status}/{id}', 'VacancyController@updatePositionAvailability') + Route::patch('positions/availability/{status}/{vacancy}', 'VacancyController@updatePositionAvailability') ->name('updatePositionAvailability'); @@ -214,5 +216,3 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){ }); }); - -//Route::get('/dashboard/login', '');