Completed
Push — master ( 95c0c1...518882 )
by Sherif
02:08
created

UserRepository::sendConfirmationEmail()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
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 $user_id    
78
     * @param  array   $group_ids
79
     * @return object
80
     */
81 View Code Duplication
    public function assignGroups($user_id, $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 ($user_id, $group_ids) {
84
            $user = $this->find($user_id);
85
            $user->groups()->detach();
86
            $user->groups()->attach($group_ids);
87
        });
88
89
        return $this->find($user_id);
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  array   $credentials
130
     * @return array
131
     */
132
    public function loginSocial($credentials)
133
    {
134
        $access_token = $credentials['auth_code'] ? \Socialite::driver($credentials['type'])->getAccessToken($credentials['auth_code']) : $credentials['access_token'];
135
        $user         = \Socialite::driver($credentials['type'])->userFromToken($access_token);
136
137
        if ( ! $user->email)
138
        {
139
            \ErrorHandler::noSocialEmail();
140
        }
141
142
        if ( ! $registeredUser = $this->model->where('email', $user->email)->first()) 
143
        {
144
            $data = ['email' => $user->email, 'password' => ''];
145
            return $this->register($data);
146
        }
147
        else
148
        {
149
            if ( ! \Auth::attempt(['email' => $registeredUser->email, 'password' => '']))
150
            {
151
                \ErrorHandler::userAlreadyRegistered();
152
            }
153
154
            $loginProxy = \App::make('App\Modules\Acl\Proxy\LoginProxy');
155
            return $loginProxy->login(['email' => $registeredUser->email, 'password' => ''], 0);
156
        }
157
    }
158
    
159
    /**
160
     * Handle a registration request.
161
     * 
162
     * @param  array $credentials
163
     * @return array
164
     */
165
    public function register($credentials)
166
    {
167
        $user = $this->save($credentials);
168
169
        if ( ! config('skeleton.disable_confirm_email')) 
170
        {
171
            $this->sendConfirmationEmail($user->email);
172
        }
173
    }
174
    
175
    /**
176
     * Block the user.
177
     *
178
     * @param  integer $user_id
179
     * @return object
180
     */
181
    public function block($user_id)
182
    {
183
        if ( ! $user = $this->find($user_id)) 
184
        {
185
            \ErrorHandler::notFound('user');
186
        }
187
        if ( ! $this->hasGroup(['Admin']))
188
        {
189
            \ErrorHandler::noPermissions();
190
        }
191
        else if (\Auth::id() == $user_id)
192
        {
193
            \ErrorHandler::noPermissions();
194
        }
195
        else if ($user->groups->pluck('name')->search('Admin', true) !== false) 
196
        {
197
            \ErrorHandler::noPermissions();
198
        }
199
200
        $user->blocked = 1;
201
        $user->save();
202
        
203
        return $user;
204
    }
205
206
    /**
207
     * Unblock the user.
208
     *
209
     * @param  integer $user_id
210
     * @return object
211
     */
212
    public function unblock($user_id)
213
    {
214
        if ( ! $this->hasGroup(['Admin']))
215
        {
216
            \ErrorHandler::noPermissions();
217
        }
218
219
        $user          = $this->find($user_id);
220
        $user->blocked = 0;
221
        $user->save();
222
223
        return $user;
224
    }
225
226
    /**
227
     * Send a reset link to the given user.
228
     *
229
     * @param  string  $email
230
     * @return void
231
     */
232
    public function sendReset($email)
233
    {
234
        if ( ! $user = $this->model->where('email', $email)->first())
235
        {
236
            \ErrorHandler::notFound('email');
237
        }
238
239
        $token = \Password::getRepository()->create($user);
240
        \Core::notifications()->notify($user, 'ResetPassword', $token);
241
    }
242
243
    /**
244
     * Reset the given user's password.
245
     *
246
     * @param  array  $credentials
247
     * @return array
248
     */
249
    public function resetPassword($credentials)
250
    {
251
        $response = \Password::reset($credentials, function ($user, $password) {
252
            $user->password = $password;
253
            $user->save();
254
        });
255
256
        switch ($response) {
257
            case \Password::PASSWORD_RESET:
258
                return 'success';
259
                
260
            case \Password::INVALID_TOKEN:
261
                \ErrorHandler::invalidResetToken('token');
262
263
            case \Password::INVALID_PASSWORD:
264
                \ErrorHandler::invalidResetPassword('email');
265
266
            case \Password::INVALID_USER:
267
                \ErrorHandler::notFound('user');
268
269
            default:
270
                \ErrorHandler::generalError();
271
        }
272
    }
