SocialNetworkAuthenticateService   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 9
dl 0
loc 90
ccs 0
cts 68
cp 0
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
B run() 0 37 8
A createAccount() 0 24 2
A getUser() 0 4 1
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\Service;
13
14
use Da\User\Contracts\AuthClientInterface;
15
use Da\User\Contracts\ServiceInterface;
16
use Da\User\Controller\SecurityController;
17
use Da\User\Event\SocialNetworkAuthEvent;
18
use Da\User\Model\SocialNetworkAccount;
19
use Da\User\Model\User;
20
use Da\User\Query\SocialNetworkAccountQuery;
21
use Da\User\Query\UserQuery;
22
use Yii;
23
use yii\authclient\AuthAction;
24
use yii\helpers\Url;
25
26
class SocialNetworkAuthenticateService implements ServiceInterface
27
{
28
    protected $controller;
29
    protected $authAction;
30
    protected $client;
31
    protected $socialNetworkAccountQuery;
32
    protected $userQuery;
33
34
    public function __construct(
35
        SecurityController $controller,
36
        AuthAction $authAction,
37
        AuthClientInterface $client,
38
        SocialNetworkAccountQuery $socialNetworkAccountQuery,
39
        UserQuery $userQuery
40
    ) {
41
        $this->controller = $controller;
42
        $this->authAction = $authAction;
43
        $this->client = $client;
44
        $this->socialNetworkAccountQuery = $socialNetworkAccountQuery;
45
        $this->userQuery = $userQuery;
46
    }
47
48
    public function run()
49
    {
50
        $account = $this->socialNetworkAccountQuery->whereClient($this->client)->one();
51
        if (!$this->controller->module->enableRegistration && ($account === null || $account->user === null)) {
52
            Yii::$app->session->setFlash('danger', Yii::t('usuario', 'Registration on this website is disabled'));
53
            $this->authAction->setSuccessUrl(Url::to(['/user/security/login']));
54
55
            return false;
56
        }
57
        if ($account === null) {
58
            $account = $this->createAccount();
59
            if (!$account) {
60
                Yii::$app->session->setFlash('danger', Yii::t('usuario', 'Unable to create an account.'));
61
                $this->authAction->setSuccessUrl(Url::to(['/user/security/login']));
62
63
                return false;
64
            }
65
        }
66
67
        $event = Yii::createObject(SocialNetworkAuthEvent::class, [$account, $this->client]);
68
69
        $this->controller->trigger(SocialNetworkAuthEvent::EVENT_BEFORE_AUTHENTICATE, $event);
70
71
        if ($account->user instanceof User) {
72
            if ($account->user->getIsBlocked()) {
73
                Yii::$app->session->setFlash('danger', Yii::t('usuario', 'Your account has been blocked.'));
74
                $this->authAction->setSuccessUrl(Url::to(['/user/security/login']));
75
            } else {
76
                Yii::$app->user->login($account->user, $this->controller->module->rememberLoginLifespan);
77
                $this->authAction->setSuccessUrl(Yii::$app->getUser()->getReturnUrl());
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...
78
            }
79
        } else {
80
            $this->authAction->setSuccessUrl($account->getConnectionUrl());
81
        }
82
83
        $this->controller->trigger(SocialNetworkAuthEvent::EVENT_AFTER_AUTHENTICATE, $event);
84
    }
85
86
    protected function createAccount()
87
    {
88
        $data = $this->client->getUserAttributes();
89
90
        /** @var SocialNetworkAccount $account */
91
        $account = $this->controller->make(
92
            SocialNetworkAccount::class,
93
            [],
94
            [
95
                'provider' => $this->client->getId(),
96
                'client_id' => $data['id'],
97
                'data' => json_encode($data),
98
                'username' => $this->client->getUserName(),
99
                'email' => $this->client->getEmail(),
100
            ]
101
        );
102
103
        if (($user = $this->getUser($account)) instanceof User) {
104
            $account->user_id = $user->id;
105
            $account->save(false);
106
        }
107
108
        return $account;
109
    }
110
111
    protected function getUser(SocialNetworkAccount $account)
112
    {
113
        return $this->userQuery->whereEmail($account->email)->one();
114
    }
115
}
116