Test Failed
Pull Request — master (#160)
by Maximo
07:08
created

UsersInviteController::processUserInvite()   A

Complexity

Conditions 4
Paths 14

Size

Total Lines 63
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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