1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace App\Http\Controllers\Admin; |
4
|
|
|
|
5
|
|
|
use App\User; |
6
|
|
|
use Carbon\Carbon; |
7
|
|
|
use App\UserSettings; |
8
|
|
|
use App\UserRoleType; |
9
|
|
|
use App\UserInitialize; |
10
|
|
|
use Illuminate\Support\Str; |
11
|
|
|
use Illuminate\Http\Request; |
12
|
|
|
use Illuminate\Validation\Rule; |
13
|
|
|
use App\Notifications\NewUserEmail; |
14
|
|
|
use Illuminate\Support\Facades\Log; |
15
|
|
|
use Illuminate\Support\Facades\Auth; |
16
|
|
|
use App\Http\Controllers\Controller; |
17
|
|
|
use Illuminate\Support\Facades\Route; |
18
|
|
|
use App\Http\Resources\UserCollection; |
19
|
|
|
use App\Http\Resources\User as UserResource; |
20
|
|
|
use Illuminate\Support\Facades\Notification; |
21
|
|
|
|
22
|
|
|
class UserController extends Controller |
23
|
|
|
{ |
24
|
|
|
// Constructor sets up middleware |
25
|
142 |
|
public function __construct() |
26
|
|
|
{ |
27
|
142 |
|
$this->middleware('auth')->except('initializeUser', 'submitInitializeUser'); |
28
|
|
|
$this->middleware(function($request, $next) { |
29
|
122 |
|
$this->authorize('hasAccess', 'Manage Users'); |
30
|
102 |
|
return $next($request); |
31
|
142 |
|
}); |
32
|
142 |
|
} |
33
|
|
|
|
34
|
|
|
// Show the list of current users to edit |
35
|
2 |
View Code Duplication |
public function index() |
|
|
|
|
36
|
|
|
{ |
37
|
2 |
|
Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name); |
|
|
|
|
38
|
|
|
|
39
|
2 |
|
$userList = User::with('LastUserLogin')->get()->makeVisible('user_id'); |
40
|
2 |
|
$route = 'admin.user.edit'; |
41
|
|
|
|
42
|
2 |
|
Log::debug('User list:', $userList->toArray()); |
43
|
|
|
|
44
|
2 |
|
return view('admin.userIndex', [ |
45
|
2 |
|
'userList' => $userList, |
46
|
2 |
|
'route' => $route, |
47
|
|
|
]); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
// Check if a username is in use |
51
|
12 |
|
public function checkUser($username, $type) |
52
|
|
|
{ |
53
|
12 |
|
Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name.'. Submitted Data:', ['username' => $username, 'type' => $type]); |
|
|
|
|
54
|
|
|
|
55
|
12 |
|
$user = User::where($type, $username)->first(); |
56
|
|
|
|
57
|
12 |
|
if(!$user) |
58
|
|
|
{ |
59
|
4 |
|
Log::debug('Username '.$username.' is available for use'); |
60
|
4 |
|
return response()->json(['duplicate' => false]); |
|
|
|
|
61
|
|
|
} |
62
|
|
|
|
63
|
8 |
|
Log::debug('Username '.$username.' is in use by '.$user->full_name); |
64
|
8 |
|
return response()->json([ |
65
|
8 |
|
'duplicate' => true, |
66
|
8 |
|
'user' => $user->full_name, |
67
|
8 |
|
'active' => $user->deleted_at == null ? 1 : 0, |
68
|
|
|
]); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
// Show the Add User form |
72
|
8 |
|
public function create() |
73
|
|
|
{ |
74
|
8 |
|
Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name); |
|
|
|
|
75
|
|
|
|
76
|
8 |
|
$roles = UserRoleType::all(); |
77
|
8 |
|
$roleArr = []; |
78
|
|
|
// Cycle through the roles and determine if admin and installer roles should be removed |
79
|
8 |
|
foreach($roles as $role) |
80
|
|
|
{ |
81
|
8 |
|
if($role->role_id == 1 && Auth::user()->role_id != 1) |
|
|
|
|
82
|
|
|
{ |
83
|
4 |
|
Log::debug('Installer Role skipped for User '.Auth::user()->full_name); |
|
|
|
|
84
|
4 |
|
continue; |
85
|
|
|
} |
86
|
8 |
|
else if($role->role_id == 2 && Auth::user()->role_id > 2) |
|
|
|
|
87
|
|
|
{ |
88
|
2 |
|
Log::debug('Admin Role skipped for User '.Auth::user()->full_name); |
|
|
|
|
89
|
2 |
|
continue; |
90
|
|
|
} |
91
|
|
|
else |
92
|
|
|
{ |
93
|
8 |
|
$roleArr[] = [ |
94
|
8 |
|
'value' => $role->role_id, |
95
|
8 |
|
'text' => $role->name, |
96
|
|
|
]; |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
|
100
|
8 |
|
Log::debug('Role data gathered: ', $roleArr); |
101
|
8 |
|
return view('admin.newUser', [ |
102
|
8 |
|
'roles' => $roleArr |
103
|
|
|
]); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
// Submit the Add User form |
107
|
16 |
|
public function store(Request $request) |
108
|
|
|
{ |
109
|
16 |
|
Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name.'. Submitted Data:', $request->toArray()); |
|
|
|
|
110
|
|
|
|
111
|
|
|
// Validate the new user form |
112
|
16 |
|
$request->validate([ |
|
|
|
|
113
|
16 |
|
'role' => 'required|numeric|exists:user_role_types,role_id', |
114
|
|
|
'username' => 'required|unique:users|regex:/^[a-zA-Z0-9_]*$/', |
115
|
|
|
'first_name' => 'required', |
116
|
|
|
'last_name' => 'required', |
117
|
|
|
'email' => 'required|unique:users', |
118
|
|
|
]); |
119
|
|
|
|
120
|
|
|
// Create the user |
121
|
2 |
|
$newUser = User::create([ |
|
|
|
|
122
|
2 |
|
'role_id' => $request->role, |
123
|
2 |
|
'username' => $request->username, |
124
|
2 |
|
'first_name' => $request->first_name, |
125
|
2 |
|
'last_name' => $request->last_name, |
126
|
2 |
|
'email' => $request->email, |
127
|
2 |
|
'password' => bcrypt(strtolower(Str::random(15))), |
128
|
|
|
]); |
129
|
2 |
|
$userID = $newUser->user_id; |
130
|
2 |
|
Log::debug('New User created. Data - ', $newUser->toArray()); |
131
|
|
|
// Create the user settings table |
132
|
2 |
|
UserSettings::create([ |
|
|
|
|
133
|
2 |
|
'user_id' => $userID, |
134
|
|
|
]); |
135
|
2 |
|
Log::debug('User Settings table created for user ID '.$userID); |
136
|
|
|
|
137
|
|
|
// Create the setup user link |
138
|
2 |
|
$hash = strtolower(Str::random(30)); |
139
|
2 |
|
UserInitialize::create([ |
|
|
|
|
140
|
2 |
|
'username' => $request->username, |
141
|
2 |
|
'token' => $hash |
142
|
|
|
]); |
143
|
2 |
|
Log::debug('User Initialize link created for User ID '.$userID.'. New Link Hash - '.$hash); |
144
|
|
|
|
145
|
|
|
// Email the new user |
146
|
2 |
|
Notification::send($newUser, new NewUserEmail($newUser, $hash)); |
147
|
|
|
|
148
|
2 |
|
Log::notice('New user '.$newUser->first_name.' '.$newUser->last_name.' created by '.Auth::user()->full_name.'. User Data:', $newUser->toArray()); |
|
|
|
|
149
|
|
|
|
150
|
|
|
// return redirect()->back()->with('success', 'New User Created'); |
151
|
2 |
|
return response()->json(['success' => true]); |
|
|
|
|
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
// List all inactive users |
155
|
6 |
|
public function show($type) |
156
|
|
|
{ |
157
|
6 |
|
Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name); |
|
|
|
|
158
|
6 |
|
$route = ''; |
159
|
|
|
|
160
|
6 |
|
if($type !== 'inactive') |
161
|
|
|
{ |
162
|
2 |
|
Log::error('Someone tried to access the Inactive Users link with an improper argument - Argument: '.$type); |
163
|
2 |
|
return abort(404); |
164
|
|
|
} |
165
|
4 |
|
$userList = new UserCollection(User::onlyTrashed()->get() |
|
|
|
|
166
|
|
|
/** @scrutinizer ignore-call */ |
167
|
4 |
|
->makeVisible('user_id') |
168
|
4 |
|
->makeVisible('deleted_at')); |
169
|
|
|
|
170
|
4 |
|
Log::debug('List of inactive users - ', array($userList)); |
171
|
4 |
|
return view('admin.userDeleted', [ |
172
|
4 |
|
'userList' => $userList, |
173
|
4 |
|
'route' => $route, |
174
|
|
|
]); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
// Reactivate a disabled user |
178
|
4 |
|
public function reactivateUser($id) |
179
|
|
|
{ |
180
|
4 |
|
Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name); |
|
|
|
|
181
|
4 |
|
User::withTrashed()->where('user_id', $id)->restore(); |
|
|
|
|
182
|
|
|
|
183
|
4 |
|
Log::notice('User ID ' . $id . ' reactivated by ' . Auth::user()->full_name); |
|
|
|
|
184
|
4 |
|
return response()->json([ |
|
|
|
|
185
|
4 |
|
'success' => true, |
186
|
|
|
]); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
// Open the edit user form |
190
|
12 |
|
public function edit($id) |
191
|
|
|
{ |
192
|
12 |
|
Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name); |
|
|
|
|
193
|
|
|
|
194
|
12 |
|
$roles = UserRoleType::all(); |
195
|
12 |
|
$user = new UserResource(User::findOrFail($id)); |
196
|
|
|
|
197
|
|
|
// Make sure that the user is not trying to edit someone with more permissions |
198
|
10 |
|
if(($user->role_id == 1 || $user->role_id == 2) && Auth::user()->role_id <=2) |
|
|
|
|
199
|
|
|
{ |
200
|
2 |
|
Log::warning('User '.Auth::user()->full_name.' tried to update user ID '.$id.' that has more permissions than they do. This request was denied.'); |
|
|
|
|
201
|
2 |
|
return abort(403); |
202
|
|
|
} |
203
|
|
|
|
204
|
8 |
|
Log::debug('User Data gathered - ', array($user)); |
205
|
|
|
|
206
|
|
|
// Good to go - get role information |
207
|
8 |
|
$roleArr = []; |
208
|
8 |
|
foreach ($roles as $role) |
209
|
|
|
{ |
210
|
8 |
|
if ($role->role_id == 1 && Auth::user()->role_id != 1) |
|
|
|
|
211
|
|
|
{ |
212
|
4 |
|
continue; |
213
|
|
|
} |
214
|
8 |
|
else if ($role->role_id == 2 && Auth::user()->role_id > 2) |
|
|
|
|
215
|
|
|
{ |
216
|
2 |
|
continue; |
217
|
|
|
} |
218
|
|
|
else |
219
|
|
|
{ |
220
|
|
|
// $roleArr[$role->role_id] = $role->name; |
221
|
8 |
|
$roleArr[] = [ |
222
|
8 |
|
'value' => $role->role_id, |
223
|
8 |
|
'text' => $role->name, |
224
|
|
|
]; |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
8 |
|
Log::debug('Role Data gathered:', $roleArr); |
229
|
8 |
|
return view('admin.userEdit', [ |
230
|
8 |
|
'roles' => $roleArr, |
231
|
|
|
'user' => $user-> |
|
|
|
|
232
|
|
|
/** @scrutinizer ignore-call */ |
233
|
8 |
|
makeVisible(['user_id', 'username']), |
234
|
|
|
]); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
// Submit the update user form |
238
|
22 |
|
public function update(Request $request, $id) |
239
|
|
|
{ |
240
|
22 |
|
Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name.'. Submitted Data:', $request->toArray()); |
|
|
|
|
241
|
|
|
|
242
|
22 |
|
$request->validate([ |
|
|
|
|
243
|
|
|
'username' => [ |
244
|
22 |
|
'required', |
245
|
22 |
|
Rule::unique('users')->ignore($id, 'user_id') |
246
|
|
|
], |
247
|
22 |
|
'first_name' => 'required', |
248
|
22 |
|
'last_name' => 'required', |
249
|
|
|
'email' => [ |
250
|
22 |
|
'required', |
251
|
22 |
|
Rule::unique('users')->ignore($id, 'user_id') |
252
|
|
|
], |
253
|
22 |
|
'role' => 'required', |
254
|
|
|
]); |
255
|
|
|
|
256
|
|
|
// Update the user data |
257
|
8 |
|
$user = User::findOrFail($id); |
258
|
6 |
|
if($user->role_id < Auth::user()->role_id) |
|
|
|
|
259
|
|
|
{ |
260
|
2 |
|
Log::warning('User ' . Auth::user()->full_name . ' tried to update user ID ' . $id . ' that has more permissions than they do. This request was denied.'); |
|
|
|
|
261
|
2 |
|
return abort(403); |
262
|
|
|
} |
263
|
|
|
|
264
|
4 |
|
$user->update( |
265
|
|
|
[ |
266
|
4 |
|
'username' => $request->username, |
267
|
4 |
|
'first_name' => $request->first_name, |
268
|
4 |
|
'last_name' => $request->last_name, |
269
|
4 |
|
'email' => $request->email, |
270
|
4 |
|
'role_id' => $request->role, |
271
|
|
|
]); |
272
|
|
|
|
273
|
|
|
// Update the user's role |
274
|
4 |
|
Log::info('User information for '.$request->first_name.' '.$request->last_name.' (ID: '.$id.') has been updated by '.Auth::user()->full_name); |
|
|
|
|
275
|
4 |
|
return response()->json(['success' => true]); |
|
|
|
|
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
// Submit the change password form |
279
|
12 |
|
public function submitPassword(Request $request) |
280
|
|
|
{ |
281
|
12 |
|
Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name); |
|
|
|
|
282
|
|
|
|
283
|
12 |
|
$request->validate([ |
|
|
|
|
284
|
12 |
|
'password' => 'required|string|min:6|confirmed', |
285
|
|
|
'user_id' => 'required', |
286
|
|
|
]); |
287
|
|
|
|
288
|
8 |
|
if($request->force_change) |
289
|
|
|
{ |
290
|
6 |
|
$nextChange = Carbon::now()->subDay(); |
291
|
|
|
} |
292
|
|
|
else |
293
|
|
|
{ |
294
|
2 |
|
$nextChange = config('auth.passwords.settings.expire') != null ? Carbon::now()->addDays(config('auth.passwords.settings.expire')) : null; |
295
|
|
|
} |
296
|
|
|
|
297
|
8 |
|
$user = User::find($request->user_id); |
298
|
|
|
|
299
|
|
|
// Verify this is a valid user ID |
300
|
8 |
|
if (!$user) |
301
|
|
|
{ |
302
|
2 |
|
$success = false; |
303
|
2 |
|
$reason = 'Cannot find user with this ID'; |
304
|
|
|
} |
305
|
|
|
// Make sure that the user is not trying to deactivate someone with more permissions |
306
|
6 |
|
else if ($user->role_id < Auth::user()->role_id) |
|
|
|
|
307
|
|
|
{ |
308
|
2 |
|
$success = false; |
309
|
2 |
|
$reason = 'You cannot change password for a user with higher permissions that you. If this user has locked themselves out, have then use the reset link on the login page.'; |
310
|
|
|
} |
311
|
|
|
// Good to go - update user password |
312
|
|
|
else |
313
|
|
|
{ |
314
|
|
|
// Update the user data |
315
|
4 |
|
$user->update( |
316
|
|
|
[ |
317
|
4 |
|
'password' => bcrypt($request->password), |
318
|
4 |
|
'password_expires' => $nextChange |
319
|
|
|
]); |
320
|
4 |
|
$success = true; |
321
|
4 |
|
$reason = 'Password for '.$user->full_name.' successfully reset.'; |
322
|
|
|
} |
323
|
|
|
|
324
|
8 |
|
Log::notice('User ID-'.$request->user_id.' password chagned by '.Auth::user()->Full_name, [ |
|
|
|
|
325
|
8 |
|
'success' => $success, |
326
|
8 |
|
'reason' => $reason, |
327
|
|
|
]); |
328
|
|
|
|
329
|
8 |
|
return response()->json([ |
|
|
|
|
330
|
8 |
|
'success' => $success, |
331
|
8 |
|
'reason' => $reason, |
332
|
|
|
]); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
// Disable the user |
336
|
8 |
|
public function destroy($id) |
337
|
|
|
{ |
338
|
8 |
|
Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name); |
|
|
|
|
339
|
|
|
|
340
|
8 |
|
$user = User::find($id); |
341
|
|
|
|
342
|
|
|
// Verify this is a valid user ID |
343
|
8 |
|
if(!$user) |
344
|
|
|
{ |
345
|
2 |
|
$success = false; |
346
|
2 |
|
$reason = 'Cannot find user with this ID'; |
347
|
|
|
} |
348
|
|
|
// Make suer that the user is not trying to deactivate themselves |
349
|
6 |
|
else if(Auth::user()->user_id == $id) |
|
|
|
|
350
|
|
|
{ |
351
|
2 |
|
$success = false; |
352
|
2 |
|
$reason = 'You cannot deactivate yourself'; |
353
|
|
|
} |
354
|
|
|
// Make sure that the user is not trying to deactivate someone with more permissions |
355
|
4 |
|
else if($user->role_id < Auth::user()->role_id) |
|
|
|
|
356
|
|
|
{ |
357
|
2 |
|
$success = false; |
358
|
2 |
|
$reason = 'You cannot deactivate a user with higher permissions that you.'; |
359
|
|
|
} |
360
|
|
|
// Good to go - deactivate user |
361
|
|
|
else |
362
|
|
|
{ |
363
|
|
|
// $user->update(['active' => 0]); |
364
|
2 |
|
$user->delete(); |
365
|
2 |
|
$success = true; |
366
|
2 |
|
$reason = 'User '.$user->full_name.' successfully deactivated.'; |
367
|
|
|
} |
368
|
|
|
|
369
|
8 |
|
Log::notice('User ID-'.$id.' disabled by '.Auth::user()->full_name, [ |
|
|
|
|
370
|
8 |
|
'success' => $success, |
371
|
8 |
|
'reason' => $reason, |
372
|
|
|
]); |
373
|
|
|
|
374
|
8 |
|
return response()->json([ |
|
|
|
|
375
|
8 |
|
'success' => $success, |
376
|
8 |
|
'reason' => $reason, |
377
|
|
|
]); |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.