273
274
    /**
275
     * Change the logged in user password.
276
     *
277
     * @param  array  $credentials
278
     * @return void
279
     */
280
    public function changePassword($credentials)
281
    {
282
        $user = \Auth::user();
283
        if ( ! \Hash::check($credentials['old_password'], $user->password)) 
284
        {
285
            \ErrorHandler::invalidOldPassword();
286
        }
287
288
        $user->password = $credentials['password'];
289
        $user->save();
290
    }
291
292
    /**
293
     * Confirm email using the confirmation code.
294
     *
295
     * @param  string $confirmationCode
296
     * @return void
297
     */
298
    public function confirmEmail($confirmationCode)
299
    {
300
        $user                    = $this->first(['confirmation_code' => $confirmationCode]);
301
        $user->confirmed         = 1;
302
        $user->confirmation_code = null;
303
        $user->save();
304
    }
305
306
    /**
307
     * Send the confirmation mail.
308
     *
309
     * @param  string $email
310
     * @return void
311
     */
312
    public function sendConfirmationEmail($email)
313
    {
314
        $user = $this->first(['email' => $email]);
315
        if ($user->confirmed) 
316
        {
317
            \ErrorHandler::emailAlreadyConfirmed();
318
        }
319
320
        $user->confirmed         = 0;
321
        $user->confirmation_code = sha1(microtime());
322
        $user->save();
323
        \Core::notifications()->notify($user, 'ConfirmEmail');
324
    }
325
326
    /**
327
     * Paginate all users in the given group based on the given conditions.
328
     * 
329
     * @param  string  $groupName
330
     * @param  array   $relations
331
     * @param  integer $perPage
332
     * @param  string  $sortBy
333
     * @param  boolean $desc
334
     * @return \Illuminate\Http\Response
335
     */
336
    public function group($conditions, $groupName, $relations, $perPage, $sortBy, $desc)
337
    {   
338
        unset($conditions['page']);
339
        $conditions = $this->constructConditions($conditions, $this->model);
340
        $sort       = $desc ? 'desc' : 'asc';
341
        $model      = call_user_func_array("{$this->getModel()}::with", array($relations));
342
343
        $model->whereHas('groups', function($q) use ($groupName){
344
            $q->where('name', $groupName);
345
        });
346
347
        
348
        if (count($conditions['conditionValues']))
349
        {
350
            $model->whereRaw($conditions['conditionString'], $conditions['conditionValues']);
351
        }
352
353
        if ($perPage) 
354
        {
355
            return $model->orderBy($sortBy, $sort)->paginate($perPage);
356
        }
357
358
        return $model->orderBy($sortBy, $sort)->get();
359
    }
360
361
    /**
362
     * Save the given data to the logged in user.
363
     *
364
     * @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...
365
     * @return void
366
     */
367
    public function saveProfile($data) 
368
    {
369
        if (array_key_exists('profile_picture', $data)) 
370
        {
371
            $data['profile_picture'] = \Media::uploadImageBas64($data['profile_picture'], 'admins/profile_pictures');
372
        }
373
        
374
        $data['id'] = \Auth::id();
375
        $this->save($data);
376
    }
377
378
    /**
379
     * Ensure access token hasn't expired or revoked.
380
     * 
381
     * @param  string $accessToken
382
     * @return boolean
383
     */
384
    public function accessTokenExpiredOrRevoked($accessToken)
385
    {
386
387
        $accessTokenRepository = \App::make('League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface');
388
        $data                  = new ValidationData();
389
        $data->setCurrentTime(time());
390
391
        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...
392
        {
393
            return true;
394
        }
395
396
        return false;
397
    }
398
399
    /**
400
     * Revoke the given access token and all 
401
     * associated refresh tokens.
402
     *
403
     * @param  string  $accessToken
404
     * @return void
405
     */
406
    public function revokeAccessToken($accessToken)
407
    {
408
        \DB::table('oauth_refresh_tokens')
409
            ->where('access_token_id', $accessToken->id)
410
            ->update([
411
                'revoked' => true
412
            ]);
413
414
        $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...
415
    }
416
}
417