Completed
Push — master ( 43d6b6...7fd3dc )
by Sherif
12:33
created

UserRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php namespace App\Modules\V1\Acl\Repositories;
2
3
use App\Modules\V1\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\V1\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
65
     * @param  integer $userId
66
     * @return boolean
67
     */
68
    public function hasGroup($groupName, $userId = false)
69
    {
70
        $userId = $userId ?: \Auth::id();
71
        $groups = $this->find($userId)->groups;
72
        return $groups->pluck('name')->search($groupName, true) === false ? false : true;
73
    }
74
75
    /**
76
     * Assign the given group ids to the given user.
77
     * 
78
     * @param  integer $user_id    
79
     * @param  array   $group_ids
80
     * @return object
81
     */
82
    public function assignGroups($user_id, $group_ids)
83
    {
84
        \DB::transaction(function () use ($user_id, $group_ids) {
85
            $user = $this->find($user_id);
86
            $user->groups()->detach();
87
            $user->groups()->attach($group_ids);
88
        });
89
90
        return $this->find($user_id);
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->pluck('name')->search('Admin', true) === false) 
107
        {
108
            \ErrorHandler::loginFailed();
109
        }
110 View Code Duplication
        else if ( ! $adminLogin && $user->groups->pluck('name')->search('Admin', true) !== false) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
111
        {
112
            \ErrorHandler::loginFailed();
113
        }
114
        else if ($user->blocked)
115
        {
116
            \ErrorHandler::userIsBlocked();
117
        }
118
119
        return $user;
120
    }
121
122
    /**
123
     * Handle a social login request of the none admin to the application.
124
     * 
125
     * @param  array   $credentials
126
     * @return array
127
     */
128
    public function loginSocial($credentials)
129
    {
130
        $access_token = $credentials['auth_code'] ? \Socialite::driver($credentials['type'])->getAccessToken($credentials['auth_code']) : $credentials['access_token'];
131
        $user         = \Socialite::driver($credentials['type'])->userFromToken($access_token);
132
133
        if ( ! $user->email)
134
        {
135
            \ErrorHandler::noSocialEmail();
136
        }
137
138
        if ( ! $registeredUser = $this->model->where('email', $user->email)->first()) 
139
        {
140
            $data = ['email' => $user->email, 'password' => ''];
141
            return $this->register($data);
142
        }
143
        else
144
        {
145
            if ( ! \Auth::attempt(['email' => $registeredUser->email, 'password' => '']))
146
            {
147
                \ErrorHandler::userAlreadyRegistered();
148
            }
149
150
            $loginProxy = \App::make('App\Modules\V1\Acl\Proxy\LoginProxy');
151
            return $loginProxy->login(['email' => $registeredUser->email, 'password' => ''], 0);
152
        }
153
    }
154
    
155
    /**
156
     * Handle a registration request.
157
     * 
158
     * @param  array $credentials
159
     * @return array
160
     */
161
    public function register($credentials)
162
    {
163
        $loginProxy = \App::make('App\Modules\V1\Acl\Proxy\LoginProxy');
164
        $this->model->create($credentials);
165
166
        return $loginProxy->login($credentials, 0);
167
    }
168
169
    /**
170
     * Block the user.
171
     *
172
     * @param  integer $user_id
173
     * @return object
174
     */
175
    public function block($user_id)
176
    {
177
        if ( ! $user = $this->find($user_id)) 
178
        {
179
            \ErrorHandler::notFound('user');
180
        }
181
        if ( ! $this->hasGroup('Admin'))
182
        {
183
            \ErrorHandler::noPermissions();
184
        }
185 View Code Duplication
        else if (\Auth::id() == $user_id)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
186
        {
187
            \ErrorHandler::noPermissions();
188
        }
189
        else if ($user->groups->pluck('name')->search('Admin', true) !== false) 
190
        {
191
            \ErrorHandler::noPermissions();
192
        }
193
194
        $user->blocked = 1;
195
        $user->save();
196
        
197
        return $user;
198
    }
199
200
    /**
201
     * Unblock the user.
202
     *
203
     * @param  integer $user_id
204
     * @return object
205
     */
206
    public function unblock($user_id)
