Passed
Push — dev5 ( df64bd...8206b9 )
by Ron
07:37
created

UserController::show()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2.004

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 16
ccs 9
cts 10
cp 0.9
crap 2.004
rs 9.9666
1
<?php
2
3
namespace App\Http\Controllers\Admin;
4
5
use DB;
6
use Mail;
7
// use App\Role;
8
use App\User;
9
use Carbon\Carbon;
10
use App\UserInitialize;
11
use Illuminate\Support\Str;
12
use App\Mail\InitializeUser;
13
use Illuminate\Http\Request;
14
use Illuminate\Validation\Rule;
15
use Illuminate\Support\Facades\Log;
16
use Illuminate\Support\Facades\Auth;
17
use App\Http\Controllers\Controller;
18
use Illuminate\Support\Facades\Route;
19
use Illuminate\Support\Facades\Notification;
20
use App\Notifications\NewUserEmail;
21
22
use App\UserRoleType;
23
use App\UserLogins;
24
use App\Http\Resources\UserCollection;
25
use App\Http\Resources\User as UserResource;
26
27
class UserController extends Controller
28
{
29
    private $user;
30
    //  Constructor sets up middleware
31 128
    public function __construct()
32
    {
33 128
        $this->middleware('auth')->except('initializeUser', 'submitInitializeUser');
34
        $this->middleware(function ($request, $next) {
35 108
            $this->user = auth()->user();  //  TODO - is this correct????
36 108
            $this->authorize('hasAccess', 'Manage Users');
37 88
            return $next($request);
38 128
        });
39 128
    }
40
41
    //  Show the list of current users to edit
42 2
    public function index()
43
    {
44
        $userList = new UserCollection(User::with(['UserLogins' => function ($query) {
45 2
            $query->latest()->limit(1);
46 2
        }])->get()
47
            /** @scrutinizer ignore-call */
48 2
            ->makeVisible('user_id'));
49 2
        $route    = 'admin.user.edit';
50
51 2
        return view('admin.userIndex', [
52 2
            'userList' => $userList,
53 2
            'route'    => $route,
54
        ]);
55
    }
56
57
    //  Check if a username is in use
58 12
    public function checkUser($username, $type)
59
    {
60 12
        $user = User::where($type, $username)->first();
61
62 12
        if(!$user)
63
        {
64 4
            return response()->json(['duplicate' => false]);
65
        }
66
67 8
        return response()->json([
68 8
            'duplicate' => true,
69 8
            'user'      => $user->full_name,
70 8
            'active'    => $user->deleted_at == null ? 1 : 0,
71
        ]);
72
    }
73
74
    //  Show the Add User form
75 2
    public function create()
76
    {
77 2
        $roles = UserRoleType::all(); // Role::all();
78
79 2
        $roleArr = [];
80 2
        foreach($roles as $role)
81
        {
82 2
            if($role->role_id == 1 && Auth::user()->role_id != 1)
83
            {
84
                continue;
85
            }
86 2
            else if($role->role_id == 2 && Auth::user()->role_id > 1)
87
            {
88
                continue;
89
            }
90
            else
91
            {
92
                // $roleArr[$role->role_id] = $role->name;
93 2
                $roleArr[] = [
94 2
                    'value' => $role->role_id,
95 2
                    'text'  => $role->name,
96
                ];
97
            }
98
        }
99
100 2
        Log::debug('Route '.Route::currentRouteName().' visited by User ID-'.Auth::user()->user_id);
101 2
        return view('admin.newUser', [
102 2
            'roles' => $roleArr
103
        ]);
104
    }
105
106
    //  Submit the Add User form
107 16
    public function store(Request $request)
108
    {
109
        //  Validate the new user form
110 16
        $request->validate([
111 16
            'role'       => 'required|numeric',  //  TODO - add validation rule - is in user roles table
112
            'username'   => 'required|unique:users|regex:/^[a-zA-Z0-9_]*$/',
113
            'first_name' => 'required',
114
            'last_name'  => 'required',
115
            'email'      => 'required|unique:users',
116
        ]);
117
118
        //  Create the user
119 2
        $newUser = User::create([
120 2
            'role_id'    => $request->role,
121 2
            'username'   => $request->username,
122 2
            'first_name' => $request->first_name,
123 2
            'last_name'  => $request->last_name,
124 2
            'email'      => $request->email,
125 2
            'password'   => bcrypt(strtolower(Str::random(15))),
126
        ]);
127
128 2
        $userID = $newUser->user_id;
129
130
        //  Create the setup user link
131 2
        $hash = strtolower(Str::random(30));
132 2
        UserInitialize::create([
133 2
            'username' => $request->username,
134 2
            'token'    => $hash
135
        ]);
136
137
        //  Email the new user
138
        // Mail::to($request->email)->send(new InitializeUser($hash, $request->username, $request->first_name.' '.$request->last_name));
139 2
        Notification::send($newUser, new NewUserEmail($newUser, $hash));
140
141 2
        Log::debug('Route '.Route::currentRouteName().' visited by User ID-'.Auth::user()->user_id);
142 2
        Log::debug('User Data - ', $newUser->toArray());
143 2
        Log::notice('New User ID-'.$userID.' Created by ID-'.Auth::user()->user_id);
144
145
        // return redirect()->back()->with('success', 'New User Created');
146 2
        return response()->json(['success' => true]);
147
    }
148
149
    //  List all inactive users
150 4
    public function show($type)
151
    {
152 4
        $userList = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $userList is dead and can be removed.
Loading history...
153 4
        $route    = '';
154
155 4
        if($type !== 'inactive')
156
        {
157
            return abort(404);
1 ignored issue
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
158
        }
159 4
        $userList = new UserCollection(User::onlyTrashed()->get()
160
                /** @scrutinizer ignore-call */
161 4
                ->makeVisible('user_id'));
162
163 4
        return view('admin.userDeleted', [
164 4
            'userList' => $userList,
165 4
            'route'    => $route,
166
        ]);
167
168
    }
169
170
    //  Open the edit user form
171 6
    public function edit($id)
172
    {
173 6
        $roles = UserRoleType::all(); // Role::all();
174 6
        $user  = new UserResource(User::findOrFail($id));
175
176
        //  Make sure that the user is not trying to deactivate someone with more permissions
177 4
        if ($user->role_id < Auth::user()->role_id)
178
        {
179 2
            return abort(403);
1 ignored issue
show
Bug introduced by
Are you sure the usage of abort(403) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
180
        }
181
182
        //  Good to go - update user password
183 2
        $roleArr = [];
184 2
        foreach ($roles as $role) {
185 2
            if ($role->role_id == 1 && Auth::user()->role_id != 1) {
186
                continue;
187 2
            } else if ($role->role_id == 2 && Auth::user()->role_id > 1) {
188
                continue;
189
            } else {
190
                // $roleArr[$role->role_id] = $role->name;
191 2
                $roleArr[] = [
192 2
                    'value' => $role->role_id,
193 2
                    'text'  => $role->name,
194
                ];
195
            }
196
        }
197
198 2
        Log::debug('Route ' . Route::currentRouteName() . ' visited by User ID-' . Auth::user()->user_id);
199 2
        return view('admin.userEdit', [
200 2
            'roles' => $roleArr,
201 2
            'user'  => $user->makeVisible(['user_id', 'username']),
0 ignored issues
show
Bug introduced by
The method makeVisible() does not exist on App\Http\Resources\User. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

201
            'user'  => $user->/** @scrutinizer ignore-call */ makeVisible(['user_id', 'username']),
Loading history...
202
        ]);
203
    }
204
205
    //  Reactivate a disabled user
206 4
    public function reactivateUser($id)
207
    {
208 4
        User::withTrashed()->where('user_id', $id)->restore();
209
210 4
        return response()->json([
211 4
            'success' => true,
212
        ]);
213
    }
214
215
    //  Submit the update user form
216 22
    public function update(Request $request, $id)
217
    {
218 22
        $request->validate([
219
            'username'   => [
220 22
                                'required',
221 22
                                Rule::unique('users')->ignore($id, 'user_id')
222
                            ],
223 22
            'first_name' => 'required',
224 22
            'last_name'  => 'required',
225
            'email'      => [
226 22
                                'required',
227 22
                                Rule::unique('users')->ignore($id, 'user_id')
228
                            ],
229 22
            'role'       => 'required',
230
        ]);
231
232
        //  Update the user data
233 8
        $user = User::findOrFail($id);
234
235 6
        if ($user->role_id < Auth::user()->role_id)
236
        {
237 2
            return abort(403);
1 ignored issue
show
Bug introduced by
Are you sure the usage of abort(403) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
238
        }
239
240 4
        $user->update(
241
        [
242 4
            'username'   => $request->username,
243 4
            'first_name' => $request->first_name,
244 4
            'last_name'  => $request->last_name,
245 4
            'email'      => $request->email,
246 4
            'role_id'    => $request->role,
247
        ]);
248
249
        //  Update the user's role
250 4
        Log::debug('Route '.Route::currentRouteName().' visited by User ID-'.Auth::user()->user_id);
251 4
        Log::debug('Edit user form submitted for User ID-'.$id.'  Data - ', $request->toArray());
252 4
        Log::notice('User ID-'.$id.' has updated their information.');
253 4
        return response()->json(['success' => true]);
254
    }
255
256
    //  Submit the change password form
257 12
    public function submitPassword(Request $request)
258
    {
259 12
        $request->validate([
260 12
            'password' => 'required|string|min:6|confirmed',
261
            'user_id'  => 'required',
262
        ]);
263
264
        // $nextChange = isset($request->force_change) && $request->force_change == 'on' ? Carbon::now()->subDay() : null;
265
266 8
        if($request->force_change)
267
        {
268 6
            $nextChange = Carbon::now()->subDay();
269
        }
270
        else
271
        {
272 2
            $nextChange = config('users.passExpires') != null ? Carbon::now()->addDays(config('users.passExpires')) : null;
273
        }
274
275 8
        $user = User::find($request->user_id);
276
277
        //  Verify this is a valid user ID
278 8
        if (!$user) {
279 2
            $success = false;
280 2
            $reason  = 'Cannot find user with this ID';
281
        }
282
        //  Make sure that the user is not trying to deactivate someone with more permissions
283 6
        else if ($user->role_id < Auth::user()->role_id) {
284 2
            $success = false;
285 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.';
286
        }
287
        //  Good to go - update user password
288
        else {
289
            //  Update the user data
290 4
            $user->update(
291
            [
292 4
                'password'         => bcrypt($request->password),
293 4
                'password_expires' => $nextChange
294
            ]);
295 4
            $success = true;
296 4
            $reason  = 'Password for ' . $user->full_name . ' successfully reset.';
297
        }
298
299 8
        Log::debug('Route ' . Route::currentRouteName() . ' visited by User ID-' . Auth::user()->user_id);
300 8
        Log::notice('User ID-' . $request->user_id . ' password chagned by ' . Auth::user()->user_id, [
301 8
            'success' => $success,
302 8
            'reason'  => $reason,
303
        ]);
304
305 8
        return response()->json([
306 8
            'success' => $success,
307 8
            'reason'  => $reason,
308
        ]);
309
    }
310
311
    //  Disable the user
312 8
    public function destroy($id)
313
    {
314 8
        $user = User::find($id);
315
316
        //  Verify this is a valid user ID
317 8
        if(!$user)
318
        {
319 2
            $success = false;
320 2
            $reason  = 'Cannot find user with this ID';
321
        }
322
        //  Make suer that the user is not trying to deactivate themselves
323 6
        else if(Auth::user()->user_id == $id)
324
        {
325 2
            $success = false;
326 2
            $reason  = 'You cannot deactivate yourself';
327
        }
328
        //  Make sure that the user is not trying to deactivate someone with more permissions
329 4
        else if($user->role_id < Auth::user()->role_id)
330
        {
331 2
            $success = false;
332 2
            $reason  = 'You cannot deactivate a user with higher permissions that you.';
333
        }
334
        //  Good to go - deactivate user
335
        else
336
        {
337
            // $user->update(['active' => 0]);
338 2
            $user->delete();
339 2
            $success = true;
340 2
            $reason  = 'User '.$user->full_name.' successfully deactivated.';
341
        }
342
343 8
        Log::debug('Route '.Route::currentRouteName().' visited by User ID-'.Auth::user()->user_id);
344 8
        Log::notice('User ID-'.$id.' disabled by '.Auth::user()->user_id, [
345 8
            'success' => $success,
346 8
            'reason'  => $reason,
347
        ]);
348
349 8
        return response()->json([
350 8
            'success' => $success,
351 8
            'reason'  => $reason,
352
        ]);
353
    }
354
}
355