Test Failed
Pull Request — master (#18)
by Maximo
07:25
created

UsersController::processUserInvite()   B

Complexity

Conditions 6
Paths 14

Size

Total Lines 51
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 28
nc 14
nop 1
dl 0
loc 51
ccs 0
cts 37
cp 0
crap 42
rs 8.8497
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewaer\Api\Controllers;
6
7
use Gewaer\Models\Users;
8
use Gewaer\Models\UserLinkedSources;
9
use Baka\Auth\Models\Sources;
10
use Gewaer\Models\UsersInvite;
11
use Gewaer\Models\Companies;
12
use Phalcon\Http\Response;
13
use Phalcon\Validation;
14
use Phalcon\Validation\Validator\PresenceOf;
15
use Gewaer\Exception\BadRequestHttpException;
16
use Gewaer\Exception\UnprocessableEntityHttpException;
17
use Phalcon\Validation\Validator\StringLength;
18
use Baka\Http\QueryParser;
19
use Gewaer\Exception\ModelException;
20
use Gewaer\Exception\NotFoundHttpException;
21
use Gewaer\Exception\ServerErrorHttpException;
22
use Gewaer\Models\AccessList;
23
24
/**
25
 * Class UsersController
26
 *
27
 * @package Gewaer\Api\Controllers
28
 *
29
 * @property Users $userData
30
 * @property Request $request
31
 * @property Config $config
32
 */
33
class UsersController extends \Baka\Auth\UsersController
34
{
35
    /*
36
     * fields we accept to create
37
     *
38
     * @var array
39
     */
40
    protected $createFields = ['name', 'firstname', 'lastname', 'displayname', 'email', 'password', 'created_at', 'updated_at', 'default_company', 'family'];
41
42
    /*
43
     * fields we accept to create
44
     *
45
     * @var array
46
     */
47
    protected $updateFields = ['name', 'firstname', 'lastname', 'displayname', 'email', 'password', 'created_at', 'updated_at', 'default_company'];
48
49
    /**
50
     * set objects
51
     *
52
     * @return void
53
     */
54
    public function onConstruct()
55
    {
56
        $this->model = new Users();
57
58
        //if you are not a admin you cant see all the users
59
        if (!$this->userData->hasRole('Defaults.Admins')) {
60
            $this->additionalSearchFields = [
61
                ['id', ':', $this->userData->getId()],
62
            ];
63
        } else {
64
            //admin get all the users for this company
65
            $this->additionalSearchFields = [
66
                ['default_company', ':', $this->userData->default_company],
67
            ];
68
        }
69
    }
70
71
    /**
72
     * Get Uer
73
     *
74
     * @param mixed $id
75
     *
76
     * @method GET
77
     * @url /v1/users/{id}
78
     *
79
     * @return Response
80
     */
81
    public function getById($id) : Response
82
    {
83
        //find the info
84
        $user = $this->model->findFirst([
85
            'id = ?0 AND is_deleted = 0',
86
            'bind' => [$this->userData->getId()],
87
        ]);
88
89
        $user->password = null;
90
91
        //get relationship
92
        if ($this->request->hasQuery('relationships')) {
93
            $relationships = $this->request->getQuery('relationships', 'string');
94
95
            $user = QueryParser::parseRelationShips($relationships, $user);
96
        }
97
98
        //if you search for roles we give you the access for this app
99
        if (array_key_exists('roles', $user)) {
100
            $accesList = AccessList::find([
101
                'conditions' => 'roles_name = ?0 and apps_id = ?1 and allowed = 0',
102
                'bind' => [$user['roles'][0]->name, $this->config->app->id]
103
            ]);
104
105
            if (count($accesList) > 0) {
106
                foreach ($accesList as $access) {
107
                    $user['access_list'][strtolower($access->resources_name)][$access->access_name] = 0;
108
                }
109
            }
110
        }
111
112
        if ($user) {
113
            return $this->response($user);
114
        } else {
115
            throw new ModelException('Record not found');
116
        }
117
    }
118
119
    /**
120
     * Update a User Info
121
     *
122
     * @method PUT
123
     * @url /v1/users/{id}
124
     *
125
     * @return Response
126
     */
127
    public function edit($id) : Response
128
    {
129
        //none admin users can only edit themselves
130
        if (!$this->userData->hasRole('Default.Admins')) {
131
            $id = $this->userData->getId();
132
        }
133
134
        if ($user = $this->model->findFirst($id)) {
135
            $request = $this->request->getPut();
136
137
            if (empty($request)) {
138
                $request = $this->request->getJsonRawBody(true);
139
            }
140
141
            //clean pass
142
            if (array_key_exists('password', $request) && !empty($request['password'])) {
143
                $user->password = Users::passwordHash($request['password']);
144
                unset($request['password']);
145
            }
146
147
            //clean default company
148
            if (array_key_exists('default_company', $request)) {
149
                //@todo check if I belong to this company
150
                if ($company = Companies::findFirst($request['default_company'])) {
151
                    $user->default_company = $company->getId();
152
                    unset($request['default_company']);
153
                }
154
            }
155
156
            //update
157
            if ($user->update($request, $this->updateFields)) {
158
                $user->password = null;
159
                return $this->response($user);
160
            } else {
161
                //didnt work
162
                throw new ModelException((string) current($user->getMessages()));
163
            }
164
        } else {
165
            throw new NotFoundHttpException('Record not found');
166
        }
167
    }
168
169
    /**
170
     * Add users notifications
171
     *
172
     * @param int $id
173
     * @method PUT
174
     * @return Response
175
     */
176
    public function updateNotifications($id): Response
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed. ( Ignorable by Annotation )

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

176
    public function updateNotifications(/** @scrutinizer ignore-unused */ $id): Response

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
177
    {
178
        //get the notification array
179
        //delete the current ones
180
        //iterate and save into users
181
182
        return $this->response(['OK']);
183
    }
184
185
    /**
186
     * Associate a Device with the corrent loggedin user
187
     *
188
     * @url /users/{id}/device
189
     * @method POST
190
     * @return Response
191
     */
192
    public function devices(): Response
193
    {
194
        //Ok let validate user password
195
        $validation = new Validation();
196
        $validation->add('app', new PresenceOf(['message' => _('App name is required.')]));
197
        $validation->add('deviceId', new PresenceOf(['message' => _('device ID is required.')]));
198
199
        //validate this form for password
200
        $messages = $validation->validate($this->request->getPost());
201
        if (count($messages)) {
202
            foreach ($messages as $message) {
203
                throw new BadRequestHttpException((string) $message);
204
            }
205
        }
206
207
        $app = $this->request->getPost('app', 'string');
208
        $deviceId = $this->request->getPost('deviceId', 'string');
209
210
        //get the app source
211
        if ($source = Sources::getByTitle($app)) {
212
            if (!$userSource = UserLinkedSources::findFirst(['conditions' => 'users_id = ?0 and source_users_id_text =?1', 'bind' => [$this->userData->getId(), $deviceId]])) {
0 ignored issues
show
Unused Code introduced by
The assignment to $userSource is dead and can be removed.
Loading history...
213
                $userSource = new UserLinkedSources();
214
                $userSource->users_id = $this->userData->getId();
215
                $userSource->source_id = $source->getId();
216
                $userSource->source_users_id = $this->userData->getId();
217
                $userSource->source_users_id_text = $deviceId;
218
                $userSource->source_username = $this->userData->displayname . ' ' . $app;
219
220
                if (!$userSource->save()) {
221
                    throw new UnprocessableEntityHttpException((string) current($userSource->getMessages()));
222
                }
223
224
                $msg = 'User Device Associated';
225
            } else {
226
                $msg = 'User Device Already Associated';
227
            }
228
        }
229
230
        //clean password @todo move this to a better place
231
        $this->userData->password = null;
232
233
        return $this->response([
234
            'msg' => $msg,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $msg does not seem to be defined for all execution paths leading up to this point.
Loading history...
235
            'user' => $this->userData
236
        ]);
237
    }
238
239
    /**
240
     * Add invited user to our system
241
     * @return Response
242
     */
243
    public function processUserInvite(string $hash): Response
244
    {
245
        $request = $this->request->getPost();
246
247
        if (empty($request)) {
248
            $request = $this->request->getJsonRawBody(true);
249
        }
250
251
        //Ok let validate user password
252
        $validation = new Validation();
253
        $validation->add('password', new PresenceOf(['message' => _('The password is required.')]));
254
255
        $validation->add(
256
            'password',
257
            new StringLength([
258
                'min' => 8,
259
                'messageMinimum' => _('Password is too short. Minimum 8 characters.'),
260
            ])
261
        );
262
263
        //validate this form for password
264
        $messages = $validation->validate($request);
265
        if (count($messages)) {
266
            foreach ($messages as $message) {
267
                throw new ServerErrorHttpException((string)$message);
268
            }
269
        }
270
271
        //Lets find users_invite by hash on our database
272
        $usersInvite = UsersInvite::findFirst([
273
                'conditions' => 'invite_hash = ?0 and is_deleted = 0',
274
                'bind' => [$hash]
275
            ]);
276
277
        if (!$usersInvite) {
0 ignored issues
show
introduced by
$usersInvite is of type Phalcon\Mvc\Model, thus it always evaluated to true.
Loading history...
278
            throw new NotFoundHttpException('Users Invite not found');
279
        }
280
281
        $request['email'] = $usersInvite->email;
282
        $request['roles_id'] = $usersInvite->role_id;
283
        $request['created_at'] = date('Y-m-d H:m:s');
284
        $request['name'] = $this->userData->defaultCompany;
0 ignored issues
show
Bug Best Practice introduced by
The property defaultCompany does not exist on Gewaer\Models\Users. Since you implemented __get, consider adding a @property annotation.
Loading history...
285
        $request['default_company'] = $this->userData->default_company;
286
287
        //Lets insert the new user to our system.
288
289
        if ($this->model->save($request, $this->createFields)) {
290
            return $this->response($this->model->toArray());
291
        } else {
292
            //if not thorw exception
293
            throw new UnprocessableEntityHttpException((string) current($this->model->getMessages()));
294
        }
295
    }
296
}
297