Passed
Push — master ( d73137...7df3a2 )
by Maximo
02:52 queued 10s
created

UsersInviteController   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Test Coverage

Coverage 75.51%

Importance

Changes 0
Metric Value
eloc 98
dl 0
loc 203
ccs 74
cts 98
cp 0.7551
rs 10
c 0
b 0
f 0
wmc 16

4 Methods

Rating   Name   Duplication   Size   Complexity  
A onConstruct() 0 6 1
A insertInvite() 0 44 5
A getByHash() 0 12 2
B processUserInvite() 0 100 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewaer\Api\Controllers;
6
7
use Gewaer\Models\UsersInvite;
8
use Gewaer\Models\Users;
9
use Gewaer\Models\Roles;
10
use Phalcon\Security\Random;
11
use Phalcon\Validation;
12
use Phalcon\Validation\Validator\PresenceOf;
13
use Phalcon\Validation\Validator\StringLength;
14
use Gewaer\Exception\UnprocessableEntityHttpException;
15
use Gewaer\Exception\NotFoundHttpException;
16
use Gewaer\Exception\ServerErrorHttpException;
17
use Phalcon\Http\Response;
18
use Exception;
19
use Baka\Auth\Models\Sessions;
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
 * @package Gewaer\Api\Controllers
30
 *
31
 */
