<?php
namespace App\Http\Controllers;
use App\Folder;
use App\Mailbox;
use App\Subscription;
use App\Thread;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Validation\Rule;
use Validator;
class UsersController extends Controller
{
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
* Users list.
*/
public function users()
{
$this->authorize('create', 'App\User');
$users_query = User::nonDeleted();
if (!auth()->user()->isAdmin()) {
$users_query->where('role', User::ROLE_USER);
}
$users = $users_query->get();
$users = User::sortUsers($users);
return view('users/users', ['users' => $users]);
}
* New user.
*/
public function create()
{
$this->authorize('create', 'App\User');
$mailboxes = Mailbox::all();
return view('users/create', ['mailboxes' => $mailboxes]);
}
* Create new user.
*
* @param \Illuminate\Http\Request $request
*/
public function createSave(Request $request)
{
$invalid = false;
$this->authorize('create', 'App\User');
$auth_user = auth()->user();
$rules = [
'first_name' => 'required|string|max:20',
'last_name' => 'max:30',
'email' => 'required|string|email|max:100|unique:users',
];
if ($auth_user->isAdmin()) {
$rules['role'] = ['required', Rule::in(array_keys(User::$roles))];
}
if (empty($request->send_invite)) {
$rules['password'] = 'required|string|max:255';
}
$validator = Validator::make($request->all(), $rules);
if (User::mailboxEmailExists($request->email)) {
$invalid = true;
$validator->errors()->add('email', __('There is a mailbox with such email. Users and mailboxes can not have the same email addresses.'));
}
if ($invalid || $validator->fails()) {
return redirect()->route('users.create')
->withErrors($validator)
->withInput();
}
$password = '';
if (empty($request->send_invite)) {
$password = $request->password;
} else {
$password = User::generateRandomPassword();
}
$data = [
'first_name' => $request->first_name,
'last_name' => $request->last_name ?? '',
'email' => $request->email,
'password' => $password,
];
$user = User::create($data);
if (!$auth_user->can('changeRole', $user)) {
$user->role = User::ROLE_USER;
} elseif (array_key_exists($request->role, User::$roles)) {
$user->role = $request->role;
}
$user->timezone = config('app.timezone') ?: User::DEFAULT_TIMEZONE;
$user = \Eventy::filter('user.create_save', $user, $request);
$user->save();
$user->mailboxes()->sync($request->mailboxes ?: []);
$user->syncPersonalFolders($request->mailboxes);
if (!empty($request->send_invite)) {
try {
$user->sendInvite(true);
} catch (\Exception $e) {
\Session::flash('flash_error_floating', $e->getMessage().' — '.__('Check mail settings in "Manage » Settings » Mail Settings"'));
}
}
\Session::flash('flash_success_floating', __('User created successfully'));
return redirect()->route('users.profile', ['id' => $user->id]);
}
* User profile.
*/
public function profile($id)
{
$user = User::findOrFail($id);
if ($user->isDeleted()) {
abort(404);
}
$this->authorize('update', $user);
$users = $this->getUsersForSidebar($id);
return view('users/profile', ['user' => $user, 'users' => $users]);
}
public function getUsersForSidebar($except_id)
{
if (auth()->user()->isAdmin()) {
return User::sortUsers(User::nonDeleted()->get());
} else {
return [];
}
}
* Handle a registration request for the application.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function profileSave($id, Request $request)
{
$invalid = false;
$user = User::findOrFail($id);
$this->authorize('update', $user);
$auth_user = auth()->user();
$validator = Validator::make($request->all(), [
'first_name' => 'required|string|max:20',
'last_name' => 'max:30',
'email' => 'required|string|email|max:100|unique:users,email,'.$id,
//'emails' => 'max:100',
'job_title' => 'max:100',
'phone' => 'max:60',
'timezone' => 'required|string|max:255',
'time_format' => 'required',
'role' => ['nullable', Rule::in(array_keys(User::$roles))],
'photo_url' => 'nullable|image|mimes:jpeg,png,jpg,gif',
]);
$validator->setAttributeNames([
'photo_url' => __('Photo'),
]);
$validator->after(function ($validator) use ($user, $request) {
if ($request->hasFile('photo_url')) {
$path_url = $user->savePhoto($request->file('photo_url'));
if ($path_url) {
$user->photo_url = $path_url;
} else {
$invalid = true;
$validator->errors()->add('photo_url', __('Error occurred processing the image. Make sure that PHP GD extension is enabled.'));
}
}
if ($user->isAdmin() && isset($request->role) && $request->role != User::ROLE_ADMIN) {
$admins_count = User::where('role', User::ROLE_ADMIN)->count();
if ($admins_count < 2) {
$invalid = true;
$validator->errors()->add('role', __('Role of the only one administrator can not be changed.'));
}
}
});
if (User::mailboxEmailExists($request->email)) {
$invalid = true;
$validator->errors()->add('email', __('There is a mailbox with such email. Users and mailboxes can not have the same email addresses.'));
}
if ($invalid || $validator->fails()) {
return redirect()->route('users.profile', ['id' => $id])
->withErrors($validator)
->withInput();
}
if ($auth_user->id == $id && $request->locale) {
session()->put('user_locale', $request->locale);
}
$request_data = $request->all();
if (isset($request_data['photo_url'])) {
unset($request_data['photo_url']);
}
if (!$auth_user->can('changeRole', $user)) {
unset($request_data['role']);
}
if ($user->status != User::STATUS_DELETED) {
if (!empty($request_data['disabled'])) {
$request_data['status'] = User::STATUS_DISABLED;
} else {
$request_data['status'] = User::STATUS_ACTIVE;
}
}
$admin_fields = [
'role',
'status',
'email',
'only_assigned_tickets',
];
$nonfillable_fields = [
'type',
'password',
];
if (!$auth_user->isAdmin()) {
foreach ($admin_fields as $field) {
if (isset($request_data[$field])) {
unset($request_data[$field]);
}
}
}
foreach ($nonfillable_fields as $field) {
if (isset($request_data[$field])) {
unset($request_data[$field]);
}
}
$user->setData($request_data);
if ($auth_user->isAdmin() && !$user->isAdmin()) {
if (!empty($request_data['only_assigned_tickets'])) {
$user->addPermission(User::PERM_ONLY_ASSIGNED_TICKETS, false);
} else {
$user->removePermission(User::PERM_ONLY_ASSIGNED_TICKETS, false);
}
}
$user = \Eventy::filter('user.save_profile', $user, $request);
$user->save();
\Session::flash('flash_success_floating', __('Profile saved successfully'));
return redirect()->route('users.profile', ['id' => $id]);
}
* User permissions.
*/
public function permissions($id)
{
$user = auth()->user();
if (!$user->isAdmin()) {
abort(403);
}
$user = User::findOrFail($id);
if ($user->isDeleted()) {
abort(404);
}
$mailboxes = Mailbox::all()->sortBy('name');
$users = $this->getUsersForSidebar($id);
return view('users/permissions', [
'user' => $user,
'mailboxes' => $mailboxes,
'user_mailboxes' => $user->mailboxes,
'users' => $users,
]);
}
* Save user permissions.
*
* @param int $id
* @param \Illuminate\Http\Request $request
*/
public function permissionsSave($id, Request $request)
{
$user = auth()->user();
if (!$user->isAdmin()) {
abort(403);
}
$user = User::findOrFail($id);
$user->mailboxes()->sync($request->mailboxes ?: []);
$user->syncPersonalFolders($request->mailboxes);
$user_permissions = $request->user_permissions ?? [];
$permissions = [];
foreach (User::getUserPermissionsList() as $permission_id) {
$new_has_permission = in_array($permission_id, $user_permissions);
if ($user->hasPermission($permission_id, false) != $new_has_permission) {
$permissions[$permission_id] = (int)(bool)$new_has_permission;
$save_user = true;
}
}
$user->permissions = $permissions;
$user->save();
\Session::flash('flash_success_floating', __('Permissions saved successfully'));
return redirect()->route('users.permissions', ['id' => $id]);
}
* User notifications settings.
*/
public function notifications($id)
{
$user = User::findOrFail($id);
$this->authorize('updateNotifications', $user);
if ($user->isDeleted()) {
abort(404);
}
$subscriptions = $user->subscriptions()->select('medium', 'event')->get();
$person = '';
if ($id != auth()->user()->id) {
$person = $user->getFirstName(true);
}
$users = $this->getUsersForSidebar($id);
return view('users/notifications', [
'user' => $user,
'subscriptions' => $subscriptions,
'person' => $person,
'users' => $users,
'mobile_available' => \Eventy::filter('notifications.mobile_available', false),
]);
}
* Save user notifications settings.
*
* @param int $id
* @param \Illuminate\Http\Request $request
*/
public function notificationsSave($id, Request $request)
{
$user = User::findOrFail($id);
$this->authorize('updateNotifications', $user);
Subscription::saveFromArray($request->subscriptions, $user->id);
\Session::flash('flash_success_floating', __('Notifications saved successfully'));
return redirect()->route('users.notifications', ['id' => $id]);
}
* Users ajax controller.
*/
public function ajax(Request $request)
{
$response = [
'status' => 'error',
'msg' => '',
];
$auth_user = auth()->user();
switch ($request->action) {
case 'send_invite':
if (!$auth_user->isAdmin()) {
$response['msg'] = __('Not enough permissions');
}
if (empty($request->user_id)) {
$response['msg'] = __('Incorrect user');
}
if (!$response['msg']) {
$user = User::find($request->user_id);
if (!$user) {
$response['msg'] = __('User not found');
} elseif ($user->invite_state == User::INVITE_STATE_ACTIVATED) {
$response['msg'] = __('User already accepted invitation');
}
}
if (!$response['msg']) {
try {
$user->sendInvite(true);
$response['status'] = 'success';
} catch (\Exception $e) {
$response['msg'] = $e->getMessage().' — '.__('Check mail settings in "Manage » Settings » Mail Settings"');
}
}
break;
case 'reset_password':
if (!auth()->user()->isAdmin()) {
$response['msg'] = __('Not enough permissions');
}
if (empty($request->user_id)) {
$response['msg'] = __('Incorrect user');
}
if (!$response['msg']) {
$user = User::find($request->user_id);
if (!$user) {
$response['msg'] = __('User not found');
}
}
if (!$response['msg']) {
$reset_result = Password::broker()->sendResetLink(
//['id' => $request->user_id]
['id' => $request->user_id]
);
if ($reset_result == Password::RESET_LINK_SENT) {
$response['status'] = 'success';
$response['msg_success'] = __('Password reset email has been sent');
}
}
break;
case 'web_notifications':
if (!$auth_user) {
$response['msg'] = __('You are not logged in');
}
if (!$response['msg']) {
$web_notifications_info = $auth_user->getWebsiteNotificationsInfo(false);
$response['html'] = view('users/partials/web_notifications', [
'web_notifications_info_data' => $web_notifications_info['data'],
])->render();
$response['has_more_pages'] = (int) $web_notifications_info['notifications']->hasMorePages();
$response['status'] = 'success';
}
break;
case 'mark_notifications_as_read':
if (!$auth_user) {
$response['msg'] = __('You are not logged in');
}
if (!$response['msg']) {
$auth_user->unreadNotifications()->update(['read_at' => now()]);
$auth_user->clearWebsiteNotificationsCache();
$response['status'] = 'success';
}
break;
case 'delete_photo':
$user = User::find($request->user_id);
if (!$user) {
$response['msg'] = __('User not found');
} elseif (!$auth_user->can('update', $user)) {
$response['msg'] = __('Not enough permissions');
}
if (!$response['msg']) {
$user->removePhoto();
$user->save();
$response['status'] = 'success';
}
break;
case 'delete_user':
$user = User::find($request->user_id);
if (!$user) {
$response['msg'] = __('User not found');
} elseif (!$auth_user->can('delete', $user)) {
$response['msg'] = __('Not enough permissions');
} elseif ($auth_user->id == $user->id) {
$response['msg'] = __('Not enough permissions');
}
if (!$response['msg']) {
$user->deleteUser($auth_user, $request->assign_user);
\Session::flash('flash_success_floating', __('User deleted').': '.htmlspecialchars($user->getFullName()));
$response['status'] = 'success';
}
break;
default:
$response['msg'] = 'Unknown action';
$response = \Eventy::filter('users.ajax.response_default', $response, $request);
break;
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);
}
* Change user password.
*/
public function password($id)
{
$user = User::findOrFail($id);
$this->authorize('update', $user);
$users = User::all()->except($id);
return view('users/password', ['user' => $user, 'users' => $users]);
}
* Save changed user password.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function passwordSave($id, Request $request)
{
$user = auth()->user();
if ($user->id != $id) {
abort(403);
}
$validator = Validator::make($request->all(), [
'password_current' => 'required|string',
'password' => 'required|string|min:8|confirmed',
]);
$validator->after(function ($validator) use ($user, $request) {
// Check current password
if (!Hash::check($request->password_current, $user->password)) {
$validator->errors()->add('password_current', __('This password is incorrect.'));
} elseif (Hash::check($request->password, $user->password)) {
$validator->errors()->add('password', __('The new password is the same as the old password.'));
}
});
if ($validator->fails()) {
return redirect()->route('users.password', ['id' => $id])
->withErrors($validator)
->withInput();
}
$user->password = bcrypt($request->password);
$user->save();
$user->sendPasswordChanged();
\Session::flash('flash_success_floating', __('Password saved successfully!'));
return redirect()->route('users.profile', ['id' => $id]);
}
}