refactor: code style changes

Signed-off-by: miguel456 <me@nogueira.codes>
This commit is contained in:
Miguel Nogueira 2023-01-15 00:04:00 +00:00
parent 25155bff2e
commit 3727c84f3e
No known key found for this signature in database
GPG Key ID: 3C6A7E29AF26D370
146 changed files with 1013 additions and 1341 deletions

View File

@ -20,7 +20,7 @@ class Absence extends Model
'reason',
'status',
'reviewer',
'reviewed_date'
'reviewed_date',
];
public function requester(): BelongsTo
@ -28,7 +28,6 @@ class Absence extends Model
return $this->belongsTo('App\User', 'requesterID', 'id');
}
/**
* Determines whether this model can be setApproved(), setDeclined() or setCancelled()
*
@ -37,63 +36,61 @@ class Absence extends Model
*/
public function isActionable(bool $toCancel = false): bool
{
if ($toCancel)
{
if ($toCancel) {
return in_array($this->getRawOriginal('status'), ['PENDING', 'APPROVED']);
}
return $this->getRawOriginal('status') == 'PENDING';
}
/**
* Sets the Absence's status as approved
*
* @return Absence
*
* @throws AbsenceNotActionableException
*/
public function setApproved(): Absence
{
if ($this->isActionable())
{
if ($this->isActionable()) {
return tap($this)->update([
'status' => 'APPROVED'
'status' => 'APPROVED',
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as declined
*
* @return Absence
*
* @throws AbsenceNotActionableException
*/
public function setDeclined(): Absence
{
if ($this->isActionable()) {
return tap($this)->update([
'status' => 'DECLINED'
'status' => 'DECLINED',
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as cancelled
*
* @return Absence
*
* @throws AbsenceNotActionableException Thrown when the switch to this status would be invalid
*/
public function setCancelled(): Absence
{
if ($this->isActionable(true)) {
return tap($this)->update([
'status' => 'CANCELLED'
'status' => 'CANCELLED',
]);
}
@ -108,18 +105,16 @@ class Absence extends Model
public function setEnded(): Absence
{
return tap($this)->update([
'status' => 'ENDED'
'status' => 'ENDED',
]);
}
// Look out when retrieving this value;
//If you need the unaltered version of it, either adapt to its formatting or call getRawOriginal()
protected function status(): Attribute {
protected function status(): Attribute
{
return Attribute::make(
get: fn ($value) => ucfirst(strtolower($value))
);
}
}

View File

@ -64,5 +64,4 @@ class Application extends Model
'applicationStatus' => $status,
]);
}
}

View File

@ -39,14 +39,11 @@ class Install extends Command
public function handle()
{
$basePath = base_path();
if (Storage::disk('local')->missing('INSTALLED'))
{
if (Storage::disk('local')->missing('INSTALLED')) {
$this->info('[!! Welcome to Rasberry Teams !!]');
$this->info('>> Installing...');
$this->call('down', [
'--message' => 'Down for maintenance. We\'ll be right back!'
'--message' => 'Down for maintenance. We\'ll be right back!',
]);
copy($basePath.'/.env.example', $basePath.'/.env');
@ -63,22 +60,17 @@ class Install extends Command
exec('cd '.$basePath.' && npm install --silent', $npmBuildOut, $npmOut);
exec('cd '.$basePath.'&& npm run dev --silent', $npmBuildMessages, $npmBuildOut);
if($npmOut !== 0 && $npmBuildOut !== 0)
{
if ($npmOut !== 0 && $npmBuildOut !== 0) {
$this->error('[!] One or more errors have ocurred whilst attempting to install dependencies.');
$this->error('[!] It is recommended to run this command again, and report a bug if it keeps happening.');
return false;
}
$settings = [];
$this->info('>> Configuring application - We\'re going to ask a few questions here!');
do
{
do {
$this->info('== Database Settings (1/6) ==');
$settings['DB_USERNAME'] = $this->ask('Database username');
@ -108,15 +100,12 @@ class Install extends Command
$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.'));
foreach($settings as $keyname => $value)
{
foreach ($settings as $keyname => $value) {
$this->call('environment:modify', [
'key' => $keyname,
'value' => $value
'value' => $value,
]);
}
@ -131,10 +120,7 @@ class Install extends Command
$this->call('up');
$this->info('>> All done! Visit '.$basePath.' to start using your brand new installation of Raspberry Teams!');
}
else
{
} else {
$this->error('[!] The application is already installed!');
}
}

View File

@ -52,6 +52,7 @@ class SetEnv extends Command
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()

View File

@ -23,7 +23,6 @@ namespace App\CustomFacades;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class IP
{
@ -31,14 +30,14 @@ class IP
// For views, this is in a service provider, and is shared with all of them
/**
* Determines whether you should collect/display IP addresses in the app.
*
* @return bool Whether you should collect/display IPs, in the context in which this is called
*/
public function shouldCollect(): bool
{
// should collect or display IPs?
if (config('demo.is_enabled') || config('app.hide_ips'))
{
if (config('demo.is_enabled') || config('app.hide_ips')) {
return false; // do not collect!
}
@ -47,6 +46,7 @@ class IP
/**
* Looks up information on a specified IP address. Caches results automatically.
*
* @param string $IP IP address to lookup
* @return object
*/
@ -58,19 +58,17 @@ class IP
];
if ($this->shouldCollect()) {
return json_decode(Cache::remember($IP, 3600, function () use ($IP) {
return Http::get(config('general.urls.ipapi.ipcheck'), [
'apiKey' => config('general.keys.ipapi.apikey'),
'ip' => $IP,
])->body();
}));
}
return new class {
public $message = "This feature is disabled.";
return new class
{
public $message = 'This feature is disabled.';
};
}
}

View File

@ -2,7 +2,6 @@
namespace App\Exceptions;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class ApplicationNotFoundException extends ModelNotFoundException

View File

@ -2,7 +2,6 @@
namespace App\Exceptions;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class VacancyNotFoundException extends ModelNotFoundException

View File

@ -1,17 +1,13 @@
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class DigitalStorageHelper extends Facade
{
protected static function getFacadeAccessor()
{
return 'digitalStorageHelperFacadeRoot';
}
}

View File

@ -1,17 +1,13 @@
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class JSON extends Facade
{
protected static function getFacadeAccessor()
{
return 'json';
}
}

View File

@ -28,6 +28,7 @@ class ContextAwareValidator
{
/**
* The excludedNames array will make the validator ignore any of these names when including names into the rules.
*
* @var array
*/
private $excludedNames = [

View File

@ -1,5 +1,6 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);
namespace App\Helpers;
@ -10,18 +11,16 @@ namespace App\Helpers;
* It should be used whenever you need to display a file's size in a human readable way.
*
* It's framework agnostic, meaning you can take it out of context and it'll still work; However, you'll have to instantiate it first.
* @package App\Helpers
*/
class DigitalStorageHelper
{
/**
* The digital storage value to be manipulated.
* @var $value
*
* @var
*/
protected $value;
/**
* Sets the digital storage value for manipulation.
*
@ -31,10 +30,10 @@ class DigitalStorageHelper
public function setValue(int $value): DigitalStorageHelper
{
$this->value = $value;
return $this;
}
/**
* Converts the digital storage value to kilobytes.
*
@ -45,7 +44,6 @@ class DigitalStorageHelper
return $this->value / 1000;
}
/**
* Converts the digital storage value to megabytes.
*
@ -56,7 +54,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 6)); // 1 times 10 to the power of 6
}
/**
* Convert the digital storage value to gigabytes. Might be an approximation
*
@ -67,7 +64,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 9));
}
/**
* Convert the digital storage value to terabytes.
*
@ -78,7 +74,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 12));
}
/**
* Format the digital storage value to one of the units: b, kb, mb, gb and tb.
* The method has been adapted to use both MiB and MB values.
@ -86,14 +81,16 @@ class DigitalStorageHelper
* @param int $precision The rounding precision
* @param bool $si Use international system units. Defaults to false
* @return string The human readable digital storage value, in either, for instance, MB or MiB
*
* @see https://stackoverflow.com/a/2510459/11540218 StackOverflow question regarding unit conversion
* @since 7.3.23
*/
public function formatBytes($precision = 2, $si = false): string
{
$units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
if ($si)
if ($si) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
}
$bytes = max($this->value, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(($si) ? 1000 : 1024));
@ -103,5 +100,4 @@ class DigitalStorageHelper
return round($bytes, $precision).' '.$units[$pow];
}
}

View File

@ -19,30 +19,25 @@
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Helpers;
use App\Exceptions\AccountNotLinkedException;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Http;
// Small wrapper for the necessary sections of the Discord API; A library is overkill here
class Discord
{
/**
* The current working guild. Default is Home guild from app config
*
* @var string
*/
protected string $workingGuild;
/**
* Current user.
*
@ -50,15 +45,13 @@ class Discord
*/
protected User $user;
public function __construct() {
public function __construct()
{
if (isset($this->workingGuild)) {
$this->setWorkingGuild(config('services.discord.home_guild'));
}
}
/**
* Sets the working guild
*
@ -68,6 +61,7 @@ class Discord
public function setWorkingGuild(string $workingGuild): Discord
{
$this->workingGuild = $workingGuild;
return $this;
}
@ -76,12 +70,14 @@ class Discord
*
* @param User $user
* @return Discord
*
* @throws AccountNotLinkedException
*/
public function setUser(User $user): Discord
{
if ($user->hasDiscordConnection()) {
$this->user = $user;
return $this;
}
@ -93,14 +89,14 @@ class Discord
* preventing unnecessary API requests.
*
* @return object Current user's authentication info (has no sensitive fields)
*
* @throws RequestException
*/
public function getAuthorizationInfo(): object {
public function getAuthorizationInfo(): object
{
if (Cache::has($this->user->discord_user_id)) {
return unserialize(Cache::get($this->user->discord_user_id));
}
else {
} else {
$authInfo = (object) Http::withToken($this->user->discord_token)
->get(config('services.discord.base_url').'/oauth2/@me')
->throw()
@ -112,42 +108,41 @@ class Discord
}
}
/**
* Checks if the user's token is close to expiring.
* Tokens should be refreshed the day before they expire.
*
* @return bool Whether the user's token needs to be refreshed
*
* @throws RequestException
*/
public function needsRefresh(): bool {
public function needsRefresh(): bool
{
return Carbon::parse($this->getAuthorizationInfo()->expires)->diffInDays() == 1;
}
public function exchangeRefreshToken() {
public function exchangeRefreshToken()
{
}
/**
* Adds current working user to current working guild. Bot must be member of target guild, and account must be linked
*
* @return object|bool A GuildMember object; false if member is already in guild
*
* @throws RequestException Any client and server errors
*
* @see https://discord.com/developers/docs/resources/guild#guild-member-object
*/
public function addGuildMember(): object|bool
{
$params = [
'access_token' => $this->user->discord_token
'access_token' => $this->user->discord_token,
];
$member = Http::withBody(json_encode($params), 'application/json')
->withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token')
'Authorization' => 'Bot '.config('services.discord.token'),
])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/members/{$this->user->discord_user_id}")
->throw();
@ -158,20 +153,21 @@ class Discord
}
}
/**
* Bans a specified user from the guild.
* May be called from the suspension service optionally by the banning user
*
* @param string $reason The reason to supply Discord with
* @return void Nothing on success
*
* @throws RequestException
* @throws AccountNotLinkedException
*/
public function addGuildBan(string $reason): void {
public function addGuildBan(string $reason): void
{
Http::withHeaders([
'Authorization' => 'Bot '.config('services.discord.token'),
'X-Audit-Log-Reason' => $reason
'X-Audit-Log-Reason' => $reason,
])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
->throw();
@ -181,19 +177,21 @@ class Discord
/**
* @param string $reason The removal reason to provide Discord with (e.g. ban expired)
* @return null|bool Null on unnan, false if user is not banned
*
* @throws RequestException
*/
public function removeGuildBan(string $reason): null|bool {
public function removeGuildBan(string $reason): null|bool
{
if ($this->getGuildBan($this->user)) {
Http::withHeaders([
'Authorization' => 'Bot '.config('services.discord.token'),
'X-Audit-Log-Reason' => $reason
'X-Audit-Log-Reason' => $reason,
])->delete(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
->throw();
return null;
}
return false;
}
@ -201,13 +199,15 @@ class Discord
* Gets (possible) ban for current user.
*
* @return object|bool Ban object if user is banned. Null
*
* @throws RequestException
*
* @see https://discord.com/developers/docs/resources/guild#ban-object
*/
public function getGuildBan(): object|bool
{
$ban = Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token')
'Authorization' => 'Bot '.config('services.discord.token'),
])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}");
if ($ban->status() == 404) {
@ -217,20 +217,21 @@ class Discord
return ($ban->successful()) ? (object) $ban->json() : $ban->throwIf($ban->status() !== 404);
}
/**
* Retrieves list of Role objects
*
* @see https://discord.com/developers/docs/topics/permissions#role-object
*
* @return array List of role objects
*
* @throws RequestException
*/
public function getGuildRoles(): array {
public function getGuildRoles(): array
{
return Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token')
'Authorization' => 'Bot '.config('services.discord.token'),
])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/roles")
->throw()
->json();
}
}

View File

@ -1,16 +1,23 @@
<?php
namespace App\Helpers;
/**
* Class JSON - Used for JSON responses.
* @package App\Helpers
*/
class JSON
{
protected $type;
protected $type, $status, $message, $code, $data, $additional;
protected $status;
protected $message;
protected $code;
protected $data;
protected $additional;
/**
* @param mixed $type
@ -18,6 +25,7 @@ class JSON
public function setResponseType($type): JSON
{
$this->type = $type;
return $this;
}
@ -27,6 +35,7 @@ class JSON
public function setAdditional($additional)
{
$this->additional = $additional;
return $this;
}
@ -61,6 +70,7 @@ class JSON
public function setStatus($status)
{
$this->status = $status;
return $this;
}
@ -79,6 +89,7 @@ class JSON
public function setMessage($message)
{
$this->message = $message;
return $this;
}
@ -97,6 +108,7 @@ class JSON
public function setCode($code)
{
$this->code = $code;
return $this;
}
@ -115,6 +127,7 @@ class JSON
public function setData($data)
{
$this->data = $data;
return $this;
}
@ -126,17 +139,15 @@ class JSON
'meta' => [
'status' => $this->getStatus(),
'message' => $this->getMessage(),
]
],
];
if (!empty($this->additional))
{
foreach($this->additional as $additionalKeyName => $key)
{
if (! empty($this->additional)) {
foreach ($this->additional as $additionalKeyName => $key) {
$response[$additionalKeyName] = $key;
}
}
return response($response, $this->getCode(), $headers);
}
}

View File

@ -33,30 +33,28 @@ use Illuminate\Support\Facades\Log;
*/
class Options
{
/**
* Returns an assortment of settings found in the mentioned category
*
* @param string $category The category
* @return Collection The settings in this category
*
* @throws EmptyOptionsException
*/
public function getCategory(string $category): Collection
{
$options = Option::where('option_category', $category)->get();
if ($options->isEmpty())
{
if ($options->isEmpty()) {
throw new EmptyOptionsException('There are no options in category '.$category);
}
return $options;
}
public function getOption(string $option): string
{
$value = Cache::get($option);
if (is_null($value)) {
Log::debug('Option '.$option.'not found in cache, refreshing from database');
$value = Option::where('option_name', $option)->first();
@ -79,7 +77,7 @@ class Options
'option_name' => $option,
'option_value' => $value,
'friendly_name' => $description,
'option_category' => $category
'option_category' => $category,
]);
Cache::put($option, $value, now()->addDay());

View File

@ -5,24 +5,20 @@ namespace App\Http\Controllers;
use App\Absence;
use App\Exceptions\AbsenceNotActionableException;
use App\Http\Requests\StoreAbsenceRequest;
use App\Http\Requests\UpdateAbsenceRequest;
use App\Services\AbsenceService;
use App\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
class AbsenceController extends Controller
{
private AbsenceService $absenceService;
public function __construct (AbsenceService $absenceService) {
public function __construct(AbsenceService $absenceService)
{
$this->absenceService = $absenceService;
}
/**
@ -38,11 +34,11 @@ class AbsenceController extends Controller
->with('absences', Absence::paginate(6));
}
/**
* Display a listing of absences belonging to the current user.
*
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws AuthorizationException
*/
public function showUserAbsences()
@ -54,11 +50,8 @@ class AbsenceController extends Controller
return view('dashboard.absences.own')
->with('absences', $absences);
}
/**
* Show the form for creating a new absence request.
*
@ -99,6 +92,7 @@ class AbsenceController extends Controller
* Display the specified absence request.
*
* @param \App\Absence $absence
*
* @throws AuthorizationException
*/
public function show(Absence $absence)
@ -108,7 +102,7 @@ class AbsenceController extends Controller
return view('dashboard.absences.view')
->with([
'absence' => $absence,
'totalDays' => Carbon::parse($absence->start)->diffInDays($absence->predicted_end)
'totalDays' => Carbon::parse($absence->start)->diffInDays($absence->predicted_end),
]);
}
@ -117,18 +111,16 @@ class AbsenceController extends Controller
*
* @param Absence $absence
* @return RedirectResponse
*
* @throws AuthorizationException
*/
public function approveAbsence(Absence $absence): RedirectResponse
{
$this->authorize('approve', $absence);
try
{
try {
$this->absenceService->approveAbsence($absence);
}
catch (AbsenceNotActionableException $notActionableException)
{
} catch (AbsenceNotActionableException $notActionableException) {
return redirect()
->back()
->with('error', $notActionableException->getMessage());
@ -139,23 +131,21 @@ class AbsenceController extends Controller
->with('success', __('Absence request successfully approved. It will automatically transition to "Ended" on its predicted end date.'));
}
/**
* Decline the specified absence.
*
* @param Absence $absence
* @return RedirectResponse
*
* @throws AuthorizationException
*/
public function declineAbsence(Absence $absence): RedirectResponse
{
$this->authorize('decline', $absence);
try
{
try {
$this->absenceService->declineAbsence($absence);
} catch (AbsenceNotActionableException $notActionableException)
{
} catch (AbsenceNotActionableException $notActionableException) {
return redirect()
->back()
->with('error', $notActionableException->getMessage());
@ -166,24 +156,21 @@ class AbsenceController extends Controller
->with('success', __('Absence request successfully declined.'));
}
/**
* Cancel the specified absence.
*
* @param Absence $absence
* @return \Illuminate\Http\RedirectResponse
*
* @throws AuthorizationException
*/
public function cancelAbsence(Absence $absence): \Illuminate\Http\RedirectResponse
public function cancelAbsence(Absence $absence): RedirectResponse
{
$this->authorize('cancel', $absence);
try
{
try {
$this->absenceService->cancelAbsence($absence);
}
catch (AbsenceNotActionableException $notActionableException)
{
} catch (AbsenceNotActionableException $notActionableException) {
return redirect()
->back()
->with('error', $notActionableException->getMessage());

View File

@ -29,23 +29,19 @@ use App\Exceptions\IncompleteApplicationException;
use App\Exceptions\InvalidAgeException;
use App\Exceptions\UnavailableApplicationException;
use App\Exceptions\VacancyNotFoundException;
use App\Facades\IP;
use App\Services\ApplicationService;
use App\Vacancy;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ApplicationController extends Controller
{
private $applicationService;
public function __construct(ApplicationService $applicationService) {
public function __construct(ApplicationService $applicationService)
{
$this->applicationService = $applicationService;
}
public function showUserApps()
{
return view('dashboard.user.applications')
@ -67,7 +63,6 @@ class ApplicationController extends Controller
'canVote' => $this->applicationService->canVote($application->votes),
]
);
}
public function showAllApps(Request $request)
@ -76,42 +71,36 @@ class ApplicationController extends Controller
return view('dashboard.appmanagement.all')
->with('applications', Application::orderBy('applicationStatus', 'ASC')->paginate(6));
}
public function discordApply(Request $request, $vacancySlug) {
public function discordApply(Request $request, $vacancySlug)
{
$request->session()->put('discordApplicationRedirectedSlug', $vacancySlug);
return redirect(route('discordRedirect'));
return redirect(route('discordRedirect'));
}
public function renderApplicationForm($vacancySlug)
{
try {
return $this->applicationService->renderForm($vacancySlug);
}
catch (ApplicationNotFoundException $ex) {
} catch (ApplicationNotFoundException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
} catch (DiscordAccountRequiredException $e) {
\Log::info('Redirecting user: '.$e->getMessage(), [
'user' => Auth::user()->email
'user' => Auth::user()->email,
]);
request()->session()->put('discordApplicationRedirectedSlug', $vacancySlug);
return redirect(route('discordRedirect'));
} catch (IncompatibleAgeException $e) {
return redirect()
->to(route('dashboard'))
->with('error', $e->getMessage());
} catch (InvalidAgeException $e) {
return view('dashboard.application-rendering.add-age');
}
}
@ -121,9 +110,7 @@ class ApplicationController extends Controller
if (Auth::user()->isEligible()) {
try {
$this->applicationService->fillForm(Auth::user(), $request->all(), $vacancySlug);
} catch (VacancyNotFoundException|IncompleteApplicationException|UnavailableApplicationException $e) {
return redirect()
->back()
->with('error', $e->getMessage());
@ -146,8 +133,7 @@ class ApplicationController extends Controller
try {
$status = $this->applicationService->updateStatus($application, $newStatus);
} catch (\LogicException $ex)
{
} catch (\LogicException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
@ -170,6 +156,5 @@ class ApplicationController extends Controller
return redirect()
->back()
->with('success', __('Application deleted. Comments, appointments and responses have also been deleted.'));
}
}

View File

@ -36,13 +36,12 @@ use Illuminate\Http\Request;
class AppointmentController extends Controller
{
private $appointmentService;
private $meetingNoteService;
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService) {
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService)
{
$this->appointmentService = $appointmentService;
$this->meetingNoteService = $meetingNoteService;
}
@ -71,10 +70,8 @@ class AppointmentController extends Controller
return redirect()
->back()
->with('success', __("Interview finished! Staff members can now vote on it."));
}
catch (InvalidAppointmentStatusException $ex) {
->with('success', __('Interview finished! Staff members can now vote on it.'));
} catch (InvalidAppointmentStatusException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
@ -86,35 +83,26 @@ class AppointmentController extends Controller
$this->authorize('update', $application->appointment);
try {
$this->appointmentService->deleteAppointment($application, $request->reason);
return redirect()
->back()
->with('success', __('Appointment cancelled.'));
}
catch (\Exception $ex) {
} catch (\Exception $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
}
}
public function saveNotes(SaveNotesRequest $request, Application $application)
{
try {
$this->meetingNoteService->addToApplication($application, $request->noteText);
return redirect()
->back()
->with('success', __('Saved notes.'));
} catch (InvalidAppointmentException $ex) {
return redirect()
->back()

View File

@ -21,46 +21,39 @@
namespace App\Http\Controllers\Auth;
use App\Facades\Discord;
use App\Facades\Options;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\InvalidStateException;
class DiscordController extends Controller
{
public function discordRedirect() {
public function discordRedirect()
{
return Socialite::driver('discord')
->scopes(['email', 'guilds.join', 'guilds.members.read', 'guilds'])
->redirect();
}
public function discordCallback() {
public function discordCallback()
{
try {
$discordUser = Socialite::driver('discord')->user();
} catch (InvalidStateException $stateException) {
Log::warning('Invalid state for social authentication: ', [
'message' => $stateException->getMessage(),
'ua' => request()->userAgent(),
'ip' => request()->ip()
'ip' => request()->ip(),
]);
return redirect(route('discordRedirect'));
}
$appUser = User::where('email', $discordUser->getEmail())->first();
if ($appUser) {
$appUser->discord_token = $discordUser->token;
$appUser->discord_refresh_token = $discordUser->refreshToken;
$appUser->discord_user_id = $discordUser->getId();
@ -68,9 +61,7 @@ class DiscordController extends Controller
$appUser->save();
Auth::login($appUser, true);
} else {
$oAuthUser = User::create([
'uuid' => null,
'name' => $discordUser->getName(),
@ -82,7 +73,7 @@ class DiscordController extends Controller
'discord_user_id' => $discordUser->getId(),
'discord_pfp' => $discordUser->getAvatar(),
'discord_token' => $discordUser->token,
'discord_refresh_token' => $discordUser->refreshToken
'discord_refresh_token' => $discordUser->refreshToken,
]);
$oAuthUser->assignRole('user');
@ -97,5 +88,4 @@ class DiscordController extends Controller
return redirect()
->route('dashboard');
}
}

View File

@ -21,17 +21,13 @@
namespace App\Http\Controllers\Auth;
use App\Facades\IP;
use App\Http\Controllers\Controller;
use App\Services\AccountSuspensionService;
use App\User;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use App\Facades\IP;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
class LoginController extends Controller
{
@ -79,12 +75,11 @@ class LoginController extends Controller
$isLocked = $service->isLocked($user);
if ($isBanned || $isLocked) {
Log::alert('Restricted user attempting to login.', [
'ip' => $request->ip(),
'email' => $user->email,
'isBanned' => $isBanned,
'isLocked' => $isLocked
'isLocked' => $isLocked,
]);
return false;
@ -99,17 +94,14 @@ class LoginController extends Controller
public function authenticated(Request $request, User $user)
{
if (IP::shouldCollect()) {
if ($user->originalIP !== $request->ip())
{
if ($user->originalIP !== $request->ip()) {
Log::alert('User IP address changed from last login. Updating.', [
'prev' => $user->originalIP,
'new' => $request->ip()
'new' => $request->ip(),
]);
$user->currentIp = $request->ip();
$user->save();
}
}
}
}

View File

@ -21,15 +21,12 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Profile;
use App\Services\AccountSuspensionService;
use App\User;
use App\Facades\Options;
use App\Facades\IP;
use App\Facades\Options;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
@ -74,8 +71,7 @@ class RegisterController extends Controller
{
$password = ['required', 'string', 'confirmed'];
switch (Options::getOption('pw_security_policy'))
{ // this could be better structured, switch doesn't feel right
switch (Options::getOption('pw_security_policy')) { // this could be better structured, switch doesn't feel right
case 'off':
$password = ['required', 'string', 'confirmed'];
break;
@ -102,7 +98,7 @@ class RegisterController extends Controller
'dob.before' => __('You must be 13 years of age or older in order to sign up for an account.'),
'dob.required' => __('Please enter your date of birth.'),
'uuid.required' => __('Please enter a valid (and Premium) Minecraft username! We do not support cracked users.'),
'acceptTerms.required' => __('Please accept the Community Guidelines, Terms of Service and Privacy Policy to continue.')
'acceptTerms.required' => __('Please accept the Community Guidelines, Terms of Service and Privacy Policy to continue.'),
]);
}
@ -117,13 +113,13 @@ class RegisterController extends Controller
$ip = IP::shouldCollect() ? request()->ip() : '0.0.0.0';
$user = User::create([
'uuid' => $data['uuid'] ?? "disabled",
'uuid' => $data['uuid'] ?? 'disabled',
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'registrationIp' => $ip,
'currentIp' => $ip,
'dob' => $data['dob']
'dob' => $data['dob'],
]);
$user->assignRole('user');

View File

@ -26,13 +26,13 @@ use App\Comment;
use App\Http\Requests\NewCommentRequest;
use App\Services\CommentService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CommentController extends Controller
{
private $commentService;
public function __construct(CommentService $commentService) {
public function __construct(CommentService $commentService)
{
$this->commentService = $commentService;
}

View File

@ -39,12 +39,12 @@ class DashboardController extends Controller
$totalDeniedSingle = Application::where([
['applicationStatus', '=', 'DENIED'],
['applicantUserID', '=', Auth::user()->id]
['applicantUserID', '=', Auth::user()->id],
])->get();
$totalNewSingle = Application::where([
['applicationStatus', '=', 'STAGE_SUBMITTED'],
['applicantUserID', '=', Auth::user()->id]
['applicantUserID', '=', Auth::user()->id],
])->get();
return view('dashboard.dashboard')
@ -55,7 +55,7 @@ class DashboardController extends Controller
'totalPeerReview' => $totalPeerReview,
'totalNewApplications' => $totalNewApplications,
'totalNewSingle' => $totalNewSingle->count(),
'totalDeniedSingle' => $totalDeniedSingle->count()
'totalDeniedSingle' => $totalDeniedSingle->count(),
]);
}
}

View File

@ -33,17 +33,20 @@ use Illuminate\Support\Facades\Log;
class DevToolsController extends Controller
{
public function __construct() {
public function __construct()
{
//
}
private function singleAuthorise() {
private function singleAuthorise()
{
if (! Auth::user()->can('admin.developertools.use')) {
abort(403, __('You\'re not authorized to access this page.'));
}
}
public function index() {
public function index()
{
$this->singleAuthorise();
return view('dashboard.administration.devtools')
@ -54,7 +57,8 @@ class DevToolsController extends Controller
/**
* Force an application to be approved.
*/
public function forceApprovalEvent(Request $request) {
public function forceApprovalEvent(Request $request)
{
$this->singleAuthorise();
$application = Application::find($request->application);
@ -80,20 +84,19 @@ class DevToolsController extends Controller
->with('success', __('Event dispatched; Candidate rejection sequence initiated.'));
}
public function evaluateVotes() {
public function evaluateVotes()
{
$this->singleAuthorise();
$code = Artisan::call("votes:evaluate");
$code = Artisan::call('votes:evaluate');
return redirect()
->back()
->with('success', __('Ran vote evaluation logic, with exit code :exitCode ', ['exitCode' => $code]));
}
public function purgeSuspensions(AccountSuspensionService $service) {
public function purgeSuspensions(AccountSuspensionService $service)
{
$this->singleAuthorise();
if ($service->purgeExpired()) {
@ -105,7 +108,6 @@ class DevToolsController extends Controller
return redirect()
->back()
->with('error', __('There were no expired suspensions (or no suspensions at all) to purge.'));
}
public function endAbsencesNow(AbsenceService $service)

View File

@ -25,14 +25,14 @@ use App\Exceptions\EmptyFormException;
use App\Exceptions\FormHasConstraintsException;
use App\Form;
use App\Services\FormManagementService;
use ContextAwareValidator;
use Illuminate\Http\Request;
class FormController extends Controller
{
private $formService;
public function __construct(FormManagementService $formService) {
public function __construct(FormManagementService $formService)
{
$this->formService = $formService;
}
@ -56,17 +56,14 @@ class FormController extends Controller
{
try {
$form = $this->formService->addForm($request->all());
}
catch (EmptyFormException $ex)
{
} catch (EmptyFormException $ex) {
return redirect()
->back()
->with('exception', $ex->getMessage());
}
// Form is boolean or array
if ($form)
{
if ($form) {
return redirect()
->back()
->with('success', __('Form created!'));
@ -81,18 +78,15 @@ class FormController extends Controller
{
$this->authorize('delete', $form);
try {
$this->formService->deleteForm($form);
return redirect()
->back()
->with('success', __('Form deleted successfuly'));
} catch (FormHasConstraintsException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
}
}

View File

@ -24,20 +24,17 @@ namespace App\Http\Controllers;
use App\Exceptions\InvalidGamePreferenceException;
use App\Exceptions\OptionNotFoundException;
use App\Facades\Options;
use App\Options as Option;
use App\Services\ConfigurationService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class OptionsController extends Controller
{
private $configurationService;
public function __construct(ConfigurationService $configurationService) {
public function __construct(ConfigurationService $configurationService)
{
$this->configurationService = $configurationService;
}
/**
@ -56,16 +53,15 @@ class OptionsController extends Controller
'graceperiod' => Options::getOption('graceperiod'),
'pwExpiry' => Options::getOption('password_expiry'),
'requiresPMC' => Options::getOption('requireGameLicense'),
'enforce2fa' => Options::getOption('force2fa')
'enforce2fa' => Options::getOption('force2fa'),
],
'currentGame' => Options::getOption('currentGame')
'currentGame' => Options::getOption('currentGame'),
]);
}
public function saveSettings(Request $request): \Illuminate\Http\RedirectResponse
{
try {
if (Auth::user()->can('admin.settings.edit')) {
$this->configurationService->saveConfiguration($request->all());
@ -73,13 +69,10 @@ class OptionsController extends Controller
->back()
->with('success', __('Options updated successfully!'));
}
} catch (OptionNotFoundException|\Exception $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
}
return redirect()
@ -90,12 +83,11 @@ class OptionsController extends Controller
public function saveGameIntegration(Request $request)
{
try {
$this->configurationService->saveGameIntegration($request->gamePref);
return redirect()
->back()
->with('success', __('Game preference updated.'));
} catch (InvalidGamePreferenceException $ex) {
return redirect()
->back()

View File

@ -21,8 +21,6 @@
namespace App\Http\Controllers;
use App\Exceptions\ProfileAlreadyExistsException;
use App\Exceptions\ProfileCreationFailedException;
use App\Exceptions\ProfileNotFoundException;
use App\Facades\IP;
use App\Http\Requests\ProfileSave;
@ -32,13 +30,13 @@ use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Spatie\Permission\Models\Role;
class ProfileController extends Controller
{
private ProfileService $profileService;
public function __construct(ProfileService $profileService) {
public function __construct(ProfileService $profileService)
{
$this->profileService = $profileService;
}
@ -60,27 +58,22 @@ class ProfileController extends Controller
public function showSingleProfile(AccountSuspensionService $accountSuspensionService, User $user)
{
if (is_null($user->profile)) {
return redirect()
->back()
->with('error', "This user doesn't have a profile.");
}
$socialMediaProfiles = json_decode($user->profile->socialLinks, true);
$createdDate = Carbon::parse($user->created_at);
$suspensionInfo = null;
if ($accountSuspensionService->isSuspended($user))
{
if ($accountSuspensionService->isSuspended($user)) {
$suspensionInfo = [
'isPermanent' => $user->bans->isPermanent,
'reason' => $user->bans->reason,
'bannedUntil' => $user->bans->bannedUntil
'bannedUntil' => $user->bans->bannedUntil,
];
}
@ -94,7 +87,7 @@ class ProfileController extends Controller
'discord' => $socialMediaProfiles['links']['discord'] ?? 'UpdateMe#12345',
'since' => $createdDate->englishMonth.' '.$createdDate->year,
'ipInfo' => IP::lookup($user->currentIp),
'suspensionInfo' => $suspensionInfo
'suspensionInfo' => $suspensionInfo,
]);
} else {
abort(403, __('You cannot view someone else\'s profile.'));
@ -104,23 +97,20 @@ class ProfileController extends Controller
public function saveProfile(ProfileSave $request)
{
$this->profileService->updateProfile(Auth::user()->id, $request);
return redirect()
->back()
->with('success', __('Profile updated.'));
}
public function createProfile(Request $request)
{
try {
$this->profileService->createProfile($request->user());
} catch (\Exception $e) {
return redirect()
->back()
->with('error', $e->getMessage());
}
return redirect()
@ -128,24 +118,18 @@ class ProfileController extends Controller
->with('success', __('Your profile has been created.'));
}
public function deleteProfile(Request $request)
{
try {
$this->profileService->deleteProfile($request->user());
} catch (ProfileNotFoundException $e) {
return redirect()
->back()
->with('error', $e->getMessage());
}
return redirect()
->back()
->with('success', __('Profile deleted successfully.'));
}
}

View File

@ -2,19 +2,15 @@
namespace App\Http\Controllers;
use App\Facades\Options;
use App\Http\Requests\SaveSecuritySettings;
use App\Services\SecuritySettingsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use function PHPSTORM_META\map;
class SecuritySettingsController extends Controller
{
private $securityService;
public function __construct(SecuritySettingsService $securityService) {
public function __construct(SecuritySettingsService $securityService)
{
$this->securityService = $securityService;
}
@ -24,12 +20,11 @@ class SecuritySettingsController extends Controller
'graceperiod' => $request->graceperiod,
'pwExpiry' => $request->pwExpiry,
'enforce2fa' => $request->enforce2fa,
'requirePMC' => $request->requirePMC
'requirePMC' => $request->requirePMC,
]);
return redirect()
->back()
->with('success', __('Settings saved.'));
}
}

View File

@ -27,7 +27,6 @@ use App\Exceptions\UserAlreadyInvitedException;
use App\Http\Requests\EditTeamRequest;
use App\Http\Requests\NewTeamRequest;
use App\Http\Requests\SendInviteRequest;
use App\Mail\InviteToTeam;
use App\Services\TeamService;
use App\Team;
use App\User;
@ -35,22 +34,19 @@ use App\Vacancy;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Mpociot\Teamwork\Exceptions\UserNotInTeamException;
use Mpociot\Teamwork\Facades\Teamwork;
use Mpociot\Teamwork\TeamInvite;
class TeamController extends Controller
{
private $teamService;
public function __construct(TeamService $teamService) {
public function __construct(TeamService $teamService)
{
$this->teamService = $teamService;
}
/**
* Display a listing of the resource.
*
*/
public function index()
{
@ -67,6 +63,7 @@ class TeamController extends Controller
*
* @param NewTeamRequest $request
* @return RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(NewTeamRequest $request)
@ -84,16 +81,18 @@ class TeamController extends Controller
*
* @param Team $team
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function edit(Team $team)
{
$this->authorize('update', $team);
return view('dashboard.teams.edit-team')
->with([
'team' => $team,
'users' => User::all(),
'vacancies' => Vacancy::with('teams')->get()->all()
'vacancies' => Vacancy::with('teams')->get()->all(),
]);
}
@ -103,6 +102,7 @@ class TeamController extends Controller
* @param EditTeamRequest $request
* @param Team $team
* @return RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(EditTeamRequest $request, Team $team): RedirectResponse
@ -110,7 +110,6 @@ class TeamController extends Controller
$this->authorize('update', $team);
$team = $this->teamService->updateTeam($team, $request->teamDescription, $request->joinType);
if ($team) {
return redirect()
->to(route('teams.index'))
@ -138,13 +137,11 @@ class TeamController extends Controller
$this->authorize('invite', $team);
try {
$this->teamService->inviteUser($team, $request->user);
return redirect()
->back()
->with('success', __('User invited successfully!'));
} catch (UserAlreadyInvitedException|PublicTeamInviteException $ex) {
return redirect()
->back()
@ -155,19 +152,15 @@ class TeamController extends Controller
public function processInviteAction(Request $request, $action, $token): RedirectResponse
{
try {
$this->teamService->processInvite(Auth::user(), $action, $token);
return redirect()
->to(route('teams.index'))
->with('success', __('Invite processed successfully!'));
} catch (InvalidInviteException $e) {
return redirect()
->back()
->with('error', $e->getMessage());
}
}

View File

@ -4,31 +4,23 @@ namespace App\Http\Controllers;
// Most of these namespaces have no effect on the code, however, they're used by IDEs so they can resolve return types and for PHPDocumentor as well
use App\Exceptions\FileUploadException;
use App\Http\Requests\UploadFileRequest;
use App\Services\TeamFileService;
use App\TeamFile;
use App\Http\Requests\UploadFileRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
// Documentation-purpose namespaces
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
// Documentation-purpose namespaces
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
class TeamFileController extends Controller
{
private $fileService;
public function __construct(TeamFileService $fileService) {
public function __construct(TeamFileService $fileService)
{
$this->fileService = $fileService;
}
@ -41,9 +33,9 @@ class TeamFileController extends Controller
{
$this->authorize('index', TeamFile::class);
if (is_null(Auth::user()->currentTeam))
{
if (is_null(Auth::user()->currentTeam)) {
$request->session()->flash('error', __('Please choose a team before viewing it\'s files.'));
return redirect()->to(route('teams.index'));
}
@ -51,7 +43,6 @@ class TeamFileController extends Controller
->with('files', TeamFile::with('team', 'uploader')->paginate(6));
}
/**
* Store a newly created resource in storage.
*
@ -62,8 +53,7 @@ class TeamFileController extends Controller
{
$this->authorize('store', TeamFile::class);
if (config('demo.is_enabled'))
{
if (config('demo.is_enabled')) {
return redirect()
->back()
->with('error', __('This feature is disabled'));
@ -78,31 +68,23 @@ class TeamFileController extends Controller
return redirect()
->back()
->with('success', __('File uploaded successfully.'));
} catch (FileUploadException $uploadException) {
return redirect()
->back()
->with('error', $uploadException->getMessage());
}
}
public function download(Request $request, TeamFile $teamFile)
{
$this->authorize('download', TeamFile::class);
try
{
try {
return Storage::download($teamFile->fs_location, $teamFile->name);
}
catch (FileNotFoundException $ex)
{
} catch (FileNotFoundException $ex) {
$request->session()->flash('error', __('Sorry, but the requested file could not be found in storage. Sometimes, files may be physically deleted by admins, but not from the app\'s database.'));
return redirect()->back();
return redirect()->back();
}
}
@ -117,22 +99,18 @@ class TeamFileController extends Controller
{
$this->authorize('delete', $teamFile);
if (config('demo.is_enabled'))
{
if (config('demo.is_enabled')) {
return redirect()
->back()
->with('error', __('This feature is disabled'));
}
try
{
try {
Storage::delete($teamFile->fs_location);
$teamFile->delete();
$request->session()->flash('success', __('File deleted successfully.'));
}
catch (\Exception $ex)
{
} catch (\Exception $ex) {
$request->session()->flash('error', __('There was an error deleting the file: :msg', ['msg' => $ex->getMessage()]));
}

View File

@ -22,7 +22,6 @@
namespace App\Http\Controllers;
use App\Ban;
use App\Facades\IP;
use App\Facades\Options;
use App\Http\Requests\Add2FASecretRequest;
use App\Http\Requests\AddDobRequest;
@ -44,7 +43,6 @@ use App\Services\AccountSuspensionService;
use App\Services\DiscordService;
use App\Traits\DisablesFeatures;
use App\Traits\HandlesAccountDeletion;
use App\Traits\ReceivesAccountTokens;
use App\User;
use Google2FA;
use Illuminate\Contracts\Foundation\Application;
@ -61,11 +59,11 @@ class UserController extends Controller
{
use HandlesAccountDeletion, DisablesFeatures;
/**
* Shows list of users
*
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function showUsers()
@ -80,13 +78,14 @@ class UserController extends Controller
]);
}
/**
* Searches for a player with the given search query.
*
* @deprecated Until Algolia implementation
*
* @param SearchPlayerRequest $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function showPlayersLike(SearchPlayerRequest $request)
@ -115,12 +114,12 @@ class UserController extends Controller
}
}
/**
* Shows the user account's settings page
*
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
@ -149,7 +148,6 @@ class UserController extends Controller
->with('twofaQRCode', $QRCode);
}
/**
* Show account management screen
*
@ -157,11 +155,11 @@ class UserController extends Controller
* @param Request $request
* @param User $user
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function showAcocuntManagement(AccountSuspensionService $suspensionService, Request $request, User $user)
{
$this->authorize('adminEdit', $user);
$systemRoles = Role::all()->pluck('name')->all();
@ -190,7 +188,7 @@ class UserController extends Controller
'suspensionReason' => $suspensionService->getSuspensionReason($user),
'suspensionDuration' => $suspensionService->getSuspensionDuration($user),
'has2FA' => $user->has2FA(),
'applications' => $user->applications()->get()
'applications' => $user->applications()->get(),
]);
}
@ -199,6 +197,7 @@ class UserController extends Controller
*
* @param FlushSessionsRequest $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function flushSessions(FlushSessionsRequest $request)
@ -219,8 +218,6 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Change the current user's password
*
@ -255,17 +252,15 @@ class UserController extends Controller
}
}
/**
* Sets a new password for the user.
*
* @param SetNewPasswordRequest $request
* @return Application|RedirectResponse|Redirector
*/
public function setPassword(SetNewPasswordRequest $request) {
public function setPassword(SetNewPasswordRequest $request)
{
if (! Auth::user()->hasPassword()) {
Auth::user()->password = Hash::make($request->newpass);
Auth::user()->save();
@ -281,7 +276,6 @@ class UserController extends Controller
->with('error', __('Your account already has a password.'));
}
/**
* Sets a user's password and removes their discord information from storage
*
@ -295,31 +289,30 @@ class UserController extends Controller
try {
$discordService->revokeAccountTokens(Auth::user());
Log::warning('Revoking social account tokens, user initiated', [
'user' => Auth::user()->email
'user' => Auth::user()->email,
]);
} catch (RequestException $requestException) {
if ($requestException->getCode() == 401) {
return redirect(route('discordRedirect'));
}
Log::error('Error while trying to revoke Discord credentials', [$requestException->getMessage()]);
return redirect()
->back()
->with('error', __('An unknown error ocurred. Please try again later.'));
}
$request->session()->flash('success', __('Discord account unlinked successfully. Link it again by re-authorizing the app with the same account in the login screen, or through your account settings.'));
return redirect()->back();
}
return redirect()
->back()
->with('error', __('Please set a password for your account first before trying to unlink Discord.'));
}
/**
* Change the current user's email address
*
@ -351,16 +344,16 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Removes the user's password and notifies them.
*
* @param User $user The user to remove the password for
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function forcePasswordReset(User $user) {
public function forcePasswordReset(User $user)
{
$this->authorize('adminEdit', $user);
if ($user->hasPassword()) {
@ -369,10 +362,9 @@ class UserController extends Controller
$user->password = null;
$user->save();
Log::alert("Removed account password", [
Log::alert('Removed account password', [
'target' => $user,
'actor' => Auth::user()
'actor' => Auth::user(),
]);
return redirect()
@ -385,15 +377,14 @@ class UserController extends Controller
->with('error', __('This user doesn\'t have a password to reset.'));
}
/**
* Adds a user's date of birth if they don't have one.
*
* @param AddDobRequest $request
* @return RedirectResponse
*/
public function addDob(AddDobRequest $request) {
public function addDob(AddDobRequest $request)
{
Auth::user()->dob = $request->dob;
Auth::user()->save();
@ -401,13 +392,13 @@ class UserController extends Controller
->back();
}
/**
* Delete the given user's account
*
* @param DeleteUserRequest $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function delete(DeleteUserRequest $request, User $user)
@ -426,13 +417,13 @@ class UserController extends Controller
return redirect()->route('registeredPlayerList');
}
/**
* Update a given user's details
*
* @param UpdateUserRequest $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateUserRequest $request, User $user)
@ -470,12 +461,12 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Generate and add a 2FA secret for the current user
*
* @param Add2FASecretRequest $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
@ -522,7 +513,6 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Remove the current user's two factor secret key
*
@ -544,7 +534,6 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Remove the given user's two factor secret key
*
@ -552,7 +541,8 @@ class UserController extends Controller
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*/
public function reset2FASecret(Reset2FASecretRequest $request, User $user) {
public function reset2FASecret(Reset2FASecretRequest $request, User $user)
{
// note: could invalidate other sessions for increased security
if ($user->has2FA()) {
Log::warning('SECURITY: Disabling two factor authentication (admin initiated)', [
@ -584,6 +574,7 @@ class UserController extends Controller
* @param BanUserRequest $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function suspend(AccountSuspensionService $suspensionService, BanUserRequest $request, User $user)
@ -591,17 +582,15 @@ class UserController extends Controller
$this->authorize('create', [Ban::class, $user]);
$this->disable();
if ($suspensionService->isSuspended($user))
{
if ($suspensionService->isSuspended($user)) {
return redirect()
->back()
->with('error', __('Account already suspended.'));
}
if ($request->suspensionType = "on") {
if ($request->suspensionType = 'on') {
$suspensionService->suspend($user, $request->reason, $request->duration);
}
else {
} else {
$suspensionService->suspend($user, $request->reason);
}
@ -615,6 +604,7 @@ class UserController extends Controller
* @param Request $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function unsuspend(AccountSuspensionService $suspensionService, Request $request, User $user)
@ -623,15 +613,12 @@ class UserController extends Controller
$this->disable();
if ($suspensionService->isSuspended($user)) {
$suspensionService->unsuspend($user);
$request->session()->flash('success', __('Account unsuspended successfully!'));
} else {
$request->session()->flash('error', __('This account isn\'t suspended!'));
}
return redirect()->back();
}
}

View File

@ -21,7 +21,6 @@
namespace App\Http\Controllers;
use App\Facades\JSON;
use App\Form;
use App\Http\Requests\VacancyEditRequest;
use App\Http\Requests\VacancyRequest;
@ -50,8 +49,6 @@ class VacancyController extends Controller
$messageIsError = false;
$this->authorize('create', Vacancy::class);
$form = Form::find($request->vacancyFormID);
if (! is_null($form)) {
@ -71,12 +68,11 @@ class VacancyController extends Controller
'vacancyFormID' => $request->vacancyFormID,
'vacancyCount' => $request->vacancyCount,
'requiresDiscord' => $request->requireDiscordAccount == 'on',
'requiredAge' => $request->requiredAge
'requiredAge' => $request->requiredAge,
]);
$message = __('Vacancy successfully opened. It will now show in the home page.');
} else {
$message = __('You cannot create a vacancy without a valid form.');
$messageIsError = true;
@ -108,12 +104,9 @@ class VacancyController extends Controller
break;
default:
$message = __("Please do not tamper with the URLs. To report a bug, please contact an administrator.");
$message = __('Please do not tamper with the URLs. To report a bug, please contact an administrator.');
$type = 'error';
}
} else {
$message = __("The position you're trying to update doesn't exist!");
$type = 'error';
@ -126,7 +119,6 @@ class VacancyController extends Controller
return redirect()
->back()
->with($type, $message);
}
public function edit(Request $request, Vacancy $vacancy)
@ -159,7 +151,6 @@ class VacancyController extends Controller
$this->authorize('delete', $vacancy);
if ($vacancy->teams->isEmpty()) {
$vacancy->delete();
return redirect()

View File

@ -23,7 +23,6 @@ namespace App\Http\Middleware;
use App\Application;
use App\User;
use Carbon\Carbon;
use Closure;
use Exception;
use Illuminate\Http\Request;
@ -38,9 +37,11 @@ class ApplicationEligibility
*
* @deprecated Deprecated in 0.9.0
* @see User::isEligible()
*
* @param Request $request
* @param Closure $next
* @return mixed
*
* @throws Exception
*/
public function handle($request, Closure $next)
@ -49,7 +50,6 @@ class ApplicationEligibility
$daysRemaining = __('N/A');
if (Auth::check()) {
$lastApplication = Application::where('applicantUserID', Auth::user()->id)->latest()->first();
if (is_null($lastApplication)) {
@ -61,7 +61,6 @@ class ApplicationEligibility
$daysRemaining = $lastApplication->created_at->addMonth()->diffInDays(now());
if ($lastApplication->created_at->diffInMonths(now()) > 1 && in_array($lastApplication->applicationStatus, ['DENIED', 'APPROVED'])) {
$eligible = true;
}
@ -69,7 +68,7 @@ class ApplicationEligibility
'eligible' => $eligible,
'daysRemaining' => $daysRemaining,
'ipAddress' => Auth::user()->originalIP,
'checkUserID' => Auth::user()->id
'checkUserID' => Auth::user()->id,
]);
View::share('isEligibleForApplication', $eligible);

View File

@ -31,12 +31,11 @@ class Bancheck
{
private AccountSuspensionService $suspensionService;
public function __construct(AccountSuspensionService $suspensionService) {
public function __construct(AccountSuspensionService $suspensionService)
{
$this->suspensionService = $suspensionService;
}
/**
* Handle an incoming request.
*

View File

@ -36,7 +36,6 @@ class ForceLogoutMiddleware
*/
public function handle($request, Closure $next)
{
if ((new AccountSuspensionService())->isSuspended(Auth::user())) {
Auth::logout();
$request->session()->flash('error', __('Your account is suspended. If you think this was a mistake, please contact an admin.'));

View File

@ -19,20 +19,15 @@ class PasswordExpirationMiddleware
*/
public function handle(Request $request, Closure $next)
{
if(Auth::check())
{
if (Auth::check()) {
$sinceUpdate = Carbon::parse(Auth::user()->password_last_updated)->diffInDays(now());
$updateThreshold = Options::getOption('password_expiry');
if ($updateThreshold !== 0 && $sinceUpdate > $updateThreshold)
{
if ($updateThreshold !== 0 && $sinceUpdate > $updateThreshold) {
session()->put('passwordExpired', true);
}
else
{
} else {
session()->put('passwordExpired', false);
}
}
return $next($request);

View File

@ -17,8 +17,7 @@ class PasswordExpirationRedirectMiddleware
*/
public function handle(Request $request, Closure $next)
{
if (Auth::check() && session('passwordExpired'))
{
if (Auth::check() && session('passwordExpired')) {
// WARNING!! Routes under the profile group must not have this middleware, because it'll result in an infinite redirect loop.
return redirect(route('showAccountSettings'));
}

View File

@ -24,7 +24,6 @@ namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
@ -45,5 +44,4 @@ class TrustProxies extends Middleware
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}

View File

@ -53,7 +53,7 @@ class BanUserRequest extends FormRequest
public function messages()
{
return [
'duration.required_if' => __('You must provide a duration if the suspension is temporary.')
'duration.required_if' => __('You must provide a duration if the suspension is temporary.'),
];
}
}

View File

@ -24,7 +24,7 @@ class CancelAppointmentRequest extends FormRequest
public function rules()
{
return [
'reason' => 'string|required'
'reason' => 'string|required',
];
}
}

View File

@ -28,7 +28,7 @@ class SaveSecuritySettings extends FormRequest
'graceperiod' => 'required|integer',
'pwExpiry' => 'required|integer',
'enforce2fa' => 'required|boolean',
'requirePMC' => 'required|boolean'
'requirePMC' => 'required|boolean',
];
}
}

View File

@ -5,7 +5,6 @@ namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class StoreAbsenceRequest extends FormRequest
{
/**
@ -30,7 +29,7 @@ class StoreAbsenceRequest extends FormRequest
'start_date' => 'required|date',
'predicted_end' => 'required|date|after:start_date',
'available_assist' => 'required|string',
'invalidAbsenceAgreement' => 'required|accepted'
'invalidAbsenceAgreement' => 'required|accepted',
];
}
}

View File

@ -26,7 +26,7 @@ class UploadFileRequest extends FormRequest
return [
'caption' => 'required|string|max:100',
'description' => 'required|string|max:800',
'file' => 'required|file|mimes:jpeg,jpg,png,bmp,tiff,docx,doc,odt,ott,xls,xlsx,ods,ots,gif,pdf,mp3,mp4,pptx,ppt,odp,ppsx,pub,psd,svg'
'file' => 'required|file|mimes:jpeg,jpg,png,bmp,tiff,docx,doc,odt,ott,xls,xlsx,ods,ots,gif,pdf,mp3,mp4,pptx,ppt,odp,ppsx,pub,psd,svg',
];
}
}

View File

@ -48,7 +48,7 @@ class VacancyEditRequest extends FormRequest
'vacancyFullDescription' => 'nullable|string',
'vacancyCount' => 'required|integer|min:1',
'requireDiscordAccount' => 'required|string',
'requiredAge' => 'required|integer|numeric|min:13|max:100'
'requiredAge' => 'required|integer|numeric|min:13|max:100',
];
}
}

View File

@ -53,7 +53,7 @@ class VacancyRequest extends FormRequest
'vacancyCount' => 'required|integer',
'vacancyFormID' => 'required|integer',
'requireDiscordAccount' => 'required|string',
'requiredAge' => 'required|integer|numeric|min:13|max:100'
'requiredAge' => 'required|integer|numeric|min:13|max:100',
];
}
}

View File

@ -22,7 +22,7 @@ class ApplicationResource extends JsonResource
'applicant' => new UserResource(User::findOrFail($this->applicantUserID)),
'response' => new ResponseResource(Response::findOrFail($this->applicantFormResponseID)),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at
'updated_at' => $this->updated_at,
];
}
}

View File

@ -20,7 +20,7 @@ class FormResource extends JsonResource
'formStructure' => json_decode($this->formStructure),
'formStatus' => $this->formStatus,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at
'updated_at' => $this->updated_at,
];
}
}

View File

@ -22,7 +22,7 @@ class ResponseResource extends JsonResource
'responseData' => json_decode($this->responseData),
'vacancy' => new VacancyResource(Vacancy::findOrFail($this->associatedVacancyID)),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at
'updated_at' => $this->updated_at,
];
}
}

View File

@ -22,7 +22,7 @@ class UserResource extends JsonResource
'username' => $this->username,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'current_team_id' => $this->current_team_id
'current_team_id' => $this->current_team_id,
];
}
}

View File

@ -6,7 +6,6 @@ use App\Notifications\AccountDeleted;
use App\Notifications\UserDeletedAccount;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
@ -25,7 +24,6 @@ class ProcessAccountDelete implements ShouldQueue
*/
protected User $user;
/**
* Create a new job instance.
*
@ -44,7 +42,7 @@ class ProcessAccountDelete implements ShouldQueue
public function handle()
{
Log::alert('[Worker] Processing account deletion request', [
'email' => $this->user->email
'email' => $this->user->email,
]);
$email = $this->user->email;
@ -52,7 +50,7 @@ class ProcessAccountDelete implements ShouldQueue
if ($this->user->delete()) {
Notification::route('mail', [
$email => $name
$email => $name,
])->notify(new AccountDeleted($name));
// Notify admins

View File

@ -21,9 +21,7 @@
namespace App\Jobs;
use App\Ban;
use App\Services\AccountSuspensionService;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

View File

@ -4,7 +4,6 @@ namespace App\Jobs;
use App\Services\AbsenceService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;

View File

@ -2,9 +2,6 @@
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class NewUser
{
/**

View File

@ -54,6 +54,5 @@ class OnUserRegistration
})->get()->each(function ($user, $key) use ($event) {
$user->notify(new NewUser($event->user));
});
}
}

View File

@ -48,7 +48,7 @@ class PromoteUser
Log::info('User promoted automatically (application approved)', [
'user' => $event->application->user->name,
'vacancy' => $event->application->response->vacancy->vacancyName,
'role' => 'staff'
'role' => 'staff',
]);
$event->application->setStatus('APPROVED');

View File

@ -31,11 +31,16 @@ class UserAccountDeleteConfirmation extends Mailable
use Queueable, SerializesModels;
public string
$approveLink,
$cancelLink,
$name,
$userID;
$approveLink;
public string
$cancelLink;
public string
$name;
public string
$userID;
/**
* Create a new message instance.

View File

@ -35,13 +35,11 @@ class ApplicationApproved extends Notification implements ShouldQueue
{
use Queueable, Cancellable;
/**
* @var Application The application we're notifying about
*/
public Application $application;
/**
* @var User The candidate
*/

View File

@ -4,7 +4,6 @@ namespace App\Notifications;
use App\Application;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

View File

@ -46,15 +46,16 @@ class ApplicationMoved extends Notification implements ShouldQueue
public function channels()
{
Log::debug('Application moved notification: channels chosen', [
'channels' => $this->chooseChannelsViaOptions()
'channels' => $this->chooseChannelsViaOptions(),
]);
return $this->chooseChannelsViaOptions();
}
public function optOut($notifiable)
{
Log::debug('Application moved notification: opt out verified', [
'opt-out' => Options::getOption('notify_application_status_change') != 1
'opt-out' => Options::getOption('notify_application_status_change') != 1,
]);
return Options::getOption('notify_application_status_change') != 1;

View File

@ -5,7 +5,6 @@ namespace App\Notifications;
use App\Application;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
@ -14,7 +13,9 @@ class AppointmentCancelled extends Notification
use Queueable;
private $application;
private $reason;
private $appointmentDate;
/**
@ -51,7 +52,7 @@ class AppointmentCancelled extends Notification
// TODO: Switch to HTML & Blade.
return (new MailMessage)
->greeting("Hi " . $notifiable->name . ",")
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - interview cancelled')
->line('The interview that was previously scheduled with you has been cancelled.')

View File

@ -31,7 +31,6 @@ class AppointmentFinished extends Notification implements ShouldQueue
{
use Queueable;
public $appointment;
/**
@ -64,14 +63,13 @@ class AppointmentFinished extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting("Hi " . $notifiable->name . ",")
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - appointment completed')
->line('Your appointment, "'.$this->appointment->appointmentDescription.'", has been marked as completed!')
->line('Please allow an additional day for your application to be fully processed.')
->action('View applications', url(route('showUserApps')))
->salutation('The team at '.config('app.name'));
}
/**

View File

@ -36,7 +36,6 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
protected string $status;
protected Vacancy $vacancy;
/**
@ -49,7 +48,7 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
// there's no simpler solution to this for now, but an array works
$statusDict = [
'open' => 'opened',
'close' => 'closed'
'close' => 'closed',
];
$this->vacancy = $vacancy;
@ -69,7 +68,6 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))

View File

@ -23,7 +23,6 @@ namespace App\Observers;
use App\Exceptions\ProfileAlreadyExistsException;
use App\Exceptions\ProfileCreationFailedException;
use App\Profile;
use App\Services\ProfileService;
use App\User;
use Illuminate\Support\Facades\Log;
@ -45,20 +44,15 @@ class UserObserver
{
$profileService = new ProfileService();
try
{
try {
$profileService->createProfile($user);
}
catch (ProfileAlreadyExistsException $exception)
{
} catch (ProfileAlreadyExistsException $exception) {
Log::error('Attempting to create profile that already exists!', [
'trace' => $exception->getTrace()
'trace' => $exception->getTrace(),
]);
}
catch (ProfileCreationFailedException $e)
{
} catch (ProfileCreationFailedException $e) {
Log::error('Failed creating a new profile!', [
'trace' => $e->getTrace()
'trace' => $e->getTrace(),
]);
}
}

View File

@ -14,4 +14,3 @@ class OneoffApplicant extends Model
return $this->belongsTo('App\Application', 'id', 'application_id');
}
}

View File

@ -3,7 +3,6 @@
namespace App\Policies;
use App\Absence;
use App\Response;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
@ -19,15 +18,13 @@ class AbsencePolicy
*/
public function viewAny(User $user)
{
if ($user->hasPermissionTo('admin.viewAllAbsences'))
{
if ($user->hasPermissionTo('admin.viewAllAbsences')) {
return true;
}
return false;
}
public function viewOwn(User $user): bool
{
if ($user->hasPermissionTo('reviewer.viewAbsence')) {
@ -46,8 +43,7 @@ class AbsencePolicy
*/
public function view(User $user, Absence $absence)
{
if ($user->hasPermissionTo('reviewer.viewAbsence') && $user->is($absence->requester) || $user->hasPermissionTo('admin.manageAbsences'))
{
if ($user->hasPermissionTo('reviewer.viewAbsence') && $user->is($absence->requester) || $user->hasPermissionTo('admin.manageAbsences')) {
return true;
}
@ -65,7 +61,6 @@ class AbsencePolicy
return $user->hasPermissionTo('reviewer.requestAbsence');
}
/**
* Determine whether the user can approve the absence request
*
@ -75,19 +70,16 @@ class AbsencePolicy
*/
public function approve(User $user, Absence $absence): bool
{
if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester))
{
if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester)) {
return true;
}
return false;
}
public function decline(User $user, Absence $absence): bool
{
if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester))
{
if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester)) {
return true;
}
@ -101,8 +93,8 @@ class AbsencePolicy
* @param Absence $absence
* @return bool
*/
public function cancel(User $user, Absence $absence): bool {
public function cancel(User $user, Absence $absence): bool
{
if ($user->is($absence->requester) && $user->can('reviewer.withdrawAbsence')) {
return true;
}
@ -121,6 +113,4 @@ class AbsencePolicy
{
return $user->hasPermissionTo('admin.manageAbsences');
}
}

View File

@ -18,13 +18,13 @@ class ApiKeyPolicy
*/
public function viewAny(User $user)
{
if ($user->hasRole('admin'))
if ($user->hasRole('admin')) {
return true;
}
return false;
}
/**
* Determine whether the user can create models.
*
@ -33,8 +33,9 @@ class ApiKeyPolicy
*/
public function create(User $user)
{
if ($user->hasRole('admin'))
if ($user->hasRole('admin')) {
return true;
}
return false;
}
@ -48,8 +49,9 @@ class ApiKeyPolicy
*/
public function update(User $user, ApiKey $apiKey)
{
if ($user->hasRole('admin'))
if ($user->hasRole('admin')) {
return true;
}
return false;
}
@ -63,10 +65,10 @@ class ApiKeyPolicy
*/
public function delete(User $user, ApiKey $apiKey)
{
if ($user->hasRole('admin'))
if ($user->hasRole('admin')) {
return true;
}
return false;
}
}

View File

@ -37,11 +37,9 @@ class TeamPolicy
return $user->isOwnerOfTeam($team) || $user->hasPermissionTo('teams.update');
}
public function invite(User $user, Team $team)
{
if (!$team->openJoin && $user->isOwnerOfTeam($team) || !$team->openJoin && $user->hasPermissionTo('teams.invite'))
{
if (! $team->openJoin && $user->isOwnerOfTeam($team) || ! $team->openJoin && $user->hasPermissionTo('teams.invite')) {
return true;
}

View File

@ -21,24 +21,17 @@
namespace App\Providers;
use App\Facades\Options;
use App\Application;
use App\Observers\ApplicationObserver;
use App\Observers\UserObserver;
use App\Observers\VacancyObserver;
use App\User;
use App\Vacancy;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Sentry;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
@ -66,18 +59,17 @@ class AppServiceProvider extends ServiceProvider
$https = ($this->app->environment() != 'local');
$collect = true;
if(config('app.force_secure') && $this->app->environment() != 'production')
if (config('app.force_secure') && $this->app->environment() != 'production') {
$https = true;
}
if (config('app.hide_ips') || config('demo.is_enabled'))
{
if (config('app.hide_ips') || config('demo.is_enabled')) {
$collect = false;
}
// Initialize user observer
User::observe(UserObserver::class);
$this->app['request']->server->set('HTTPS', $https);
View::share('shouldCollect', $collect);

View File

@ -22,13 +22,11 @@
namespace App\Providers;
use App\Absence;
use App\ApiKey;
use App\Application;
use App\Appointment;
use App\Ban;
use App\Form;
use App\Policies\AbsencePolicy;
use App\Policies\ApiKeyPolicy;
use App\Policies\ApplicationPolicy;
use App\Policies\AppointmentPolicy;
use App\Policies\BanPolicy;
@ -69,7 +67,7 @@ class AuthServiceProvider extends ServiceProvider
Appointment::class => AppointmentPolicy::class,
Team::class => TeamPolicy::class,
TeamFile::class => TeamFilePolicy::class,
Absence::class => AbsencePolicy::class
Absence::class => AbsencePolicy::class,
];
/**
@ -82,14 +80,12 @@ class AuthServiceProvider extends ServiceProvider
$this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) {
return (new MailMessage)
->greeting("Hi {$notifiable->name}! Welcome to " . config('app.name') . ".")
->greeting("Hi {$notifiable->name}! Welcome to ".config('app.name').'.')
->line('To finish setting up your account, you must verify your email. This is to ensure only real users access our website.')
->line('If you didn\'t sign up for an account, you can safely ignore this email.')
->action('Verify account', $url)
->salutation('The team at '.config('app.name'));
});
Gate::define('viewLogViewer', function (?User $user) {

View File

@ -2,8 +2,8 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App;
use Illuminate\Support\ServiceProvider;
class DigitalStorageProvider extends ServiceProvider
{

View File

@ -25,11 +25,6 @@ use App\Application;
use App\Listeners\LogAuthenticationFailure;
use App\Listeners\LogAuthenticationSuccess;
use App\Listeners\OnUserRegistration;
use App\Observers\ApplicationObserver;
use App\Observers\UserObserver;
use App\Observers\VacancyObserver;
use App\User;
use App\Vacancy;
use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Registered;

View File

@ -15,29 +15,24 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Spatie\Permission\Models\Role;
class AbsenceService
{
/**
* Determines whether someone already has an active leave of absence request
*
* @param User $user The user to check
* @return bool Their status
*/
public function hasActiveRequest(Authenticatable $user): bool {
public function hasActiveRequest(Authenticatable $user): bool
{
$absences = Absence::where('requesterID', $user->id)->get();
foreach ($absences as $absence) {
// Or we could adjust the query (using a model scope) to only return valid absences;
// If there are any, refuse to store more, but this approach also works
// A model scope that only returns cancelled, declined and ended absences could also be implemented for future use
if (in_array($absence->getRawOriginal('status'), ['PENDING', 'APPROVED']))
{
if (in_array($absence->getRawOriginal('status'), ['PENDING', 'APPROVED'])) {
return true;
}
}
@ -47,12 +42,11 @@ class AbsenceService
public function createAbsence(Authenticatable $requester, Request $request)
{
$absence = Absence::create([
'requesterID' => $requester->id,
'start' => $request->start_date,
'predicted_end' => $request->predicted_end,
'available_assist' => $request->available_assist == "on",
'available_assist' => $request->available_assist == 'on',
'reason' => $request->reason,
'status' => 'PENDING',
]);
@ -65,22 +59,21 @@ class AbsenceService
}
});
Log::info('Processing new leave of absence request.', [
'requesting_user' => $requester->email,
'absenceid' => $absence->id,
'reason' => $request->reason
'reason' => $request->reason,
]);
return $absence;
}
/**
* Sets an absence as Approved.
*
* @param Absence $absence The absence to approve.
* @return Absence The approved absence.
*
* @throws AbsenceNotActionableException
*/
public function approveAbsence(Absence $absence)
@ -88,19 +81,19 @@ class AbsenceService
Log::info('An absence request has just been approved.', [
'absenceid' => $absence->id,
'reviewing_admim' => Auth::user()->email,
'new_status' => 'APPROVED'
'new_status' => 'APPROVED',
]);
$absence->setApproved()
->requester->notify(new AbsenceRequestApproved($absence));
}
/**
* Sets an absence as Declined.
*
* @param Absence $absence The absence to decline.
* @return Absence The declined absence.
*
* @throws AbsenceNotActionableException
*/
public function declineAbsence(Absence $absence)
@ -108,26 +101,26 @@ class AbsenceService
Log::warning('An absence request has just been declined.', [
'absenceid' => $absence->id,
'reviewing_admim' => Auth::user()->email,
'new_status' => 'DECLINED'
'new_status' => 'DECLINED',
]);
$absence->setDeclined()
->requester->notify(new AbsenceRequestDeclined($absence));
}
/**
* Sets an absence as Cancelled.
*
* @param Absence $absence The absence to cancel.
* @return Absence The cancelled absence.
*
* @throws AbsenceNotActionableException
*/
public function cancelAbsence(Absence $absence)
{
Log::warning('An absence request has just been cancelled (only cancellable by requester).', [
'absenceid' => $absence->id,
'new_status' => 'CANCELLED'
'new_status' => 'CANCELLED',
]);
$absence->setCancelled()
@ -144,7 +137,7 @@ class AbsenceService
{
Log::info('An absence request has just expired.', [
'absenceid' => $absence->id,
'new_status' => 'ENDED'
'new_status' => 'ENDED',
]);
$absence->setEnded()
@ -169,20 +162,16 @@ class AbsenceService
/**
* End all expired absences in the application
*
* @return void
*/
public function endExpired(): void
{
foreach (Absence::all() as $absence)
{
foreach (Absence::all() as $absence) {
// tell the absence we want to check for cancelability
if (! Carbon::parse($absence->predicted_end)->isFuture() && $absence->isActionable(true)) {
$this->endAbsence($absence);
}
}
}
}

View File

@ -1,5 +1,6 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);
namespace App\Services;
@ -13,7 +14,6 @@ use Illuminate\Support\Facades\Log;
class AccountSuspensionService
{
/**
* Suspends a user account, with given $reason.
* Permanent if no duration given.
@ -23,12 +23,12 @@ class AccountSuspensionService
* @param int|null $duration Duration in days
* @return Ban The ban itself
*/
public function suspend(User $target, string $reason, int $duration = null): Ban {
Log::alert("An user account has just been suspended.", [
public function suspend(User $target, string $reason, int $duration = null): Ban
{
Log::alert('An user account has just been suspended.', [
'taget_email' => $target->email,
'suspended_by' => Auth::user()->email,
'reason' => $reason
'reason' => $reason,
]);
if ($duration > 0) {
@ -40,7 +40,7 @@ class AccountSuspensionService
'reason' => $reason,
'bannedUntil' => ($duration > 0) ? $expiryDate->format('Y-m-d H:i:s') : null,
'authorUserID' => Auth::user()->id,
'isPermanent' => ($duration == 0) ? true : false
'isPermanent' => ($duration == 0) ? true : false,
]);
}
@ -49,9 +49,9 @@ class AccountSuspensionService
*
* @param User $user The user to unsuspend
*/
public function unsuspend(User $user): void {
Log::alert("A suspension has just been lifted.", [
public function unsuspend(User $user): void
{
Log::alert('A suspension has just been lifted.', [
'target_email' => $user->email,
]);
@ -64,13 +64,11 @@ class AccountSuspensionService
* @param User $user The user to check
* @return bool Whether the mentioned user is suspended
*/
public function isSuspended(User $user): bool {
public function isSuspended(User $user): bool
{
return ! is_null($user->bans);
}
/**
* Sets an administrative lock on a user account.
* Used to prevent logins after a deletion process is initiated, but may be used for
@ -83,7 +81,7 @@ class AccountSuspensionService
public function lockAccount(User $user): bool
{
Log::alert('User account locked!', [
'email' => $user->email
'email' => $user->email,
]);
$user->administratively_locked = 1;
@ -92,7 +90,6 @@ class AccountSuspensionService
return $user->save();
}
/**
* Unlocks a user account. Reverse of lockAccount().
*
@ -102,7 +99,7 @@ class AccountSuspensionService
public function unlockAccount(User $user): bool
{
Log::alert('User account unlocked!', [
'email' => $user->email
'email' => $user->email,
]);
$user->administratively_locked = 0;
@ -117,7 +114,8 @@ class AccountSuspensionService
* @param User $user The user to check
* @return bool Whether the mentioned account is locked
*/
public function isLocked(User $user): bool {
public function isLocked(User $user): bool
{
return $user->administratively_locked == 1;
}
@ -127,11 +125,13 @@ class AccountSuspensionService
* @param User $user The user account to check
* @return string|bool Reason for the suspension, false if not suspended
*/
public function getSuspensionReason(User $user): string|bool {
public function getSuspensionReason(User $user): string|bool
{
return ($this->isSuspended($user)) ? $user->bans->reason : false;
}
public function getSuspensionDuration(User $user): string|null {
public function getSuspensionDuration(User $user): string|null
{
if ($this->isSuspended($user) && ! is_null($user->bans->bannedUntil)) {
return $user->bans->bannedUntil->diffForHumans();
}
@ -149,6 +149,4 @@ class AccountSuspensionService
// Unban on the last day, not on the exact time (with Carbon::now()).
return (bool) Ban::whereDate('bannedUntil', '=', Carbon::today())->delete();
}
}

View File

@ -1,26 +1,24 @@
<?php
namespace App\Services;
use App\Exceptions\DiscordAccountRequiredException;
use App\Exceptions\IncompatibleAgeException;
use App\Exceptions\InvalidAgeException;
use App\Notifications\ApplicationConfirmed;
use Carbon\Carbon;
use ContextAwareValidator;
use App\Application;
use App\Events\ApplicationDeniedEvent;
use App\Exceptions\ApplicationNotFoundException;
use App\Exceptions\DiscordAccountRequiredException;
use App\Exceptions\IncompatibleAgeException;
use App\Exceptions\IncompleteApplicationException;
use App\Exceptions\InvalidAgeException;
use App\Exceptions\UnavailableApplicationException;
use App\Exceptions\VacancyNotFoundException;
use App\Notifications\ApplicationConfirmed;
use App\Notifications\ApplicationMoved;
use App\Notifications\NewApplicant;
use App\Response;
use App\User;
use App\Vacancy;
use Illuminate\Auth\Authenticatable;
use Carbon\Carbon;
use ContextAwareValidator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
@ -37,12 +35,11 @@ class ApplicationService
$firstVacancy = $vacancyWithForm->first();
if (is_null(Auth::user()->dob)) {
throw new InvalidAgeException("User must have added their age to apply for this vacancy.");
throw new InvalidAgeException('User must have added their age to apply for this vacancy.');
} elseif (Carbon::parse(Auth::user()->dob)->age < $firstVacancy->requiredAge) {
throw new IncompatibleAgeException("Sorry, you must be {$firstVacancy->requiredAge} or older to apply to {$firstVacancy->vacancyName}.");
}
if ($firstVacancy->requiresDiscord && ! Auth::user()->hasDiscordConnection()) {
throw new DiscordAccountRequiredException('A discord account is required beyond this point.');
}
@ -54,9 +51,7 @@ class ApplicationService
'preprocessedForm' => json_decode($vacancyWithForm->first()->forms->formStructure, true),
]);
} else {
throw new ApplicationNotFoundException(__('The application you\'re looking for could not be found or it is currently unavailable.'), 404);
}
}
@ -72,14 +67,11 @@ class ApplicationService
$vacancy = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
if ($vacancy->isEmpty()) {
throw new VacancyNotFoundException('This vacancy doesn\'t exist; Please use the proper buttons to apply to one.', 404);
}
if ($vacancy->first()->vacancyCount == 0 || $vacancy->first()->vacancyStatus !== 'OPEN') {
throw new UnavailableApplicationException("This application is unavailable.");
throw new UnavailableApplicationException('This application is unavailable.');
}
Log::info('Processing new application!');
@ -87,7 +79,6 @@ class ApplicationService
$formStructure = json_decode($vacancy->first()->forms->formStructure, true);
$responseValidation = ContextAwareValidator::getResponseValidator($formData, $formStructure);
Log::info('Built response & validator structure!');
if (! $responseValidation->get('validator')->fails()) {
@ -99,7 +90,7 @@ class ApplicationService
Log::info('Registered form response!', [
'applicant' => $applicant->name,
'vacancy' => $vacancy->first()->vacancyName
'vacancy' => $vacancy->first()->vacancyName,
]);
$application = Application::create([
@ -110,7 +101,7 @@ class ApplicationService
Log::info('Submitted an application!', [
'responseID' => $response->id,
'applicant' => $applicant->name
'applicant' => $applicant->name,
]);
User::whereHas('roles', function ($q) {
@ -122,7 +113,6 @@ class ApplicationService
$application->user->notify(new ApplicationConfirmed($application));
return true;
}
Log::warning('Application form for '.$applicant->name.' contained errors, resetting!');
@ -136,7 +126,7 @@ class ApplicationService
case 'deny':
event(new ApplicationDeniedEvent($application));
$message = __("Application denied successfully.");
$message = __('Application denied successfully.');
break;
@ -150,7 +140,7 @@ class ApplicationService
break;
default:
throw new \LogicException("Wrong status parameter. Please notify a developer.");
throw new \LogicException('Wrong status parameter. Please notify a developer.');
}
return $message;
@ -164,7 +154,6 @@ class ApplicationService
return $application->delete();
}
public function canVote($votes): bool
{
$allvotes = collect([]);

View File

@ -1,13 +1,10 @@
<?php
namespace App\Services;
use App\Application;
use App\Appointment;
use App\Exceptions\InvalidAppointmentStatusException;
use App\Notifications\ApplicationMoved;
use App\Notifications\AppointmentCancelled;
use App\Notifications\AppointmentFinished;
use App\Notifications\AppointmentScheduled;
@ -53,22 +50,20 @@ class AppointmentService
$application->user->notify(new AppointmentScheduled($appointment));
return true;
}
/**
* Cancels an appointment for the provided application.
*
* @param Application $application The target application.
* @param string $reason The reason for cancelling the appointment.
*
* @throws \Exception Thrown when there's no appointment to cancel
*/
public function deleteAppointment(Application $application, string $reason): bool
{
if (!empty($application->appointment))
{
if (! empty($application->appointment)) {
$application->user->notify(new AppointmentCancelled($application, Carbon::parse($application->appointment->appointmentDate), $reason));
$application->appointment->delete();
@ -77,14 +72,13 @@ class AppointmentService
Log::info('An interview appointment has just been cancelled.', [
'actor' => Auth::user()->name,
'applicant' => $application->user->name,
'reason' => $reason
'reason' => $reason,
]);
return true;
}
throw new \Exception("This application doesn't have an appointment!");
}
/**
@ -97,22 +91,17 @@ class AppointmentService
*/
public function updateAppointment(Application $application, $status, $updateApplication = true)
{
if ($status == 'SCHEDULED' || $status == 'concluded')
{
if ($status == 'SCHEDULED' || $status == 'concluded') {
$application->appointment->appointmentStatus = strtoupper($status);
$application->appointment->save();
if ($updateApplication)
{
if ($updateApplication) {
$application->setStatus('STAGE_PEERAPPROVAL');
$application->user->notify(new AppointmentFinished($application->appointment));
}
} else {
throw new InvalidAppointmentStatusException('Invalid appointment status!');
}
else
{
throw new InvalidAppointmentStatusException("Invalid appointment status!");
}
}
/**
@ -122,5 +111,4 @@ class AppointmentService
{
return $this->allowedPlatforms;
}
}

View File

@ -1,17 +1,15 @@
<?php
namespace App\Services;
use App\Application;
use App\Comment;
use Illuminate\Support\Facades\Auth;
class CommentService
{
public function addComment(Application $application, $comment): Comment {
public function addComment(Application $application, $comment): Comment
{
return Comment::create([
'authorID' => Auth::user()->id,
'applicationID' => $application->id,
@ -23,5 +21,4 @@ class CommentService
{
return $comment->delete();
}
}

View File

@ -1,28 +1,21 @@
<?php
namespace App\Services;
use App\Exceptions\InvalidGamePreferenceException;
use App\Exceptions\OptionNotFoundException;
use App\Facades\Options;
use Illuminate\Auth\Authenticatable;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class ConfigurationService
{
/**
* @throws OptionNotFoundException|\Exception
*
*/
public function saveConfiguration($configuration) {
public function saveConfiguration($configuration)
{
foreach ($configuration as $optionName => $option) {
try {
Log::debug('Going through option '.$optionName);
if (Options::optionExists($optionName)) {
Log::debug('Option exists, updating to new values', [
@ -31,9 +24,7 @@ class ConfigurationService
]);
Options::changeOption($optionName, $option);
}
} catch (\Exception $ex) {
Log::error('Unable to update options!', [
'msg' => $ex->getMessage(),
'trace' => $ex->getTraceAsString(),
@ -49,27 +40,26 @@ class ConfigurationService
* Saves the chosen game integration
*
* @throws InvalidGamePreferenceException
*
* @returns bool
*/
public function saveGameIntegration($gamePreference): bool
{
// TODO: Find solution to dynamically support games
$supportedGames = [
'RUST',
'MINECRAFT',
'SE',
'GMOD'
'GMOD',
];
if (!is_null($gamePreference) && in_array($gamePreference, $supportedGames))
{
if (! is_null($gamePreference) && in_array($gamePreference, $supportedGames)) {
Options::changeOption('currentGame', $gamePreference);
return true;
}
throw new InvalidGamePreferenceException("Unsupported game " . $gamePreference);
throw new InvalidGamePreferenceException('Unsupported game '.$gamePreference);
}
}

View File

@ -1,9 +1,7 @@
<?php
namespace App\Services;
use App\Exceptions\FailedCaptchaException;
use App\Notifications\NewContact;
use App\User;
@ -11,7 +9,6 @@ use Illuminate\Support\Facades\Http;
class ContactService
{
/**
* Sends a message to all admins.
*
@ -42,6 +39,4 @@ class ContactService
}
}
}
}

View File

@ -1,11 +1,11 @@
<?php
namespace App\Services;
class DemoService {
public function isDemoEnabled(): bool {
class DemoService
{
public function isDemoEnabled(): bool
{
return config('demo.is_enabled');
}
}

View File

@ -4,19 +4,19 @@ namespace App\Services;
use App\User;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
class DiscordService
{
/**
* Sends a token revocation request to Discord to invalidate a specific $user's tokens.
* Please ensure you have the user set a password for their account after this, or request new tokens.
*
* @see https://www.rfc-editor.org/rfc/rfc7009
*
* @param User $user
* @return bool
*
* @throws RequestException
*/
public function revokeAccountTokens(User $user): bool
@ -27,8 +27,6 @@ class DiscordService
'token' => $user->discord_token,
])->throw();
$user->discord_token = null;
$user->discord_user_id = null;
$user->discord_refresh_token = null;
@ -37,6 +35,4 @@ class DiscordService
return $req->ok();
}
}

View File

@ -1,6 +1,5 @@
<?php
namespace App\Services;
use App\Exceptions\EmptyFormException;
@ -10,9 +9,8 @@ use ContextAwareValidator;
class FormManagementService
{
public function addForm($fields) {
public function addForm($fields)
{
if (count($fields) == 2) {
// form is probably empty, since forms with fields will always have more than 2 items
throw new EmptyFormException('Sorry, but you may not create empty forms.');
@ -30,13 +28,15 @@ class FormManagementService
'formStatus' => 'ACTIVE',
]
);
return true;
}
return $contextValidation->get('validator')->errors()->getMessages();
}
public function deleteForm(Form $form) {
public function deleteForm(Form $form)
{
$deletable = true;
if (! is_null($form->vacancies) && $form->vacancies->count() !== 0 || ! is_null($form->responses)) {
@ -44,19 +44,16 @@ class FormManagementService
}
if ($deletable) {
$form->delete();
return true;
} else {
throw new FormHasConstraintsException(__('You cannot delete this form because it\'s tied to one or more applications and ranks, or because it doesn\'t exist.'));
}
}
public function updateForm(Form $form, $fields) {
public function updateForm(Form $form, $fields)
{
$contextValidation = ContextAwareValidator::getValidator($fields, true);
if (! $contextValidation->get('validator')->fails()) {
@ -67,10 +64,8 @@ class FormManagementService
$form->save();
return $form;
} else {
return $contextValidation->get('validator')->errors()->getMessages();
}
}
}

View File

@ -1,9 +1,7 @@
<?php
namespace App\Services;
use App\Application;
use App\Exceptions\InvalidAppointmentException;
@ -15,10 +13,11 @@ class MeetingNoteService
* @param Application $application
* @param $noteText
* @return bool
*
* @throws InvalidAppointmentException Thrown when an application doesn't have an appointment to save notes to
*/
public function addToApplication(Application $application, $noteText): bool {
public function addToApplication(Application $application, $noteText): bool
{
if (! is_null($application)) {
$application->load('appointment');
@ -26,11 +25,8 @@ class MeetingNoteService
$application->appointment->save();
return true;
} else {
throw new InvalidAppointmentException('There\'s no appointment to save notes to!');
}
}
}

View File

@ -1,33 +1,29 @@
<?php
namespace App\Services;
use App\Exceptions\ProfileAlreadyExistsException;
use App\Exceptions\ProfileCreationFailedException;
use App\Exceptions\ProfileNotFoundException;
use App\Profile;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class ProfileService
{
/**
* Creates a new profile for the specified $targetUser.
*
* @param User $targetUser The user to create the profile for.
* @return bool
*
* @throws ProfileAlreadyExistsException
* @throws ProfileCreationFailedException
*/
public function createProfile(User $targetUser): Profile {
public function createProfile(User $targetUser): Profile
{
if (is_null($targetUser->profile)) {
$profile = Profile::create([
'profileShortBio' => 'Write a one-liner about you here!',
@ -42,7 +38,7 @@ class ProfileService
}
Log::info('Created profile for new user', [
'userid' => $targetUser->id
'userid' => $targetUser->id,
]);
return $profile;
@ -56,7 +52,8 @@ class ProfileService
*
* @throws ProfileNotFoundException
*/
public function updateProfile($userID, Request $request) {
public function updateProfile($userID, Request $request)
{
$profile = User::find($userID)->profile;
$social = [];
@ -85,7 +82,7 @@ class ProfileService
return $profile->save();
}
throw new ProfileNotFoundException("This profile does not exist.");
throw new ProfileNotFoundException('This profile does not exist.');
}
/**
@ -93,15 +90,14 @@ class ProfileService
*
* @param User $targetUser
* @return bool
*
* @throws ProfileNotFoundException
*/
public function deleteProfile(User $targetUser): bool
{
if (! is_null($targetUser->profile)) {
Log::alert('Deleted user profile', [
'userid' => $targetUser->id
'userid' => $targetUser->id,
]);
return $targetUser->profile->delete();
@ -109,5 +105,4 @@ class ProfileService
throw new ProfileNotFoundException(__('Attempting to delete non-existant profile!'));
}
}

View File

@ -1,15 +1,12 @@
<?php
namespace App\Services;
use App\Facades\Options;
use Illuminate\Support\Facades\Log;
class SecuritySettingsService
{
/**
* Saves the app security settings.
*
@ -17,28 +14,25 @@ class SecuritySettingsService
* @param array $options
* @return bool
*/
public function save($policy, $options = []) {
public function save($policy, $options = [])
{
$validPolicies = [
'off',
'low',
'medium',
'high'
'high',
];
if (in_array($policy, $validPolicies))
{
if (in_array($policy, $validPolicies)) {
Options::changeOption('pw_security_policy', $policy);
Log::debug('[Options] Changing option pw_security_policy', [
'new_value' => $policy
'new_value' => $policy,
]);
}
else
{
} else {
Log::debug('[WARN] Ignoring bogus policy', [
'avaliable' => $validPolicies,
'given' => $policy
'given' => $policy,
]);
}
@ -48,7 +42,5 @@ class SecuritySettingsService
Options::changeOption('requireGameLicense', $options['requirePMC']);
return true;
}
}

View File

@ -1,19 +1,15 @@
<?php
namespace App\Services;
use App\Exceptions\FileUploadException;
use App\TeamFile;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Auth;
class TeamFileService
{
public function addFile(UploadedFile $upload, $uploader, $team, $caption, $description) {
public function addFile(UploadedFile $upload, $uploader, $team, $caption, $description)
{
$file = $upload->store('uploads');
$originalFileName = $upload->getClientOriginalName();
$originalFileExtension = $upload->extension();
@ -27,16 +23,13 @@ class TeamFileService
'description' => $description,
'fs_location' => $file,
'extension' => $originalFileExtension,
'size' => $originalFileSize
'size' => $originalFileSize,
]);
if ($fileEntry && !is_bool($file))
{
if ($fileEntry && ! is_bool($file)) {
return $fileEntry;
}
throw new FileUploadException("There was an unknown error whilst trying to upload your file.");
throw new FileUploadException('There was an unknown error whilst trying to upload your file.');
}
}

View File

@ -1,9 +1,7 @@
<?php
namespace App\Services;
use App\Exceptions\InvalidInviteException;
use App\Exceptions\PublicTeamInviteException;
use App\Exceptions\UserAlreadyInvitedException;
@ -18,7 +16,6 @@ use Mpociot\Teamwork\TeamInvite;
class TeamService
{
/**
* Create a team
*
@ -26,8 +23,8 @@ class TeamService
* @param $ownerID
* @return Team
*/
public function createTeam($teamName, $ownerID): Team {
public function createTeam($teamName, $ownerID): Team
{
$team = Team::create([
'name' => $teamName,
'owner_id' => $ownerID,
@ -40,7 +37,6 @@ class TeamService
public function updateTeam(Team $team, $teamDescription, $joinType): bool
{
$team->description = $teamDescription;
$team->openJoin = $joinType;
@ -55,7 +51,6 @@ class TeamService
*/
public function inviteUser(Team $team, $userID): bool
{
$user = User::findOrFail($userID);
if (! $team->openJoin) {
@ -63,6 +58,7 @@ class TeamService
Teamwork::inviteToTeam($user, $team, function (TeamInvite $invite) use ($user) {
Mail::to($user)->send(new InviteToTeam($invite));
});
return true;
} else {
throw new UserAlreadyInvitedException('This user has already been invited.');
@ -70,7 +66,6 @@ class TeamService
} else {
throw new PublicTeamInviteException('You can\'t invite users to public teams.');
}
}
/**
@ -80,10 +75,11 @@ class TeamService
* @param $action
* @param $token
* @return bool True on success or exception on failure
*
* @throws InvalidInviteException Thrown when the invite code / url is invalid
*/
public function processInvite(Authenticatable $user, $action, $token): bool {
public function processInvite(Authenticatable $user, $action, $token): bool
{
switch ($action) {
case 'accept':
@ -91,9 +87,7 @@ class TeamService
if ($invite && $invite->user->is($user)) {
Teamwork::acceptInvite($invite);
} else {
throw new InvalidInviteException('Invalid or expired invite URL.');
}
@ -104,11 +98,8 @@ class TeamService
$invite = Teamwork::getInviteFromDenyToken($token);
if ($invite && $invite->user->is($user)) {
Teamwork::denyInvite($invite);
} else {
throw new InvalidInviteException('Invalid or expired invite URL.');
}
@ -119,10 +110,8 @@ class TeamService
}
return true;
}
/**
* @param Team $team
* @param $associatedVacancies
@ -130,7 +119,6 @@ class TeamService
*/
public function updateVacancies(Team $team, $associatedVacancies): string
{
// P.S. To future developers
// This method gave me a lot of trouble lol. It's hard to write code when you're half asleep.
// There may be an n+1 query in the view and I don't think there's a way to avoid that without writing a lot of extra code.
@ -160,6 +148,7 @@ class TeamService
} else {
$team->vacancies()->attach($requestVacancies);
}
return 'Assignments changed successfully.';
}
}

View File

@ -37,8 +37,6 @@ class Team extends TeamworkTeam
return $this->belongsToMany('App\Vacancy', 'team_has_vacancy');
}
public function files()
{
return $this->hasMany('App\TeamFile', 'team_id');

View File

@ -11,7 +11,6 @@ class TeamFile extends Model
{
use HasFactory, UsedByTeams;
protected $fillable = [
'uploaded_by',
'team_id',
@ -20,7 +19,7 @@ class TeamFile extends Model
'extension',
'size',
'caption',
'description'
'description',
];
public function uploader()
@ -33,7 +32,6 @@ class TeamFile extends Model
return $this->belongsTo('App\Team');
}
public function getSizeAttribute($value)
{
return DigitalStorageHelper::setValue($value)->formatBytes(2, true);

View File

@ -37,7 +37,7 @@ trait Cancellable
}
Log::debug('Cancellable: current channels list', [
'channels' => $channels
'channels' => $channels,
]);
return $channels;

View File

@ -6,7 +6,6 @@ use Illuminate\Http\RedirectResponse;
trait DisablesFeatures
{
/**
* Checks if demo mode is active. If so, it stops any more logic from running.
*
@ -19,7 +18,7 @@ trait DisablesFeatures
->back()
->with('error', __('This feature is disabled'));
}
return null;
}
}

View File

@ -35,7 +35,6 @@ use Illuminate\Support\Facades\URL;
trait HandlesAccountDeletion
{
/**
* Starts the user account deletion process.
*
@ -45,8 +44,7 @@ trait HandlesAccountDeletion
*/
public function userDelete(AccountSuspensionService $suspensionService, UserDeleteRequest $request)
{
if (config('demo.is_enabled'))
{
if (config('demo.is_enabled')) {
return redirect()
->back()
->with('error', 'This feature is disabled');
@ -58,7 +56,7 @@ trait HandlesAccountDeletion
),
'cancelURL' => URL::temporarySignedRoute(
'processDeleteConfirmation', now()->addDays(7), ['accountID' => $request->user()->id, 'action' => 'cancel']
)
),
];
Mail::to($request->user())
@ -69,10 +67,10 @@ trait HandlesAccountDeletion
Auth::logout();
$request->session()->flash('success', __('Please check your email to finish deleting your account.'));
return redirect()->to('/');
}
/**
* Dispatches the correct jobs and events to delete the specified user account
*
@ -84,8 +82,7 @@ trait HandlesAccountDeletion
*/
public function processDeleteConfirmation(Request $request, AccountSuspensionService $suspensionService, $accountID, $action)
{
if (config('demo.is_enabled') || !$request->hasValidSignature())
{
if (config('demo.is_enabled') || ! $request->hasValidSignature()) {
abort(403);
}
@ -93,8 +90,7 @@ trait HandlesAccountDeletion
// The request URL can't be tampered with and the request can't be initiated without a valid account in the first place
$account = User::find($accountID);
if (!is_null($account))
{
if (! is_null($account)) {
if (! $suspensionService->isLocked($account)) {
abort(403);
}
@ -125,13 +121,11 @@ trait HandlesAccountDeletion
return redirect()
->route('login');
}
Log::error("Cannot delete account that doesn't exist!", [
'validSignature' => $request->hasValidSignature()
'validSignature' => $request->hasValidSignature(),
]);
abort(400);
}
}

View File

@ -44,7 +44,6 @@ class UUID
// Note: Caching could simply be assigning the username to it's UUID, however, to make this work, we'd need to loop over all cache items, which would be slighly ineffective
public function toUsername(string $uuid)
{
$shortUUID = substr($uuid, 0, 8);
$username = Cache::remember('uuid_'.$shortUUID, now()->addDays(30), function () use ($shortUUID, $uuid) {
$response = json_decode(Http::get(trim(config('general.urls.mojang.session')).'/session/minecraft/profile/'.$uuid)->body(), true);

View File

@ -21,18 +21,10 @@
namespace App;
use App\Services\AccountSuspensionService;
use App\Traits\HandlesAccountTokens;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
use Mpociot\Teamwork\Traits\UserHasTeams;
use Spatie\Permission\Traits\HasRoles;
@ -58,7 +50,7 @@ class User extends Authenticatable implements MustVerifyEmail
'currentIp',
'discord_user_id',
'discord_token',
'discord_refresh_token'
'discord_refresh_token',
];
/**
@ -67,7 +59,7 @@ class User extends Authenticatable implements MustVerifyEmail
* @var array
*/
protected $hidden = [
'password', 'remember_token', 'discord_token', 'discord_refresh_token'
'password', 'remember_token', 'discord_token', 'discord_refresh_token',
];
/**
@ -78,7 +70,7 @@ class User extends Authenticatable implements MustVerifyEmail
protected $casts = [
'email_verified_at' => 'datetime',
'discord_token' => 'encrypted',
'discord_refresh_token' => 'encrypted'
'discord_refresh_token' => 'encrypted',
];
// RELATIONSHIPS
@ -91,7 +83,6 @@ class User extends Authenticatable implements MustVerifyEmail
public function votes()
{
return $this->hasMany('App\Vote', 'userID', 'id');
}
public function profile()
@ -119,8 +110,8 @@ class User extends Authenticatable implements MustVerifyEmail
return $this->hasMany('App\Absence', 'requesterID');
}
public function isEligible(): bool {
public function isEligible(): bool
{
$lastApplication = Application::where('applicantUserID', $this->getAttribute('id'))->latest()->first();
if (is_null($lastApplication)) {
@ -134,8 +125,8 @@ class User extends Authenticatable implements MustVerifyEmail
return false;
}
public function isVerified(): bool {
public function isVerified(): bool
{
return ! is_null($this->email_verified_at);
}
@ -143,6 +134,7 @@ class User extends Authenticatable implements MustVerifyEmail
* Checks if user is staff
*
* @deprecated This method is being replaced by a better way of checking permissions, rather than checking for group name.
*
* @return bool
*/
public function isStaffMember(): bool
@ -168,12 +160,9 @@ class User extends Authenticatable implements MustVerifyEmail
*/
public function hasTeam($team): bool
{
if ($team instanceof Team || is_int($team))
{
if ($team instanceof Team || is_int($team)) {
return $this->teams->contains($team);
}
else
{
} else {
/**
* In PHP 8, we can just use union types and let PHP enforce this for us.
*/
@ -186,18 +175,18 @@ class User extends Authenticatable implements MustVerifyEmail
*
* @return bool
*/
public function hasDiscordConnection(): bool {
public function hasDiscordConnection(): bool
{
return ! is_null($this->discord_token) && ! is_null($this->discord_refresh_token);
}
/**
* Check if user has a password
*
* @return bool
*/
public function hasPassword(): bool {
public function hasPassword(): bool
{
return ! is_null($this->password);
}
}

View File

@ -45,7 +45,7 @@ class Vacancy extends Model
'vacancySlug',
'team_id',
'requiresDiscord',
'requiredAge'
'requiredAge',
];
@ -94,15 +94,14 @@ class Vacancy extends Model
public function decrease()
{
if ($this->vacancyCount !== 0)
{
if ($this->vacancyCount !== 0) {
$this->update([
'vacancyCount' => $this->vacancyCount - 1
'vacancyCount' => $this->vacancyCount - 1,
]);
Log::info('Vacancies: Decreased vacancy slots by one.', [
'vacancyId' => $this->id,
'vacancyName' => $this->vacancyName
'vacancyName' => $this->vacancyName,
]);
}
}

View File

@ -2,17 +2,26 @@
namespace App\View\Components;
use App\User;
use Illuminate\View\Component;
class AccountStatus extends Component
{
public bool
$isVerified,
$isSuspended,
$isLocked,
$has2FA,
$hasDiscord,
$isVerified;
public bool
$isSuspended;
public bool
$isLocked;
public bool
$has2FA;
public bool
$hasDiscord;
public bool
$hasPassword;
/**

View File

@ -25,11 +25,13 @@ use Illuminate\View\Component;
class Alert extends Component
{
public
$alertType,
$extraStyling,
$title,
$icon;
public $alertType;
public $extraStyling;
public $title;
public $icon;
/**
* Create a new component instance.

View File

@ -7,13 +7,27 @@ use Illuminate\View\Component;
class Button extends Component
{
public string
$type,
$icon,
$link,
$target,
$size,
$color,
$disabled,
$type;
public string
$icon;
public string
$link;
public string
$target;
public string
$size;
public string
$color;
public string
$disabled;
public string
$id;
public function __construct($id, $color, $type = 'button', $disabled = false, $size = '', $target = '', $link = '', $icon = '')

View File

@ -40,6 +40,7 @@
"barryvdh/laravel-debugbar": "^3.3",
"barryvdh/laravel-ide-helper": "^2.12",
"fakerphp/faker": "^1.19",
"laravel/pint": "^1.4",
"laravel/sail": "^1.15",
"mockery/mockery": "^1.3.1",
"nunomaduro/collision": "^6.1",

68
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "04e34fbbef2bf9b12382145e6a9f4fb4",
"content-hash": "9ebe2207f617199a090bd8d2c19e1597",
"packages": [
{
"name": "almasaeed2010/adminlte",
@ -9740,6 +9740,72 @@
],
"time": "2022-01-07T12:00:00+00:00"
},
{
"name": "laravel/pint",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "0e7ffdb0af871be10d798e234772ea5d4020ae4a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/0e7ffdb0af871be10d798e234772ea5d4020ae4a",
"reference": "0e7ffdb0af871be10d798e234772ea5d4020ae4a",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
"php": "^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~3.13.1",
"illuminate/view": "^9.32.0",
"laravel-zero/framework": "^9.2.0",
"mockery/mockery": "^1.5.1",
"nunomaduro/larastan": "^2.2.0",
"nunomaduro/termwind": "^1.14.0",
"pestphp/pest": "^1.22.1"
},
"bin": [
"builds/pint"
],
"type": "project",
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Seeders\\": "database/seeders/",
"Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nuno Maduro",
"email": "enunomaduro@gmail.com"
}
],
"description": "An opinionated code formatter for PHP.",
"homepage": "https://laravel.com",
"keywords": [
"format",
"formatter",
"lint",
"linter",
"php"
],
"support": {
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2023-01-10T20:03:42+00:00"
},
{
"name": "laravel/sail",
"version": "v1.15.4",

View File

@ -235,7 +235,7 @@ return [
[
'text' => 'Dashboard',
'icon' => 'fas fa-tachometer-alt',
'url' => '/dashboard'
'url' => '/dashboard',
],
[
'header' => 'h_applications',
@ -269,7 +269,7 @@ return [
],
[
'header' => 'Human Resources',
'can' => 'reviewer.requestAbsence'
'can' => 'reviewer.requestAbsence',
],
[
'text' => 'Absence Management',
@ -280,13 +280,13 @@ return [
'text' => 'New request',
'icon' => 'fas fa-plus',
'can' => 'reviewer.requestAbsence',
'route' => 'absences.create'
'route' => 'absences.create',
],
[
'text' => 'My requests',
'icon' => 'fas fa-business-time',
'can' => 'reviewer.viewAbsence',
'route' => 'showUserAbsences'
'route' => 'showUserAbsences',
],
],
@ -295,7 +295,7 @@ return [
'text' => 'Absence requests',
'icon' => 'fas fa-address-card',
'can' => 'admin.manageAbsences',
'route' => 'absences.index'
'route' => 'absences.index',
],
[
'header' => 'h_app_management',
@ -317,15 +317,15 @@ return [
'text' => 'Available Teams',
'icon' => 'fas fa-clipboard',
'url' => 'teams',
'can' => 'teams.view'
'can' => 'teams.view',
],
[
'text' => 'Files',
'icon' => 'fas fa-file-alt',
'url' => 'team/files',
'can' => 'teams.view'
'can' => 'teams.view',
],
],
]
],
[
'header' => 'h_admin',
@ -624,14 +624,14 @@ return [
[
'type' => 'css',
'asset' => false,
'location' => 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css'
'location' => 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css',
],
[
'type' => 'js',
'asset' => false,
'location' => 'https://cdn.jsdelivr.net/npm/flatpickr'
]
]
'location' => 'https://cdn.jsdelivr.net/npm/flatpickr',
],
],
],
[
'name' => 'Pusher',
@ -640,9 +640,9 @@ return [
[
'type' => 'js',
'asset' => false,
'location' => 'https://js.pusher.com/beams/1.0/push-notifications-cdn.js'
]
]
]
'location' => 'https://js.pusher.com/beams/1.0/push-notifications-cdn.js',
],
],
],
],
];

View File

@ -46,9 +46,6 @@ return [
*/
'sitehomepage' => env('APP_SITEHOMEPAGE', 'https://google.com'),
/*
|--------------------------------------------------------------------------
| Application Version
@ -77,7 +74,6 @@ return [
*/
'force_secure' => env('NONPROD_FORCE_SECURE', false),
/*
|--------------------------------------------------------------------------
| IP address anonymity
@ -94,7 +90,6 @@ return [
*/
'hide_ips' => env('HIDE_IPS'),
/*
|--------------------------------------------------------------------------
| Legal documents & source code
@ -351,7 +346,7 @@ return [
'ContextAwareValidator' => App\Facades\ContextAwareValidation::class,
'Settings' => App\Facades\Options::class,
'JSON' => App\Facades\JSON::class,
'DiscordOauth' => App\Facades\Discord::class
'DiscordOauth' => App\Facades\Discord::class,
],

Some files were not shown because too many files have changed in this diff Show More