Passed
Push — master ( 939347...72ceee )
by Mihail
07:40
created

User::actionApprove()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
rs 8.439
cc 5
eloc 13
nc 3
nop 2
1
<?php
2
3
namespace Apps\Controller\Front;
4
5
use Apps\ActiveRecord\Invite;
6
use Apps\ActiveRecord\UserRecovery;
7
use Apps\Model\Front\User\FormRecovery;
8
use Apps\Model\Front\User\FormRegister;
9
use Extend\Core\Arch\FrontAppController;
10
use Ffcms\Core\App;
11
use Apps\Model\Front\User\FormLogin;
12
use Ffcms\Core\Arch\View;
13
use Ffcms\Core\Exception\ForbiddenException;
14
use Ffcms\Core\Exception\NotFoundException;
15
use Ffcms\Core\Helper\Type\Obj;
16
use Ffcms\Core\Helper\Type\Str;
17
18
/**
19
 * Class User - standard user controller: login/signup/logout/etc
20
 * @package Apps\Controller\Front
21
 */
22
class User extends FrontAppController
23
{
24
    /**
25
     * View login form and process submit action
26
     * @throws ForbiddenException
27
     */
28
    public function actionLogin()
29
    {
30
        if (App::$User->isAuth()) { // always auth? get the f*ck out
31
            throw new ForbiddenException();
32
        }
33
34
        $configs = $this->getConfigs();
35
        // load login model
36
        $loginForm = new FormLogin($configs['captchaOnLogin'] === 1);
37
38
        // check if data is send and valid
39
        if ($loginForm->send() && $loginForm->validate()) {
40
            if ($loginForm->tryAuth()) {
41
                App::$Response->redirect('/'); // void header change & exit()
42
            }
43
            App::$Session->getFlashBag()->add('error', __('User is never exist or password is incorrect!'));
44
        }
45
46
        // render view
47
        return App::$View->render('login', [
48
            'model' => $loginForm->export(),
49
            'useCaptcha' => $configs['captchaOnLogin'] === 1
50
        ]);
51
    }
52
53
    /**
54
     * View register form and process submit action
55
     * @throws ForbiddenException
56
     */
57
    public function actionSignup()
58
    {
59
        if (App::$User->isAuth()) { // always auth? prevent any actions
60
            throw new ForbiddenException();
61
        }
62
63
        // load configs
64
        $configs = $this->getConfigs();
65
66
        // init register model
67
        $registerForm = new FormRegister($configs['captchaOnRegister'] === 1);
68
69
        // registration based on invite. Check conditions.
70
        if ($configs['registrationType'] === 0) {
71
            // get token and email
72
            $inviteToken = App::$Request->query->get('token');
73
            $inviteEmail = App::$Request->query->get('email');
74
            // data sounds like a invalid?
75
            if (Str::length($inviteToken) < 32 || !Str::isEmail($inviteEmail)) {
76
                throw new ForbiddenException(__('Registration allowed only if you have invite!'));
77
            }
78
            // remove oldest data
79
            Invite::clean();
80
            // try to find token
81
            $find = Invite::where('token', '=', $inviteToken)
82
                ->where('email', '=', $inviteEmail)->count();
83
84
            // token not foud? invalid invite key
85
            if ($find !== 1) {
86
                throw new ForbiddenException(__('Your invite token is invalid! Contact with administrator'));
87
            }
88
            // notify the invite token is accepted
89
            if (!$registerForm->send()) {
90
                App::$Session->getFlashBag()->add('success', __('Invite was accepted! Continue registration'));
91
            }
92
93
            // set email from token data
94
            $registerForm->email = $inviteEmail;
95
        }
96
97
        // if register data is send and valid
98
        if ($registerForm->send() && $registerForm->validate()) {
99
            if ($registerForm->tryRegister($configs['registrationType'] === 1)) {
100
                App::$Session->getFlashBag()->add('success', __('Your account is registered. You must confirm account via email'));
101
            } else {
102
                App::$Session->getFlashBag()->add('error', __('Login or email is always used on website'));
103
            }
104
        }
105
106
        // render view
107
        return App::$View->render('signup', [
108
            'model' => $registerForm->export(),
109
            'config' => $configs,
110
            'useCaptcha' => $configs['captchaOnRegister'] === 1
111
        ]);
112
    }
113
114
    /**
115
     * Recovery form and recovery submit action
116
     * @param int|null $id
117
     * @param string|null $token
118
     * @throws ForbiddenException
119
     * @throws NotFoundException
120
     * @throws \Ffcms\Core\Exception\SyntaxException
121
     */
122
    public function actionRecovery($id = null, $token = null)
123
    {
124
        if (App::$User->isAuth()) { // always auth? prevent any actions
125
            throw new ForbiddenException();
126
        }
127
128
        // is recovery submit?
129
        if (Obj::isLikeInt($id) && Str::length($token) >= 64) {
130
            $rObject = UserRecovery::where('id', '=', $id)
131
                ->where('token', '=', $token)
132
                ->where('archive', '=', false);
133
            // check if recovery row exist
134
            if ($rObject->count() !== 1) {
135
                throw new NotFoundException('This recovery data is not found');
136
            }
137
138
            $rData = $rObject->first();
139
            // check if user with this "user_id" in recovery row exist
140
            $rUser = App::$User->identity($rData->user_id);
141
            if ($rUser === null) {
142
                throw new NotFoundException('User is not found');
143
            }
144
145
            // all is ok, lets set new pwd
146
            $rUser->password = $rData->password;
0 ignored issues
show
Bug introduced by
Accessing password on the interface Ffcms\Core\Interfaces\iUser suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
147
            $rUser->save();
148
149
            $rData->archive = true;
150
            $rData->save();
151
152
            // add notification
153
            App::$Session->getFlashBag()->add('success', __('Your account are successful recovered. We recommend you change password'));
154
155
            // lets open user session with recovered data
156
            $loginModel = new FormLogin();
157
            $loginModel->openSession($rUser);
158
            App::$Response->redirect('/'); // session is opened, refresh page
159
        }
160
161
        // lets work with recovery form data
162
        $model = new FormRecovery();
163
        if ($model->send()) {
164
            if ($model->validate()) {
165
                $model->make();
166
                App::$Session->getFlashBag()->add('success', __('We send to you email with instruction to recovery your account'));
167
            } else {
168
                App::$Session->getFlashBag()->add('error', __('Form validation is failed'));
169
            }
170
        }
171
172
        // render visual form content
173
        return App::$View->render('recovery', [
174
            'model' => $model
175
        ]);
176
    }
177
178
    /**
179
     * Make logout if user is signIn
180
     * @throws ForbiddenException
181
     */
182
    public function actionLogout()
183
    {
184
        if (!App::$User->isAuth()) { // not auth? what you wanna?
185
            throw new ForbiddenException();
186
        }
187
188
        // unset session data
189
        App::$Session->invalidate();
190
191
        // redirect to main
192
        App::$Response->redirect('/');
193
    }
194
195
    /**
196
     * Approve user profile via $email and $token params
197
     * @param $email
198
     * @param $token
199
     * @throws ForbiddenException
200
     */
201
    public function actionApprove($email, $token)
202
    {
203
        // sounds like a not valid token
204
        if (App::$User->isAuth() || Str::length($token) < 32 || !Str::isEmail($email)) {
205
            throw new ForbiddenException();
206
        }
207
        // lets find token&email
208
        $find = App::$User->where('approve_token', '=', $token)
209
            ->where('email', '=', $email);
210
211
        // not found? exit
212
        if ($find->count() !== 1) {
213
            throw new ForbiddenException();
214
        }
215
216
        // get row and update approve information
217
        $user = $find->first();
218
        $user->approve_token = '0';
219
        $user->save();
220
221
        // open session and redirect to main
222
        $loginModel = new FormLogin();
223
        $loginModel->openSession($user);
224
        App::$Response->redirect('/'); // session is opened, refresh page
225
    }
226
}