Failed Conditions
Pull Request — master (#342)
by Maximo
02:25
created

UsersInviteController::onConstruct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 12
ccs 0
cts 5
cp 0
crap 6
rs 10
c 0
b 0
f 0
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\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...
12
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...
13
use Canvas\Exception\NotFoundHttpException;
14
use Phalcon\Http\Response;
0 ignored issues
show
Bug introduced by
The type Phalcon\Http\Response 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...
15
use Exception;
16
use Canvas\Http\Exception\UnprocessableEntityException;
17
use Canvas\Traits\AuthTrait;
18
use Canvas\Notifications\Invitation;
19
use Canvas\Validation as CanvasValidation;
20
21
/**
22
 * Class LanguagesController.
23
 * @property Users $userData
24
 * @property Request $request
25
 * @property Config $config
26
 * @property Apps $app
27
 * @property Mail $mail
28
 * @property Auth $auth
29
 * @property Payload $payload
30
 * @property Exp $exp
31
 * @property JWT $jwt
32
 * @package Canvas\Api\Controllers
33
 *
34
 */
35
class UsersInviteController extends BaseController
36
{
37
    use AuthTrait;
38
39
    /*
40
     * fields we accept to create
41
     *
42
     * @var array
43
     */
44
    protected $createFields = [
45
        'invite_hash',
46
        'companies_id',
47
        'role_id',
48
        'app_id',
49
        'email'
50
    ];
51
52
    /*
53
     * fields we accept to create
54
     *
55
     * @var array
56
     */
57
    protected $updateFields = [
58
        'invite_hash',
59
        'companies_id',
60
        'role_id',
61
        'app_id',
62
        'email'
63
    ];
64
65
    /**
66
     * set objects.
67
     *
68
     * @return void
69
     */
70
    public function onConstruct()
71
    {
72
        $this->model = new UsersInvite();
0 ignored issues
show
Bug Best Practice introduced by
The property model does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
73
        $additionaFields = [
74
            ['is_deleted', ':', '0'],
75
        ];
76
77
        if ($this->di->has('userData')) {
78
            $additionaFields[] = ['companies_id', ':', $this->userData->currentCompanyId()];
79
        }
80
81
        $this->additionalSearchFields = $additionaFields;
0 ignored issues
show
Bug Best Practice introduced by
The property additionalSearchFields does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
82
    }
83
84
    /**
85
     * Get users invite by hash.
86
     * @param string $hash
87
     * @return Response
88
     */
89
    public function getByHash(string $hash):Response
90
    {
91
        $userInvite = $this->model::findFirst([
92
            'conditions' => 'invite_hash =  ?0 and is_deleted = 0',
93
            'bind' => [$hash]
94
        ]);
95
96
        if (!is_object($userInvite)) {
97
            throw new NotFoundHttpException('Users Invite not found');
0 ignored issues
show
Deprecated Code introduced by
The class Canvas\Exception\NotFoundHttpException has been deprecated: version 0.1.5 ( Ignorable by Annotation )

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

97
            throw /** @scrutinizer ignore-deprecated */ new NotFoundHttpException('Users Invite not found');
Loading history...
98
        }
99
100
        return $this->response($userInvite);
101
    }
102
103
    /**
104
     * Sets up invitation information for a would be user.
105
     * @return Response
106
     */
107
    public function insertInvite(): Response
108
    {
109
        $request = $this->request->getPostData();
110
        $random = new Random();
111
112
        $validation = new CanvasValidation();
113
        $validation->add('email', new PresenceOf(['message' => _('The email is required.')]));
114
        $validation->add('role_id', new PresenceOf(['message' => _('The role is required.')]));
115
116
        //validate this form for password
117
        $validation->validate($request);
118
119
        //Check if user was already was invited to current company and return message
120
        UsersInvite::isValid($request['email'], (int) $request['role_id']);
121
122
        //Save data to users_invite table and generate a hash for the invite
123
        $userInvite = $this->model;
124
        $userInvite->companies_id = $this->userData->getDefaultCompany()->getId();
125
        $userInvite->users_id = $this->userData->getId();
126
        $userInvite->app_id = $this->app->getId();
127
        $userInvite->role_id = Roles::existsById((int)$request['role_id'])->id;
128
        $userInvite->email = $request['email'];
129
        $userInvite->invite_hash = $random->base58();
130
        $userInvite->created_at = date('Y-m-d H:m:s');
131
132
        if (!$userInvite->save()) {
133
            throw new UnprocessableEntityException((string) current($userInvite->getMessages()));
134
        }
135
136
        //create temp invite users
137
        $tempUser = new Users();
138
        $tempUser->id = 0;
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
139
        $tempUser->email = $request['email'];
0 ignored issues
show
Bug Best Practice introduced by
The property email does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
140
        $tempUser->notify(new Invitation($userInvite));
141
142
        return $this->response($userInvite);
143
    }
144
145
    /**
146
     * Add invited user to our system.
147
     * @return Response
148
     */
149
    public function processUserInvite(string $hash): Response
150
    {
151
        $request = $this->request->getPostData();
152
        $request['password'] = ltrim(trim($request['password']));
153
154
        //Ok let validate user password
155
        $validation = new CanvasValidation();
156
        $validation->add('password', new PresenceOf(['message' => _('The password is required.')]));
157
158
        $validation->add(
159
            'password',
160
            new StringLength([
161
                'min' => 8,
162
                'messageMinimum' => _('Password is too short. Minimum 8 characters.'),
163
            ])
164
        );
165
166
        //validate this form for password
167
        $validation->validate($request);
168
169
        //Lets find users_invite by hash on our database
170
        $usersInvite = UsersInvite::getByHash($hash);
171
172
        //set userData as the user who is inviting the user
173
        $this->setUserDataById((int)$usersInvite->users_id);
174
175
        try {
176
            //Check if user already exists
177
            $userExists = Users::getByEmail($usersInvite->email);
178
            $newUser = $userExists;
179
            $this->userData->getDefaultCompany()->associate($userExists, $this->userData->getDefaultCompany());
180
        } catch (Exception $e) {
181
            try {
182
                $newUser = $usersInvite->newUser($request);
183
184
                $this->db->begin();
185
186
                //signup
187
                $newUser->signup();
188
189
                $this->db->commit();
190
            } catch (Exception $e) {
191
                $this->db->rollback();
192
193
                throw new UnprocessableEntityException($e->getMessage());
194
            }
195
        }
196
197
        //associate the user and the app + company
198
        $this->app->associate($newUser, $usersInvite->company);
199
        $this->events->fire('user:afterInvite', $newUser, $usersInvite);
200
201
        //Lets login the new user
202
        $authInfo = $this->loginUsers($usersInvite->email, $request['password']);
203
204
        if (!defined('API_TESTS')) {
205
            $usersInvite->softDelete();
206
207
            return $this->response([
208
                'user' => $newUser,
209
                'session' => $authInfo
210
            ]);
211
        }
212
213
        return $this->response($newUser);
214
    }
215
}
216