@@ -22,36 +22,22 @@
|
||||
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;
|
||||
use App\Http\Requests\BanUserRequest;
|
||||
use App\Http\Requests\ChangeEmailRequest;
|
||||
use App\Http\Requests\ChangePasswordRequest;
|
||||
use App\Http\Requests\DeleteUserRequest;
|
||||
use App\Http\Requests\FlushSessionsRequest;
|
||||
use App\Http\Requests\Remove2FASecretRequest;
|
||||
use App\Http\Requests\Reset2FASecretRequest;
|
||||
use App\Http\Requests\SearchPlayerRequest;
|
||||
use App\Http\Requests\SetNewPasswordRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
use App\Notifications\ChangedPassword;
|
||||
use App\Notifications\EmailChanged;
|
||||
use App\Notifications\PasswordAdminResetNotification;
|
||||
use App\Notifications\TwoFactorResetNotification;
|
||||
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;
|
||||
use Illuminate\Http\Client\RequestException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -59,20 +45,13 @@ use Spatie\Permission\Models\Role;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
use HandlesAccountDeletion, DisablesFeatures;
|
||||
use HandlesAccountDeletion;
|
||||
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$this->authorize('viewPlayers', User::class);
|
||||
|
||||
return view('dashboard.administration.users')
|
||||
return view('dashboard.administration.players')
|
||||
->with([
|
||||
'users' => User::with('roles')->paginate('6'),
|
||||
'numUsers' => count(User::all()),
|
||||
@@ -80,15 +59,6 @@ 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)
|
||||
{
|
||||
$this->authorize('viewPlayers', User::class);
|
||||
@@ -102,7 +72,7 @@ class UserController extends Controller
|
||||
if (! $matchingUsers->isEmpty()) {
|
||||
$request->session()->flash('success', __('There were :usersCount user(s) matching your search.', ['usersCount' => $matchingUsers->count()]));
|
||||
|
||||
return view('dashboard.administration.users')
|
||||
return view('dashboard.administration.players')
|
||||
->with([
|
||||
'users' => $matchingUsers,
|
||||
'numUsers' => count(User::all()),
|
||||
@@ -115,16 +85,6 @@ 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
|
||||
*/
|
||||
public function showAccount(Request $request)
|
||||
{
|
||||
$QRCode = null;
|
||||
@@ -149,58 +109,6 @@ class UserController extends Controller
|
||||
->with('twofaQRCode', $QRCode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show account management screen
|
||||
*
|
||||
* @param AccountSuspensionService $suspensionService
|
||||
* @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();
|
||||
$userRoles = $user->roles->pluck('name')->all();
|
||||
|
||||
$roleList = [];
|
||||
|
||||
foreach ($systemRoles as $role) {
|
||||
if (in_array($role, $userRoles)) {
|
||||
$roleList[$role] = true;
|
||||
} else {
|
||||
$roleList[$role] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return view('dashboard.user.manage')
|
||||
->with([
|
||||
'user' => $user,
|
||||
'roles' => $roleList,
|
||||
'isVerified' => $user->isVerified(),
|
||||
'isLocked' => $suspensionService->isLocked($user),
|
||||
'isSuspended' => $suspensionService->isSuspended($user),
|
||||
'hasDiscord' => $user->hasDiscordConnection(),
|
||||
'hasPassword' => $user->hasPassword(),
|
||||
'requireLicense' => Options::getOption('requireGameLicense'),
|
||||
'suspensionReason' => $suspensionService->getSuspensionReason($user),
|
||||
'suspensionDuration' => $suspensionService->getSuspensionDuration($user),
|
||||
'has2FA' => $user->has2FA(),
|
||||
'applications' => $user->applications()->get()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out other sessions for the current user
|
||||
*
|
||||
* @param FlushSessionsRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\AuthenticationException
|
||||
*/
|
||||
public function flushSessions(FlushSessionsRequest $request)
|
||||
{
|
||||
// TODO: Move all log calls to a listener, which binds to an event fired by each significant event, such as this one
|
||||
@@ -219,14 +127,6 @@ class UserController extends Controller
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Change the current user's password
|
||||
*
|
||||
* @param ChangePasswordRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse|void
|
||||
*/
|
||||
public function changePassword(ChangePasswordRequest $request)
|
||||
{
|
||||
if (config('demo.is_enabled')) {
|
||||
@@ -255,80 +155,13 @@ class UserController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a new password for the user.
|
||||
*
|
||||
* @param SetNewPasswordRequest $request
|
||||
* @return Application|RedirectResponse|Redirector
|
||||
*/
|
||||
public function setPassword(SetNewPasswordRequest $request) {
|
||||
|
||||
if (!Auth::user()->hasPassword()) {
|
||||
|
||||
Auth::user()->password = Hash::make($request->newpass);
|
||||
Auth::user()->save();
|
||||
|
||||
Auth::logout();
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect(route('login'));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __('Your account already has a password.'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a user's password and removes their discord information from storage
|
||||
*
|
||||
* @param User $user
|
||||
* @param SetNewPasswordRequest $request
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function unlinkDiscordAccount(Request $request, DiscordService $discordService)
|
||||
{
|
||||
if ($request->user()->hasPassword()) {
|
||||
try {
|
||||
$discordService->revokeAccountTokens(Auth::user());
|
||||
Log::warning('Revoking social account tokens, user initiated', [
|
||||
'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
|
||||
*
|
||||
* @param ChangeEmailRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function changeEmail(ChangeEmailRequest $request)
|
||||
{
|
||||
$this->disable();
|
||||
if (config('demo.is_enabled')) {
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __('This feature is disabled'));
|
||||
}
|
||||
|
||||
$user = User::find(Auth::user()->id);
|
||||
|
||||
@@ -351,68 +184,13 @@ 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) {
|
||||
|
||||
$this->authorize('adminEdit', $user);
|
||||
|
||||
if ($user->hasPassword()) {
|
||||
$user->notify(new PasswordAdminResetNotification());
|
||||
|
||||
$user->password = null;
|
||||
$user->save();
|
||||
|
||||
|
||||
Log::alert("Removed account password", [
|
||||
'target' => $user,
|
||||
'actor' => Auth::user()
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('success', __('Account password removed.'));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->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) {
|
||||
|
||||
Auth::user()->dob = $request->dob;
|
||||
Auth::user()->save();
|
||||
|
||||
return redirect()
|
||||
->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)
|
||||
{
|
||||
$this->disable();
|
||||
if (config('demo.is_enabled')) {
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', _('This feature is disabled'));
|
||||
}
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
@@ -426,19 +204,14 @@ 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)
|
||||
{
|
||||
if (config('demo.is_enabled')) {
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __('This feature is disabled'));
|
||||
}
|
||||
$this->authorize('adminEdit', $user);
|
||||
$this->disable();
|
||||
|
||||
// Mass update would not be possible here without extra code, making route model binding useless
|
||||
$user->email = $request->email;
|
||||
@@ -470,16 +243,6 @@ 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
|
||||
*/
|
||||
public function add2FASecret(Add2FASecretRequest $request)
|
||||
{
|
||||
if (config('demo.is_enabled')) {
|
||||
@@ -522,13 +285,6 @@ class UserController extends Controller
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the current user's two factor secret key
|
||||
*
|
||||
* @param Remove2FASecretRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function remove2FASecret(Remove2FASecretRequest $request)
|
||||
{
|
||||
Log::warning('SECURITY: Disabling two factor authentication (user initiated)', [
|
||||
@@ -544,94 +300,34 @@ class UserController extends Controller
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given user's two factor secret key
|
||||
*
|
||||
* @param Reset2FASecretRequest $request
|
||||
* @param User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
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)', [
|
||||
'initiator' => $request->user()->email,
|
||||
'target' => $user->email,
|
||||
'ip' => $request->ip(),
|
||||
]);
|
||||
|
||||
$user->twofa_secret = null;
|
||||
$user->password = null;
|
||||
$user->save();
|
||||
|
||||
$user->notify(new TwoFactorResetNotification());
|
||||
|
||||
public function terminate(Request $request, User $user)
|
||||
{
|
||||
$this->authorize('terminate', User::class);
|
||||
if (config('demo.is_enabled')) {
|
||||
return redirect()
|
||||
->back()
|
||||
->with('success', __('Two factor removed & user notified.'));
|
||||
->with('error', __('This feature is disabled'));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', 'This user does not have two-factor authentication enabled.');
|
||||
}
|
||||
// TODO: move logic to policy
|
||||
if (! $user->isStaffMember() || $user->is(Auth::user())) {
|
||||
$request->session()->flash('error', __('You cannot terminate this user.'));
|
||||
|
||||
/**
|
||||
* Suspend the given user
|
||||
*
|
||||
* @param AccountSuspensionService $suspensionService
|
||||
* @param BanUserRequest $request
|
||||
* @param User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function suspend(AccountSuspensionService $suspensionService, BanUserRequest $request, User $user)
|
||||
{
|
||||
$this->authorize('create', [Ban::class, $user]);
|
||||
$this->disable();
|
||||
|
||||
if ($suspensionService->isSuspended($user))
|
||||
{
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __('Account already suspended.'));
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
if ($request->suspensionType = "on") {
|
||||
$suspensionService->suspend($user, $request->reason, $request->duration);
|
||||
}
|
||||
else {
|
||||
$suspensionService->suspend($user, $request->reason);
|
||||
foreach ($user->roles as $role) {
|
||||
if ($role->name == 'user') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$user->removeRole($role->name);
|
||||
}
|
||||
|
||||
Log::info('User '.$user->name.' has just been demoted.');
|
||||
$request->session()->flash('success', __('User terminated successfully.'));
|
||||
|
||||
//TODO: Dispatch event
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsuspend the given user
|
||||
*
|
||||
* @param AccountSuspensionService $suspensionService
|
||||
* @param Request $request
|
||||
* @param User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function unsuspend(AccountSuspensionService $suspensionService, Request $request, User $user)
|
||||
{
|
||||
$this->authorize('delete', $user->bans);
|
||||
$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();
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user