Passed
Push — master ( 1d6d9a...2a90e7 )
by Ron
02:47 queued 12s
created

UserController::create()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 17
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 31
ccs 17
cts 17
cp 1
crap 6
rs 9.0777
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
    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
            'username'  => $user->username,
68 8
            'active'    => $user->deleted_at == null ? 1 : 0,
69
        ]);
70
    }
71
72
    //  Show the Add User form
73 8
    public function create()
74
    {
75 8
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
76
77 8
        $roles = UserRoleType::all();
78 8
        $roleArr = [];
79
        //  Cycle through the roles and determine if admin and installer roles should be removed
80 8
        foreach($roles as $role)
81
        {
82 8
            if($role->role_id == 1 && Auth::user()->role_id != 1)
83
            {
84 4
                Log::debug('Installer Role skipped for User '.Auth::user()->full_name);
85 4
                continue;
86
            }
87 8
            else if($role->role_id == 2 && Auth::user()->role_id > 2)
88
            {
89 2
                Log::debug('Admin Role skipped for User '.Auth::user()->full_name);
90 2
                continue;
91
            }
92
            else
93
            {
94 8
                $roleArr[] = [
95 8
                    'value' => $role->role_id,
96 8
                    'text'  => $role->name,
97
                ];
98
            }
99
        }
100
101 8
        Log::debug('Role data gathered: ', $roleArr);
102 8
        return view('admin.newUser', [
103 8
            'roles' => $roleArr
104
        ]);
105
    }
106
107
    //  Submit the Add User form
108 16
    public function store(Request $request)
109
    {
110 16
        Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name.'. Submitted Data:', $request->toArray());
111
112
        //  Validate the new user form
113 16
        $request->validate([
114 16
            'role'       => 'required|numeric|exists:user_role_types,role_id',
115
            'username'   => 'required|unique:users|regex:/^[a-zA-Z0-9_]*$/',
116
            'first_name' => 'required',
117
            'last_name'  => 'required',
118
            'email'      => 'required|unique:users',
119
        ]);
120
121
        //  Create the user
122 2
        $newUser = User::create([
123 2
            'role_id'    => $request->role,
124 2
            'username'   => $request->username,
125 2
            'first_name' => $request->first_name,
126 2
            'last_name'  => $request->last_name,
127 2
            'email'      => $request->email,
128 2
            'password'   => bcrypt(strtolower(Str::random(15))),
129
        ]);
130 2
        $userID = $newUser->user_id;
131 2
        Log::debug('New User created.  Data - ', $newUser->toArray());
132
        //  Create the user settings table
133 2
        UserSettings::create([
134 2
            'user_id' => $userID,
135
        ]);
136 2
        Log::debug('User Settings table created for user ID '.$userID);
137
138
        //  Create the setup user link
139 2
        $hash = strtolower(Str::random(30));
140 2
        UserInitialize::create([
141 2
            'username' => $request->username,
142 2
            'token'    => $hash
143
        ]);
144 2
        Log::debug('User Initialize link created for User ID '.$userID.'. New Link Hash - '.$hash);
145
146
        //  Email the new user
147 2
        Notification::send($newUser, new NewUserEmail($newUser, $hash));
148
149 2
        Log::notice('New user '.$newUser->first_name.' '.$newUser->last_name.' created by '.Auth::user()->full_name.'. User Data:', $newUser->toArray());
150
151
        // return redirect()->back()->with('success', 'New User Created');
152 2
        return response()->json(['success' => true]);
153
    }
154
155
    //  List all inactive users
156 6
    public function show($type)
157
    {
158 6
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
159 6
        $route = '';
160
161 6
        if($type !== 'inactive')
162
        {
163 2
            Log::error('Someone tried to access the Inactive Users link with an improper argument - Argument: '.$type);
164 2
            return abort(404);
165
        }
166 4
        $userList = new UserCollection(User::onlyTrashed()->get()
167
                /** @scrutinizer ignore-call */
168 4
                ->makeVisible('user_id')
169 4
                ->makeVisible('deleted_at'));
170
171 4
        Log::debug('List of inactive users - ', array($userList));
172 4
        return view('admin.userDeleted', [
173 4
            'userList' => $userList,
174 4
            'route'    => $route,
175
        ]);
176
    }
177
178
    //  Reactivate a disabled user
179 4
    public function reactivateUser($id)
180
    {
181 4
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
182 4
        User::withTrashed()->where('user_id', $id)->restore();
183
184 4
        Log::notice('User ID ' . $id . ' reactivated by ' . Auth::user()->full_name);
185 4
        return response()->json([
186 4
            'success' => true,
187
        ]);
188
    }
189
190
    //  Open the edit user form
191 12
    public function edit($id)
