Failed Conditions
Pull Request — master (#61)
by Rafael
06:01
created

UsersController::onConstruct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0932

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 0
dl 0
loc 13
ccs 5
cts 7
cp 0.7143
crap 2.0932
rs 10
c 0
b 0
f 0
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\Companies;
11
use Phalcon\Http\Response;
12
use Phalcon\Validation;
13
use Phalcon\Validation\Validator\PresenceOf;
14
use Gewaer\Exception\BadRequestHttpException;
15
use Gewaer\Exception\UnprocessableEntityHttpException;
16
use Baka\Http\QueryParser;
17
use Gewaer\Exception\ModelException;
18
use Gewaer\Exception\NotFoundHttpException;
19
use Gewaer\Models\AccessList;
20
21
/**
22
 * Class UsersController
23
 *
24
 * @package Gewaer\Api\Controllers
25
 *
26
 * @property Users $userData
27
 * @property Request $request
28
 * @property Config $config
29
 */
30
class UsersController extends \Baka\Auth\UsersController
31
{
32
    /*
33
     * fields we accept to create
34
     *
35
     * @var array
36
     */
37
    protected $createFields = ['name', 'firstname', 'lastname', 'displayname', 'language', 'email', 'password', 'created_at', 'updated_at', 'default_company', 'family', 'cell_phone_number', 'country_id'];
38
39
    /*
40
     * fields we accept to create
41
     *
42
     * @var array
43
     */
44
    protected $updateFields = ['name', 'firstname', 'lastname', 'displayname', 'language', 'email', 'password', 'created_at', 'updated_at', 'default_company', 'cell_phone_number', 'country_id'];
45
46
    /**
47
     * set objects
48
     *
49
     * @return void
50
     */
51 3
    public function onConstruct()
52
    {
53 3
        $this->model = new Users();
54
55
        //if you are not a admin you cant see all the users
56 3
        if (!$this->userData->hasRole('Defaults.Admins')) {
57
            $this->additionalSearchFields = [
58
                ['id', ':', $this->userData->getId()],
59
            ];
60
        } else {
61
            //admin get all the users for this company
62 3
            $this->additionalSearchFields = [
63 3
                ['default_company', ':', $this->userData->currentCompanyId()],
64
            ];
65
        }
66 3
    }
67
68
    /**
69
     * Get Uer
70
     *
71
     * @param mixed $id
72
     *
73
     * @method GET
74
     * @url /v1/users/{id}
75
     *
76
     * @return Response
77
     */
78
    public function getById($id) : Response
79
    {
80
        //find the info
81
        $user = $this->model->findFirst([
82
            'id = ?0 AND is_deleted = 0',
83
            'bind' => [$this->userData->getId()],
84
        ]);
85
86
        $user->password = null;
87
88
        //get relationship
89
        if ($this->request->hasQuery('relationships')) {
90
            $relationships = $this->request->getQuery('relationships', 'string');
91
92
            $user = QueryParser::parseRelationShips($relationships, $user);
93
        }
94
95
        //if you search for roles we give you the access for this app
96
        if (array_key_exists('roles', $user)) {
97
            $accesList = AccessList::find([
98
                'conditions' => 'roles_name = ?0 and apps_id = ?1 and allowed = 0',
99
                'bind' => [$user['roles'][0]->name, $this->config->app->id]
100
            ]);
101
102
            if (count($accesList) > 0) {
103
                foreach ($accesList as $access) {
104
                    $user['access_list'][strtolower($access->resources_name)][$access->access_name] = 0;
105
                }
106
            }
107
        }
108
109
        if ($user) {
110
            return $this->response($user);
111
        } else {
112
            throw new ModelException('Record not found');
113
        }
114
    }
115
116
    /**
117
     * Update a User Info
118
     *
119
     * @method PUT
120
     * @url /v1/users/{id}
121
     *
122
     * @return Response
123
     */
124
    public function edit($id) : Response
125
    {
126
        //none admin users can only edit themselves
127
        if (!$this->userData->hasRole('Default.Admins')) {
128
            $id = $this->userData->getId();
129
        }
130
131
        if ($user = $this->model->findFirst($id)) {
132
            $request = $this->request->getPut();
133
134
            if (empty($request)) {
135
                $request = $this->request->getJsonRawBody(true);
136
            }
137
138
            if (empty($request)) {
139
                throw new BadRequestHttpException(_('No data to update this account with '));
140
            }
141
142
            //update password
143
            if (array_key_exists('new_password', $request) && (!empty($request['new_password']) && !empty($request['current_password']))) {
144
                //Ok let validate user password
145
                $validation = new Validation();
146
                $validation->add('new_password', new PresenceOf(['message' => 'The new_password is required.']));
147
                $validation->add('current_password', new PresenceOf(['message' => 'The current_password is required.']));
148
                $validation->add('confirm_new_password', new PresenceOf(['message' => 'The confirm_new_password is required.']));
149
                $messages = $validation->validate($request);
150
151
                if (count($messages)) {
152
                    foreach ($messages as $message) {
153
                        throw new BadRequestHttpException((string)$message);
154
                    }
155
                }
156
157
                $user->updatePassword($request['current_password'], $request['new_password'], $request['confirm_new_password']);
158
            } else {
159
                //remove on any actino that doesnt involve password
160
                unset($request['password']);
161
            }
162
163
            //change my default company
164
            if (array_key_exists('default_company', $request)) {
165
                if ($company = Companies::findFirst($request['default_company'])) {
166
                    if ($company->userAssociatedToCompany($this->userData)) {
167
                        $user->default_company = $company->getId();
168
                        unset($request['default_company']);
169
                    }
170
                }
171
            }
172
173
            //update
174
            if ($user->update($request, $this->updateFields)) {
175
                $user->password = null;
176
                return $this->response($user);
177
            } else {
178
                //didnt work
179
                throw new ModelException((string)current($user->getMessages()));
180
            }
181
        } else {
182
            throw new NotFoundHttpException('Record not found');
183
        }
184
    }
185
186
    /**
187
     * Add users notifications
188
     *
189
     * @param int $id
190
     * @method PUT
191
     * @return Response
192
     */
193
    public function updateNotifications(int $id) : Response
194
    {
195
        //get the notification array
196
        //delete the current ones
197
        //iterate and save into users
198
199
        return $this->response(['OK' => $id]);
200
    }
201
202
    /**
203
     * Associate a Device with the corrent loggedin user
204
     *
205
     * @url /users/{id}/device
206
     * @method POST
207
     * @return Response
208
     */
209 2
    public function devices() : Response
210
    {
211
        //Ok let validate user password
212 2
        $validation = new Validation();
213 2
        $validation->add('app', new PresenceOf(['message' => _('App name is required.')]));
214 2
        $validation->add('deviceId', new PresenceOf(['message' => _('device ID is required.')]));
215 2
        $msg = null;
216
217
        //validate this form for password
218 2
        $messages = $validation->validate($this->request->getPost());
219 2
        if (count($messages)) {
220
            foreach ($messages as $message) {
221
                throw new BadRequestHttpException((string)$message);
222
            }
223
        }
224
225 2
        $app = $this->request->getPost('app', 'string');
226 2
        $deviceId = $this->request->getPost('deviceId', 'string');
227
228
        //get the app source
229 2
        if ($source = Sources::getByTitle($app)) {
230 2
            $userSource = UserLinkedSources::findFirst([
231 2
                'conditions' => 'users_id = ?0 and source_users_id_text = ?1',
232 2
                'bind' => [$this->userData->getId(), $deviceId]
233
            ]);
234
235 2
            if (!is_object($userSource)) {
236 1
                $userSource = new UserLinkedSources();
237 1
                $userSource->users_id = $this->userData->getId();
238 1
                $userSource->source_id = $source->getId();
239 1
                $userSource->source_users_id = $this->userData->getId();
240 1
                $userSource->source_users_id_text = $deviceId;
241 1
                $userSource->source_username = $this->userData->displayname . ' ' . $app;
242
243 1
                if (!$userSource->save()) {
244
                    throw new UnprocessableEntityHttpException((string) current($userSource->getMessages()));
245
                }
246
247 1
                $msg = 'User Device Associated';
248
            } else {
249 1
                $msg = 'User Device Already Associated';
250
            }
251
        }
252
253
        //clean password @todo move this to a better place
254 2
        $this->userData->password = null;
255
256 2
        return $this->response([
257 2
            'msg' => $msg,
258 2
            'user' => $this->userData
259
        ]);
260
    }
261
262
    /**
263
     * Detach user's devices
264
     * @param integer $deviceId User's devices id
265
     * @return Response
266
     */
267 1
    public function detachDevice(int $id, int $deviceId): Response
268
    {
269
        //Validation
270 1
        $validation = new Validation();
271 1
        $validation->add('app', new PresenceOf(['message' => _('App name is required.')]));
272
273
        //validate this form for password
274 1
        $messages = $validation->validate($this->request->getPost());
275 1
        if (count($messages)) {
276
            foreach ($messages as $message) {
277
                throw new BadRequestHttpException((string)$message);
278
            }
279
        }
280
281 1
        $app = $this->request->getPost('app', 'string');
282
283
        //Get Source
284
285 1
        $source = Sources::getByTitle($app);
286
287 1
        if (!is_object($source)) {
288
            throw new NotFoundHttpException('Source not found');
289
        }
290
291 1
        $userSource = UserLinkedSources::findFirst([
292 1
                'conditions' => 'users_id = ?0 and source_id = ?1 and source_users_id_text = ?2 and is_deleted = 0',
293 1
                'bind' => [$this->userData->getId(), $source->getId(), $deviceId]
294
            ]);
295
296
        //Check if User Linked Sources exists by users_id and source_users_id_text
297 1
        if (!is_object($userSource)) {
298
            throw new NotFoundHttpException('User Linked Source not found');
299
        }
300
301 1
        $userSource->is_deleted = 1;
302 1
        if (!$userSource->update()) {
303
            throw new UnprocessableEntityHttpException((string) current($userSource->getMessages()));
304
        }
305
306 1
        return $this->response([
307 1
                'msg' => 'User Device detached',
308 1
                'user' => $this->userData
309
            ]);
310
    }
311
312
    /**
313
     * Get current active device of user
314
     * @return Response
315
     */
316
    public function getCurrentActiveDevice(): Response
317
    {
318
        $userSource = UserLinkedSources::findFirst([
319
            'conditions' => 'users_id = ?0 and source_id = ?1 and source_users_id = ?2 and is_deleted = 0',
320
            'bind' => [$this->userData->getId(), $this->app->getId(), $this->userData->getId()]
0 ignored issues
show
Bug Best Practice introduced by
The property app does not exist on Gewaer\Api\Controllers\UsersController. Since you implemented __get, consider adding a @property annotation.
Loading history...
321
        ]);
322
323
        if (!is_object($userSource)) {
324
            throw new NotFoundHttpException('User Linked Source not found');
325
        }
326
327
        return $this->response($userSource);
328
    }
329
}
330