Completed
Push — master ( a23113...3f274c )
by Sherif
02:17
created

UserRepository::saveProfile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php namespace App\Modules\Acl\Repositories;
2
3
use App\Modules\Core\AbstractRepositories\AbstractRepository;
4
use Lcobucci\JWT\ValidationData;
5
6
class UserRepository extends AbstractRepository
7
{
8
    /**
9
     * Return the model full namespace.
10
     * 
11
     * @return string
12
     */
13
    protected function getModel()
14
    {
15
        return 'App\Modules\Acl\AclUser';
16
    }
17
18
19
    /**
20
     * Return the logged in user account.
21
     *
22
     * @param  array   $relations
23
     * @return boolean
24
     */
25
    public function account($relations = [])
26
    {
27
        $permissions = [];
28
        $user        = \Core::users()->find(\Auth::id(), $relations);
29
        foreach ($user->groups()->get() as $group)
30
        {
31
            $group->permissions->each(function ($permission) use (&$permissions){
32
                $permissions[$permission->model][$permission->id] = $permission->name;
33
            });
34
        }
35
        $user->permissions = $permissions;
36
37
       return $user;
38
    }
39
40
    /**
41
     * Check if the logged in user or the given user 
42
     * has the given permissions on the given model.
43
     * 
44
     * @param  string  $nameOfPermission
45
     * @param  string  $model            
46
     * @param  boolean $user
47
     * @return boolean
48
     */
49
    public function can($nameOfPermission, $model, $user = false)
50
    {      
51
        $user        = $user ?: $this->find(\Auth::id(), ['groups.permissions']);
52
        $permissions = [];
53
54
        $user->groups->pluck('permissions')->each(function ($permission) use (&$permissions, $model){
55
            $permissions = array_merge($permissions, $permission->where('model', $model)->pluck('name')->toArray()); 
56
        });
57
        
58
        return in_array($nameOfPermission, $permissions);
59
    }
60
61
    /**
62
     * Check if the logged in user has the given group.
63
     * 
64
     * @param  string  $groupName
0 ignored issues
show
Bug introduced by
There is no parameter named $groupName. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
65
     * @param  integer $userId
0 ignored issues
show
Bug introduced by
There is no parameter named $userId. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
66
     * @return boolean
67
     */
68
    public function hasGroup($groups, $user = false)
69
    {
70
        $user = $user ?: $this->find(\Auth::id());
71
        return $user->groups->whereIn('name', $groups)->count() ? true : false;
72
    }
73
74
    /**
75
     * Assign the given group ids to the given user.
76
     * 
77
     * @param  integer $userId    
78
     * @param  array   $group_ids
79
     * @return object
80
     */
81 View Code Duplication
    public function assignGroups($userId, $group_ids)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
82
    {
83
        \DB::transaction(function () use ($userId, $group_ids) {
84
            $user = $this->find($userId);
85
            $user->groups()->detach();
86
            $user->groups()->attach($group_ids);
87
        });
88
89
        return $this->find($userId);
90
    }
91
92
93
    /**
94
     * Handle a login request to the application.
95
     * 
96
     * @param  array   $credentials    
97
     * @param  boolean $adminLogin
98
     * @return object
99
     */
100
    public function login($credentials, $adminLogin = false)
101
    {
102
        if ( ! $user = $this->first(['email' => $credentials['email']])) 
103
        {
104
            \ErrorHandler::loginFailed();
105
        }
106
        else if ($adminLogin && ! $user->groups->whereIn('name', ['Admin'])->count()) 
107
        {
108
            \ErrorHandler::loginFailed();
109
        }
110
        else if ( ! $adminLogin && $user->groups->whereIn('name', ['Admin'])->count()) 
111
        {
112
            \ErrorHandler::loginFailed();
113
        }
114
        else if ($user->blocked)
115
        {
116
            \ErrorHandler::userIsBlocked();
117
        }
118
        else if ( ! config('skeleton.disable_confirm_email') && ! $user->confirmed)
119
        {
120
            \ErrorHandler::emailNotConfirmed();
121
        }
122
123
        return $user;
124
    }
125
126
    /**
127
     * Handle a social login request of the none admin to the application.
128
     * 
129
     * @param  string $authCode
130
     * @param  string $accessToken
131
     * @param  string $type
132
     * @return array
133
     */
134
    public function loginSocial($authCode, $accessToken, $type)
135
    {
136
        $access_token = $authCode ? array_get(\Socialite::driver($type)->getAccessTokenResponse($authCode), 'access_token') : $accessToken;
137
        $user         = \Socialite::driver($type)->userFromToken($access_token);
138
139
        if ( ! $user->email)
140
        {
141
            \ErrorHandler::noSocialEmail();
142
        }
143
144
        if ( ! $registeredUser = $this->model->where('email', $user->email)->first()) 
145
        {
146
            $this->register(['email' => $user->email, 'password' => ''], 1);
0 ignored issues
show
Documentation introduced by
1 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
147
        }
148
149
        $loginProxy = \App::make('App\Modules\Acl\Proxy\LoginProxy');
150
        return $loginProxy->login(['email' => $credentials['email'], 'password' => config('skeleton.social_pass')], 0);
0 ignored issues
show
Bug introduced by
The variable $credentials does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
151
    }
152
    
153
    /**
154
     * Handle a registration request.
155
     * 
156
     * @param  array   $credentials
157
     * @param  boolean $skipConfirmEmail
158
     * @return array
159
     */
160
    public function register($credentials, $skipConfirmEmail = false)
161
    {
162
        $user = $this->save($credentials);
163
164
        if ($skipConfirmEmail) 
165
        {
166
            $user->confirmed = 1;
167
            $user->save();
0 ignored issues
show
Bug introduced by
The method save cannot be called on $user (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
168
        }
169
        else if ( ! config('skeleton.disable_confirm_email'))  
170
        {
171
            $this->sendConfirmationEmail($user->email);
172
        }
173
174
        return $user;
175
    }
176
    
177
    /**
178
     * Block the user.
179
     *
180
     * @param  integer $userId
181
     * @return object
182
     */
183
    public function block($userId)
184
    {
185
        if ( ! $user = $this->find($userId)) 
186
        {
187
            \ErrorHandler::notFound('user');
188
        }
189
        if ( ! $this->hasGroup(['Admin']))
190
        {
191
            \ErrorHandler::noPermissions();
192
        }
193
        else if (\Auth::id() == $userId)
194
        {
195
            \ErrorHandler::noPermissions();
196
        }
197
        else if ($user->groups->pluck('name')->search('Admin', true) !== false) 
198
        {
199
            \ErrorHandler::noPermissions();
200
        }
201
202
        $user->blocked = 1;
203
        $user->save();
204
        
205
        return $user;
206
    }
207
208
    /**
209
     * Unblock the user.
210
     *
211
     * @param  integer $userId
212
     * @return object
213
     */
214
    public function unblock($userId)
215
    {
216
        if ( ! $this->hasGroup(['Admin']))
217
        {
218
            \ErrorHandler::noPermissions();
219
        }
220
221
        $user          = $this->find($userId);
222
        $user->blocked = 0;
223
        $user->save();
224
225
        return $user;
226
    }
227
228
    /**
229
     * Send a reset link to the given user.
230
     *
231
     * @param  string  $email
232
     * @return void
233
     */
234
    public function sendReset($email)
235
    {
236
        if ( ! $user = $this->model->where('email', $email)->first())
237
        {
238
            \ErrorHandler::notFound('email');
239
        }
240
241
        $token = \Password::getRepository()->create($user);
242
        \Core::notifications()->notify($user, 'ResetPassword', $token);
243
    }
244
245
    /**
246
     * Reset the given user's password.
247
     *
248
     * @param  array  $credentials
249
     * @return array
250
     */
251
    public function resetPassword($credentials)
252
    {
253
        $response = \Password::reset($credentials, function ($user, $password) {
254
            $user->password = $password;
255
            $user->save();
256
        });
257
258
        switch ($response) {
259
            case \Password::PASSWORD_RESET:
260
                return 'success';
261
                
262
            case \Password::INVALID_TOKEN:
263
                \ErrorHandler::invalidResetToken('token');
264
265
            case \Password::INVALID_PASSWORD:
266
                \ErrorHandler::invalidResetPassword('email');
267
268
            case \Password::INVALID_USER:
269
                \ErrorHandler::notFound('user');
270
271
            default:
272
                \ErrorHandler::generalError();
273
        }
274
    }
275
276
    /**
277
     * Change the logged in user password.
278
     *
279
     * @param  array  $credentials
280
     * @return void
281
     */
282
    public function changePassword($credentials)
283
    {
284
        $user = \Auth::user();
285
        if ( ! \Hash::check($credentials['old_password'], $user->password)) 
286
        {
287
            \ErrorHandler::invalidOldPassword();
288
        }
289
290
        $user->password = $credentials['password'];
291
        $user->save();
292
    }
293
294
    /**
295
     * Confirm email using the confirmation code.
296
     *
297
     * @param  string $confirmationCode
298
     * @return void
299
     */
300
    public function confirmEmail($confirmationCode)
301
    {
302
        $user                    = $this->first(['confirmation_code' => $confirmationCode]);
303
        $user->confirmed         = 1;
304
        $user->confirmation_code = null;
305
        $user->save();
306
    }
307
308
    /**
309
     * Send the confirmation mail.
310
     *
311
     * @param  string $email
312
     * @return void
313
     */
314
    public function sendConfirmationEmail($email)
315
    {
316
        $user = $this->first(['email' => $email]);
317
        if ($user->confirmed) 
318
        {
319
            \ErrorHandler::emailAlreadyConfirmed();
320
        }
321
322
        $user->confirmed         = 0;
323
        $user->confirmation_code = sha1(microtime());
324
        $user->save();
325
        \Core::notifications()->notify($user, 'ConfirmEmail');
326
    }
327
328
    /**
329
     * Paginate all users in the given group based on the given conditions.
330
     * 
331
     * @param  string  $groupName
332
     * @param  array   $relations
333
     * @param  integer $perPage
334
     * @param  string  $sortBy
335
     * @param  boolean $desc
336
     * @return \Illuminate\Http\Response
337
     */
338
    public function group($conditions, $groupName, $relations, $perPage, $sortBy, $desc)
339
    {   
340
        unset($conditions['page']);
341
        $conditions = $this->constructConditions($conditions, $this->model);
342
        $sort       = $desc ? 'desc' : 'asc';
343
        $model      = call_user_func_array("{$this->getModel()}::with", array($relations));
344
345
        $model->whereHas('groups', function($q) use ($groupName){
346
            $q->where('name', $groupName);
347
        });
348
349
        
350
        if (count($conditions['conditionValues']))
351
        {
352
            $model->whereRaw($conditions['conditionString'], $conditions['conditionValues']);
353
        }
354
355
        if ($perPage) 
356
        {
357
            return $model->orderBy($sortBy, $sort)->paginate($perPage);
358
        }
359
360
        return $model->orderBy($sortBy, $sort)->get();
361
    }
362
363
    /**
364
     * Save the given data to the logged in user.
365
     *
366
     * @param  array $credentials
0 ignored issues
show
Bug introduced by
There is no parameter named $credentials. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
367
     * @return void
368
     */
369
    public function saveProfile($data) 
370
    {
371
        if (array_key_exists('profile_picture', $data)) 
372
        {
373
            $data['profile_picture'] = \Media::uploadImageBas64($data['profile_picture'], 'admins/profile_pictures');
374
        }
375
        
376
        $data['id'] = \Auth::id();
377
        $this->save($data);
378
    }
379
380
    /**
381
     * Ensure access token hasn't expired or revoked.
382
     * 
383
     * @param  string $accessToken
384
     * @return boolean
385
     */
386
    public function accessTokenExpiredOrRevoked($accessToken)
387
    {
388
389
        $accessTokenRepository = \App::make('League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface');
390
        $data                  = new ValidationData();
391
        $data->setCurrentTime(time());
392
393
        if ($accessToken->validate($data) === false || $accessTokenRepository->isAccessTokenRevoked($accessToken->getClaim('jti'))) 
0 ignored issues
show
Bug introduced by
The method validate cannot be called on $accessToken (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method getClaim cannot be called on $accessToken (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
394
        {
395
            return true;
396
        }
397
398
        return false;
399
    }
400
401
    /**
402
     * Revoke the given access token and all 
403
     * associated refresh tokens.
404
     *
405
     * @param  string  $accessToken
406
     * @return void
407
     */
408
    public function revokeAccessToken($accessToken)
409
    {
410
        \DB::table('oauth_refresh_tokens')
411
            ->where('access_token_id', $accessToken->id)
412
            ->update([
413
                'revoked' => true
414
            ]);
415
416
        $accessToken->revoke();
0 ignored issues
show
Bug introduced by
The method revoke cannot be called on $accessToken (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
417
    }
418
}
419