207
    {
208
        if ( ! $this->hasGroup('Admin'))
209
        {
210
            \ErrorHandler::noPermissions();
211
        }
212
213
        $user          = $this->find($user_id);
214
        $user->blocked = 0;
215
        $user->save();
216
217
        return $user;
218
    }
219
220
    /**
221
     * Send a reset link to the given user.
222
     *
223
     * @param  string  $email
224
     * @return void
225
     */
226
    public function sendReset($email)
227
    {
228
        if ( ! $user = $this->model->where('email', $email)->first())
229
        {
230
            \ErrorHandler::notFound('email');
231
        }
232
233
        $url   = $this->config['resetLink'];
234
        $token = \Password::getRepository()->create($user);
235
        
236
        \Mail::send('acl::resetpassword', ['user' => $user, 'url' => $url, 'token' => $token], function ($m) use ($user) {
237
            $m->to($user->email, $user->name)->subject('Your Password Reset Link');
238
        });
239
    }
240
241
    /**
242
     * Reset the given user's password.
243
     *
244
     * @param  array  $credentials
245
     * @return array
246
     */
247
    public function resetPassword($credentials)
248
    {
249
        $response = \Password::reset($credentials, function ($user, $password) {
250
            $user->password = $password;
251
            $user->save();
252
        });
253
254
        switch ($response) {
255
            case \Password::PASSWORD_RESET:
256
                return 'success';
257
                
258
            case \Password::INVALID_TOKEN:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
259
                \ErrorHandler::invalidResetToken('token');
260
261
            case \Password::INVALID_PASSWORD:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
262
                \ErrorHandler::invalidResetPassword('email');
263
264
            case \Password::INVALID_USER:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
265
                \ErrorHandler::notFound('user');
266
267
            default:
268
                \ErrorHandler::generalError();
269
        }
270
    }
271
272
    /**
273
     * Change the logged in user password.
274
     *
275
     * @param  array  $credentials
276
     * @return void
277
     */
278
    public function changePassword($credentials)
279
    {
280
        $user = \Auth::user();
281
        if ( ! \Hash::check($credentials['old_password'], $user->password)) 
282
        {
283
            \ErrorHandler::invalidOldPassword();
284
        }
285
286
        $user->password = $credentials['password'];
287
        $user->save();
288
    }
289
290
    /**
291
     * Paginate all users in the given group based on the given conditions.
292
     * 
293
     * @param  string  $groupName
294
     * @param  array   $relations
295
     * @param  integer $perPage
296
     * @param  string  $sortBy
297
     * @param  boolean $desc
298
     * @return \Illuminate\Http\Response
299
     */
300
    public function group($conditions, $groupName, $relations, $perPage, $sortBy, $desc)
301
    {   
302
        unset($conditions['page']);
303
        $conditions = $this->constructConditions($conditions, $this->model);
304
        $sort       = $desc ? 'desc' : 'asc';
305
        $model      = call_user_func_array("{$this->getModel()}::with", array($relations));
306
307
        $model->whereHas('groups', function($q) use ($groupName){
308
            $q->where('name', $groupName);
309
        });
310
311
        
312
        if (count($conditions['conditionValues']))
313
        {
314
            $model->whereRaw($conditions['conditionString'], $conditions['conditionValues']);
315
        }
316
317
        if ($perPage) 
318
        {
319
            return $model->orderBy($sortBy, $sort)->paginate($perPage);
320
        }
321
322
        return $model->orderBy($sortBy, $sort)->get();
323
    }
324
325
    /**
326
     * Save the given data to the logged in user.
327
     *
328
     * @param  array $credentials
329
     * @return object
330
     */
331
    public function saveProfile($credentials) 
332
    {
333
        $user = \Auth::user();
334
        $user->save($credentials);
335
336
        return $user;
337
    }
338
339
    /**
340
     * Ensure access token hasn't expired or revoked.
341
     * 
342
     * @param  string $accessToken
343
     * @return boolean
344
     */
345
    public function accessTokenExpiredOrRevoked($accessToken)
346
    {
347
348
        $accessTokenRepository = \App::make('League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface');
349
        $data = new ValidationData();
350
        $data->setCurrentTime(time());
351
352
        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...
353
        {
354
            return true;
355
        }
356
357
        return false;
358
    }
359
}
360