Completed
Push — master ( bb815b...fa0064 )
by Antonio
16s
created

SecurityController   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 50%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 8
dl 0
loc 142
ccs 23
cts 46
cp 0.5
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B behaviors() 0 26 1
A actions() 0 13 2
B actionLogin() 0 36 6
A actionLogout() 0 12 2
A authenticate() 0 4 1
A connect() 0 10 2
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-usuario project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\User\Controller;
13
14
use Da\User\Contracts\AuthClientInterface;
15
use Da\User\Event\FormEvent;
16
use Da\User\Event\UserEvent;
17
use Da\User\Form\LoginForm;
18
use Da\User\Query\SocialNetworkAccountQuery;
19
use Da\User\Service\SocialNetworkAccountConnectService;
20
use Da\User\Service\SocialNetworkAuthenticateService;
21
use Da\User\Traits\ContainerAwareTrait;
22
use Yii;
23
use yii\authclient\AuthAction;
24
use yii\base\Module;
25
use yii\filters\AccessControl;
26
use yii\filters\VerbFilter;
27
use yii\web\Controller;
28
use yii\web\Response;
29
use yii\widgets\ActiveForm;
30
31
class SecurityController extends Controller
32
{
33
    use ContainerAwareTrait;
34
35
    protected $socialNetworkAccountQuery;
36
37
    /**
38
     * SecurityController constructor.
39
     *
40
     * @param string                    $id
41
     * @param Module                    $module
42
     * @param SocialNetworkAccountQuery $socialNetworkAccountQuery
43
     * @param array                     $config
44
     */
45 4
    public function __construct(
46
        $id,
47
        Module $module,
48
        SocialNetworkAccountQuery $socialNetworkAccountQuery,
49
        array $config = []
50
    ) {
51 4
        $this->socialNetworkAccountQuery = $socialNetworkAccountQuery;
52 4
        parent::__construct($id, $module, $config);
53 4
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 4
    public function behaviors()
59
    {
60
        return [
61 4
            'access' => [
62 4
                'class' => AccessControl::className(),
63
                'rules' => [
64
                    [
65
                        'allow' => true,
66
                        'actions' => ['login', 'auth', 'blocked'],
67
                        'roles' => ['?'],
68
                    ],
69
                    [
70
                        'allow' => true,
71
                        'actions' => ['login', 'auth', 'logout'],
72
                        'roles' => ['@'],
73
                    ],
74
                ],
75
            ],
76
            'verbs' => [
77 4
                'class' => VerbFilter::className(),
78
                'actions' => [
79
                    'logout' => ['post'],
80
                ],
81
            ],
82
        ];
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 4
    public function actions()
89
    {
90
        return [
91
            'auth' => [
92 4
                'class' => AuthAction::className(),
93
                // if user is not logged in, will try to log him in, otherwise
94
                // will try to connect social account to user.
95 4
                'successCallback' => Yii::$app->user->isGuest
96 4
                    ? [$this, 'authenticate']
97 4
                    : [$this, 'connect'],
98
            ],
99
        ];
100
    }
101
102
    /**
103
     * Controller action responsible for handling login page and actions.
104
     *
105
     * @return array|string|Response
106
     */
107 4
    public function actionLogin()
108
    {
109 4
        if (!Yii::$app->user->getIsGuest()) {
110
            return $this->goHome();
111
        }
112
113
        /** @var LoginForm $form */
114 4
        $form = $this->make(LoginForm::class);
115
        /** @var FormEvent $event */
116 4
        $event = $this->make(FormEvent::class, [$form]);
117
118 4
        if (Yii::$app->request->isAjax && $form->load(Yii::$app->request->post())) {
119
            Yii::$app->response->format = Response::FORMAT_JSON;
120
121
            return ActiveForm::validate($form);
122
        }
123
124 4
        if ($form->load(Yii::$app->request->post())) {
125
            $this->trigger(FormEvent::EVENT_BEFORE_LOGIN, $event);
126
            if ($form->login()) {
127
                Yii::$app->getUser()->identity->updateAttributes(['last_login_at' => time()]);
0 ignored issues
show
Bug introduced by
The method getUser does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
128
129
                $this->trigger(FormEvent::EVENT_AFTER_LOGIN, $event);
130
131
                return $this->goBack();
132
            }
133
        }
134
135 4
        return $this->render(
136 4
            'login',
137
            [
138 4
                'model' => $form,
139 4
                'module' => $this->module,
140
            ]
141
        );
142
    }
143
144
    public function actionLogout()
145
    {
146
        $event = $this->make(UserEvent::class, [Yii::$app->getUser()->getIdentity()]);
0 ignored issues
show
Bug introduced by
The method getUser does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
147
148
        $this->trigger(UserEvent::EVENT_BEFORE_LOGOUT, $event);
149
150
        if (Yii::$app->getUser()->logout()) {
151
            $this->trigger(UserEvent::EVENT_AFTER_LOGOUT, $event);
152
        }
153
154
        return $this->goHome();
155
    }
156
157
    public function authenticate(AuthClientInterface $client)
158
    {
159
        $this->make(SocialNetworkAuthenticateService::class, [$this, $this->action, $client])->run();
160
    }
161
162
    public function connect(AuthClientInterface $client)
163
    {
164
        if (Yii::$app->user->isGuest) {
165
            Yii::$app->session->setFlash('danger', Yii::t('usuario', 'Something went wrong'));
166
167
            return;
168
        }
169
170
        $this->make(SocialNetworkAccountConnectService::class, [$this, $client])->run();
171
    }
172
}
173