Test Failed
Push — master ( dbfe7c...50c310 )
by Maximo
12:22 queued 06:18
created

UsersInviteController::insertInvite()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 48
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 29
c 1
b 0
f 0
nc 7
nop 0
dl 0
loc 48
ccs 0
cts 36
cp 0
crap 30
rs 9.1448
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Canvas\Api\Controllers;
6
7
use Canvas\Models\UsersInvite;
8
use Canvas\Models\Users;
9
use Canvas\Models\Roles;
10
use Phalcon\Security\Random;
0 ignored issues
show
Bug introduced by
The type Phalcon\Security\Random was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Phalcon\Validation;
12
use Phalcon\Validation\Validator\PresenceOf;
0 ignored issues
show
Bug introduced by
The type Phalcon\Validation\Validator\PresenceOf was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Phalcon\Validation\Validator\StringLength;
0 ignored issues
show
Bug introduced by
The type Phalcon\Validation\Validator\StringLength was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Canvas\Exception\UnprocessableEntityHttpException;
15
use Canvas\Exception\NotFoundHttpException;
16
use Canvas\Exception\ServerErrorHttpException;
17
use Phalcon\Http\Response;
18
use Exception;
19
use Canvas\Exception\ModelException;
20
use Canvas\Traits\AuthTrait;
21
use Canvas\Notifications\Invitation;
22
23
/**
24
 * Class LanguagesController.
25
 * @property Users $userData
26
 * @property Request $request
27
 * @property Config $config
28
 * @property Apps $app
29
 * @property Mail $mail
30
 * @property Auth $auth
31
 * @property Payload $payload
32
 * @property Exp $exp
33
 * @property JWT $jwt
34
 * @package Canvas\Api\Controllers
35
 *
36
 */