192
    {
193 12
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
194
195 12
        $roles = UserRoleType::all();
196 12
        $user  = new UserResource(User::findOrFail($id));
197
198
        //  Make sure that the user is not trying to edit someone with more permissions
199 10
        if(($user->role_id == 1 || $user->role_id == 2) && Auth::user()->role_id <=2)
200
        {
201 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.');
202 2
            return abort(403);
203
        }
204
205 8
        Log::debug('User Data gathered - ', array($user));
206
207
        //  Good to go - get role information
208 8
        $roleArr = [];
209 8
        foreach ($roles as $role)
210
        {
211 8
            if ($role->role_id == 1 && Auth::user()->role_id != 1)
212
            {
213 4
                continue;
214
            }
215 8
            else if ($role->role_id == 2 && Auth::user()->role_id > 2)
216
            {
217 2
                continue;
218
            }
219
            else
220
            {
221
                // $roleArr[$role->role_id] = $role->name;
222 8
                $roleArr[] = [
223 8
                    'value' => $role->role_id,
224 8
                    'text'  => $role->name,
225
                ];
226
            }
227
        }
228
229 8
        Log::debug('Role Data gathered:', $roleArr);
230 8
        return view('admin.userEdit', [
231 8
            'roles' => $roleArr,
232
            'user'  => $user->
233
            /** @scrutinizer ignore-call */
234 8
            makeVisible(['user_id', 'username']),
235
        ]);
236
    }
237
238
    //  Submit the update user form
239 22
    public function update(Request $request, $id)
240
    {
241 22
        Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name.'. Submitted Data:', $request->toArray());
242
243 22
        $request->validate([
244
            'username'   => [
245 22
                                'required',
246 22
                                Rule::unique('users')->ignore($id, 'user_id')
247
                            ],
248 22
            'first_name' => 'required',
249 22
            'last_name'  => 'required',
250
            'email'      => [
251 22
                                'required',
252 22
                                Rule::unique('users')->ignore($id, 'user_id')
253
                            ],
254 22
            'role'       => 'required',
255
        ]);
256
257
        //  Update the user data
258 8
        $user = User::findOrFail($id);
259 6
        if($user->role_id < Auth::user()->role_id)
260
        {
261 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.');
262 2
            return abort(403);
263
        }
264
265 4
        $user->update(
266
        [
267 4
            'username'   => $request->username,
268 4
            'first_name' => $request->first_name,
269 4
            'last_name'  => $request->last_name,
270 4
            'email'      => $request->email,
271 4
            'role_id'    => $request->role,
272
        ]);
273
274
        //  Update the user's role
275 4
        Log::info('User information for '.$request->first_name.' '.$request->last_name.' (ID: '.$id.') has been updated by '.Auth::user()->full_name);
276 4
        return response()->json(['success' => true]);
277
    }
278
279
    //  Submit the change password form
280 12
    public function submitPassword(Request $request)
281
    {
282 12
        Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name);
283
284 12
        $request->validate([
285 12
            'password' => 'required|string|min:6|confirmed',
286
            'user_id'  => 'required',
287
        ]);
288
289 8
        if($request->force_change)
290
        {
291 6
            $nextChange = Carbon::now()->subDay();
292
        }
293
        else
294
        {
295 2
            $nextChange = config('auth.passwords.settings.expire') != null ? Carbon::now()->addDays(config('auth.passwords.settings.expire')) : null;
296
        }
297
298 8
        $user = User::find($request->user_id);
299
300
        //  Verify this is a valid user ID
301 8
        if (!$user)
302
        {
303 2
            $success = false;
304 2
            $reason  = 'Cannot find user with this ID';
305
        }
306
        //  Make sure that the user is not trying to deactivate someone with more permissions
307 6
        else if ($user->role_id < Auth::user()->role_id)
308
        {
309 2
            $success = false;
310 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.';
311
        }
312
        //  Good to go - update user password
313
        else
314
        {
315
            //  Update the user data
316 4
            $user->update(
317
            [
318 4
                'password'         => bcrypt($request->password),
319 4
                'password_expires' => $nextChange
320
            ]);
321 4
            $success = true;
322 4
            $reason  = 'Password for '.$user->full_name.' successfully reset.';
323
        }
324
325 8
        Log::notice('User ID-'.$request->user_id.' password chagned by '.Auth::user()->Full_name, [
326 8
            'success' => $success,
327 8
            'reason'  => $reason,
328
        ]);
329
330 8
        return response()->json([
331 8
            'success' => $success,
332 8
            'reason'  => $reason,
333
        ]);
334
    }
335
336
    //  Disable the user
337 8
    public function destroy($id)
338
    {
339 8
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
340
341 8
        $user = User::find($id);
342
343
        //  Verify this is a valid user ID
344 8
        if(!$user)
345
        {
346 2
            $success = false;
347 2
            $reason  = 'Cannot find user with this ID';
348
        }
349
        //  Make suer that the user is not trying to deactivate themselves
350 6
        else if(Auth::user()->user_id == $id)
351
        {
352 2
            $success = false;
353 2
            $reason  = 'You cannot deactivate yourself';
354
        }
355
        //  Make sure that the user is not trying to deactivate someone with more permissions
356 4
        else if($user->role_id < Auth::user()->role_id)
357
        {
358 2
            $success = false;
359 2
            $reason  = 'You cannot deactivate a user with higher permissions that you.';
360
        }
361
        //  Good to go - deactivate user
362
        else
363
        {
364
            // $user->update(['active' => 0]);
365 2
            $user->delete();
366 2
            $success = true;
367 2
            $reason  = 'User '.$user->full_name.' successfully deactivated.';
368
        }
369
370 8
        Log::notice('User ID-'.$id.' disabled by '.Auth::user()->full_name, [
371 8
            'success' => $success,
372 8
            'reason'  => $reason,
373
        ]);
374
375 8
        return response()->json([
376 8
            'success' => $success,
377 8
            'reason'  => $reason,
378
        ]);
379
    }
380
}
381