32
class UsersInviteController extends BaseController
33
{
34
    /*
35
     * fields we accept to create
36
     *
37
     * @var array
38
     */
39
    protected $createFields = ['invite_hash', 'companies_id', 'role_id', 'app_id', 'email'];
40
41
    /*
42
     * fields we accept to create
43
     *
44
     * @var array
45
     */
46
    protected $updateFields = ['invite_hash', 'companies_id', 'role_id', 'app_id', 'email'];
47
48
    /**
49
     * set objects
50
     *
51
     * @return void
52
     */
53 4
    public function onConstruct()
54
    {
55 4
        $this->model = new UsersInvite();
56 4
        $this->additionalSearchFields = [
57 4
            ['is_deleted', ':', '0'],
58 4
            ['companies_id', ':', $this->userData->currentCompanyId()],
59
        ];
60 4
    }
61
62
    /**
63
     * Get users invite by hash
64
     * @param string $hash
65
     * @return Response
66
     */
67 1
    public function getByHash(string $hash):Response
68
    {
69 1
        $userInvite = $this->model::findFirst([
70 1
            'conditions' => 'invite_hash =  ?0 and is_deleted = 0',
71 1
            'bind' => [$hash]
72
        ]);
73
74 1
        if (!is_object($userInvite)) {
75
            throw new NotFoundHttpException('Users Invite not found');
76
        }
77
78 1
        return $this->response($userInvite);
79
    }
80
81
    /**
82
     * Sets up invitation information for a would be user
83
     * @return Response
84
     */
85 4
    public function insertInvite(): Response
86
    {
87 4
        $request = $this->request->getPost();
88 4
        $random = new Random();
89
90 4
        $validation = new Validation();
91 4
        $validation->add('email', new PresenceOf(['message' => _('The email is required.')]));
92 4
        $validation->add('role_id', new PresenceOf(['message' => _('The role is required.')]));
93
94
        //validate this form for password
95 4
        $messages = $validation->validate($this->request->getPost());
96 4
        if (count($messages)) {
97
            foreach ($messages as $message) {
98
                throw new ServerErrorHttpException((string)$message);
99
            }
100
        }
101
102
        //Save data to users_invite table and generate a hash for the invite
103 4
        $userInvite = $this->model;
104 4
        $userInvite->companies_id = $this->userData->default_company;
105 4
        $userInvite->app_id = $this->app->getId();
106 4
        $userInvite->role_id = Roles::getById((int)$request['role_id']);
107 4
        $userInvite->email = $request['email'];
108 4
        $userInvite->invite_hash = $random->base58();
109 4
        $userInvite->created_at = date('Y-m-d H:m:s');
110
111 4
        if (!$userInvite->save()) {
112
            throw new UnprocessableEntityHttpException((string) current($userInvite->getMessages()));
113
        }
114
115
        // Lets send the mail
116
117 4
        $invitationUrl = $this->config->app->frontEndUrl . '/users/invites/' . $userInvite->invite_hash;
118
119 4
        if (!defined('API_TESTS')) {
120
            $subject = _('You have been invited!');
121
            $this->mail
122
            ->to($userInvite->email)
123
            ->subject($subject)
124
            ->content($invitationUrl)
125
            ->sendNow();
126
        }
127
128 4
        return $this->response($userInvite);
129
    }
130
131
    /**
132
     * Add invited user to our system
133
     * @return Response
134
     */
135 2
    public function processUserInvite(string $hash): Response
136
    {
137 2
        $request = $this->request->getPost();
138
139 2
        if (empty($request)) {
140
            $request = $this->request->getJsonRawBody(true);
141
        }
142
143
        //Ok let validate user password
144 2
        $validation = new Validation();
145 2
        $validation->add('password', new PresenceOf(['message' => _('The password is required.')]));
146
147 2
        $validation->add(
148 2
            'password',
149 2
            new StringLength([
150 2
                'min' => 8,
151 2
                'messageMinimum' => _('Password is too short. Minimum 8 characters.'),
152
            ])
153
        );
154
155
        //validate this form for password
156 2
        $messages = $validation->validate($request);
157 2
        if (count($messages)) {
158
            foreach ($messages as $message) {
159
                throw new ServerErrorHttpException((string)$message);
160
            }
161
        }
162
163
        //Lets find users_invite by hash on our database
164 2
        $usersInvite = $this->model::findFirst([
165 2
                'conditions' => 'invite_hash = ?0 and is_deleted = 0',
166 2
                'bind' => [$hash]
167
            ]);
168
169 2
        if (!is_object($usersInvite)) {
170
            throw new NotFoundHttpException('Users Invite not found');
171
        }
172
173 2
        $newUser = new Users();
174 2
        $newUser->firstname = $request['firstname'];
175 2
        $newUser->lastname = $request['lastname'];
176 2
        $newUser->displayname = $request['displayname'];
177 2
        $newUser->password = ltrim(trim($request['password']));
178 2
        $newUser->email = $usersInvite->email;
179 2
        $newUser->user_active = 1;
180 2
        $newUser->roles_id = $usersInvite->role_id;
181 2
        $newUser->created_at = date('Y-m-d H:m:s');
182 2
        $newUser->default_company = $usersInvite->companies_id;
183 2
        $newUser->default_company_branch = $usersInvite->company->branch->getId();
184
185
        try {
186 2
            $this->db->begin();
187
188
            //signup
189 2
            $newUser->signup();
190
191 2
            $this->db->commit();
192
        } catch (Exception $e) {
193
            $this->db->rollback();
194
195
            throw new UnprocessableEntityHttpException($e->getMessage());
196
        }
197
198
        //Lets login the new user
199 2
        $userIp = !defined('API_TESTS') ? $this->request->getClientAddress() : '127.0.0.1';
200
201 2
        $random = new \Phalcon\Security\Random();
202
203 2
        $password = ltrim(trim($request['password']));
204
205 2
        $userData = Users::login($newUser->email, $password, 1, 0, $userIp);
206
207 2
        $sessionId = $random->uuid();
208
209
        //save in user logs
210
        $payload = [
211 2
            'sessionId' => $sessionId,
212 2
            'email' => $userData->getEmail(),
213 2
            'iat' => time(),
214
        ];
215
216 2
        $token = $this->auth->make($payload);
217
218
        //start session
219 2
        $session = new Sessions();
220 2
        $session->start($userData, $sessionId, $token, $userIp, 1);
221
222 2
        if (!defined('API_TESTS')) {
223
            $usersInvite->is_deleted = 1;
224
            $usersInvite->update();
225
226
            return $this->response([
227
                'token' => $token,
228
                'time' => date('Y-m-d H:i:s'),
229
                'expires' => date('Y-m-d H:i:s', time() + $this->config->jwt->payload->exp),
230
                'id' => $userData->getId(),
231
            ]);
232
        }
233
234 2
        return $this->response($newUser);
235
    }
236
}
237