37
class UsersInviteController extends BaseController
38
{
39
    use AuthTrait;
40
41
    /*
42
     * fields we accept to create
43
     *
44
     * @var array
45
     */
46
    protected $createFields = ['invite_hash', 'companies_id', 'role_id', 'app_id', 'email'];
47
48
    /*
49
     * fields we accept to create
50
     *
51
     * @var array
52
     */
53
    protected $updateFields = ['invite_hash', 'companies_id', 'role_id', 'app_id', 'email'];
54
55
    /**
56
     * set objects.
57
     *
58
     * @return void
59
     */
60
    public function onConstruct()
61
    {
62
        $this->model = new UsersInvite();
63
        $additionaFields = [
64
            ['is_deleted', ':', '0'],
65
        ];
66
67
        if ($this->di->has('userData')) {
68
            $additionaFields[] = ['companies_id', ':', $this->userData->currentCompanyId()];
69
        }
70
71
        $this->additionalSearchFields = $additionaFields;
72
    }
73
74
    /**
75
     * Get users invite by hash.
76
     * @param string $hash
77
     * @return Response
78
     */
79
    public function getByHash(string $hash):Response
80
    {
81
        $userInvite = $this->model::findFirst([
82
            'conditions' => 'invite_hash =  ?0 and is_deleted = 0',
83
            'bind' => [$hash]
84
        ]);
85
86
        if (!is_object($userInvite)) {
87
            throw new NotFoundHttpException('Users Invite not found');
88
        }
89
90
        return $this->response($userInvite);
91
    }
92
93
    /**
94
     * Sets up invitation information for a would be user.
95
     * @return Response
96
     */
97
    public function insertInvite(): Response
98
    {
99
        $request = $this->request->getPost();
100
        $random = new Random();
101
102
        $validation = new Validation();
103
        $validation->add('email', new PresenceOf(['message' => _('The email is required.')]));
104
        $validation->add('role_id', new PresenceOf(['message' => _('The role is required.')]));
105
106
        //validate this form for password
107
        $messages = $validation->validate($this->request->getPost());
108
        if (count($messages)) {
109
            foreach ($messages as $message) {
110
                throw new ServerErrorHttpException((string)$message);
111
            }
112
        }
113
114
        //Check if user was already was invited to current company and return message
115
        $invitedUser = $this->model::findFirst([
116
            'conditions' => 'email = ?0 and companies_id = ?1 and role_id = ?2',
117
            'bind' => [$request['email'], $this->userData->default_company, $request['role_id']]
118
        ]);
119
120
        if (is_object($invitedUser)) {
121
            throw new ModelException('User already invited to this company and added with this role');
122
        }
123
124
        //Save data to users_invite table and generate a hash for the invite
125
        $userInvite = $this->model;
126
        $userInvite->companies_id = $this->userData->default_company;
127
        $userInvite->users_id = $this->userData->getId();
128
        $userInvite->app_id = $this->app->getId();
129
        $userInvite->role_id = Roles::existsById((int)$request['role_id'])->id;
130
        $userInvite->email = $request['email'];
131
        $userInvite->invite_hash = $random->base58();
132
        $userInvite->created_at = date('Y-m-d H:m:s');
133
134
        if (!$userInvite->save()) {
135
            throw new UnprocessableEntityHttpException((string) current($userInvite->getMessages()));
136
        }
137
138
        //create temp invite users
139
        $tempUser = new Users();
140
        $tempUser->id = 0;
141
        $tempUser->email = $request['email'];
142
        $tempUser->notify(new Invitation($userInvite));
143
        
144
        return $this->response($userInvite);
145
    }
146
147
    /**
148
     * Add invited user to our system.
149
     * @return Response
150
     */
151
    public function processUserInvite(string $hash): Response
152
    {
153
        $request = $this->request->getPost();
154
        $password = ltrim(trim($request['password']));
155
156
        if (empty($request)) {
157
            $request = $this->request->getJsonRawBody(true);
158
        }
159
160
        //Ok let validate user password
161
        $validation = new Validation();
162
        $validation->add('password', new PresenceOf(['message' => _('The password is required.')]));
163
164
        $validation->add(
165
            'password',
166
            new StringLength([
167
                'min' => 8,
168
                'messageMinimum' => _('Password is too short. Minimum 8 characters.'),
169
            ])
170
        );
171
172
        //validate this form for password
173
        $messages = $validation->validate($request);
174
        if (count($messages)) {
175
            foreach ($messages as $message) {
176
                throw new ServerErrorHttpException((string)$message);
177
            }
178
        }
179
180
        //Lets find users_invite by hash on our database
181
        $usersInvite = $this->model::findFirst([
182
            'conditions' => 'invite_hash = ?0 and is_deleted = 0',
183
            'bind' => [$hash]
184
        ]);
185
186
        if (!is_object($usersInvite)) {
187
            throw new NotFoundHttpException('Users Invite not found');
188
        }
189
190
        $this->setUserDataById((int)$usersInvite->users_id);
191
192
        //Check if user already exists
193
        $userExists = Users::findFirst([
194
            'conditions' => 'email = ?0 and is_deleted = 0',
195
            'bind' => [$usersInvite->email]
196
        ]);
197
198
        if (is_object($userExists)) {
199
            $newUser = $userExists;
200
            $this->userData->defaultCompany->associate($userExists, $this->userData->defaultCompany);
201
        } else {
202
            $newUser = new Users();
203
            $newUser->firstname = $request['firstname'];
204
            $newUser->lastname = $request['lastname'];
205
            $newUser->displayname = $request['displayname'];
206
            $newUser->password = $password;
207
            $newUser->email = $usersInvite->email;
208
            $newUser->user_active = 1;
209
            $newUser->roles_id = $usersInvite->role_id;
210
            $newUser->created_at = date('Y-m-d H:m:s');
211
            $newUser->default_company = $usersInvite->companies_id;
212
            $newUser->default_company_branch = $usersInvite->company->branch->getId();
213
214
            try {
215
                $this->db->begin();
216
217
                //signup
218
                $newUser->signup();
219
220
                $this->db->commit();
221
            } catch (Exception $e) {
222
                $this->db->rollback();
223
224
                throw new UnprocessableEntityHttpException($e->getMessage());
225
            }
226
        }
227
228
        //associate the user and the app + company
229
        $this->app->associate($newUser, $usersInvite->company);
230
231
        //Lets login the new user
232
        $authInfo = $this->loginUsers($usersInvite->email, $password);
233
234
        if (!defined('API_TESTS')) {
235
            $usersInvite->is_deleted = 1;
236
            $usersInvite->update();
237
238
            return $this->response($authInfo);
239
        }
240
241
        return $this->response($newUser);
242
    }
243
}
244