UserProvider::connect()   B
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 0
cts 17
cp 0
rs 8.9713
c 0
b 0
f 0
cc 2
eloc 14
nc 2
nop 2
crap 6
1
<?php
2
3
namespace OSS\UserBundle\Services;
4
5
use FOS\UserBundle\Event\FilterUserResponseEvent;
6
use FOS\UserBundle\FOSUserEvents;
7
use FOS\UserBundle\Model\UserManagerInterface;
8
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
9
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider;
10
use OSS\UserBundle\Entity\User;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpFoundation\Response;
14
use Symfony\Component\Security\Core\User\UserInterface;
15
16
class UserProvider extends FOSUBUserProvider
17
{
18
    /**
19
     * @var EventDispatcherInterface
20
     */
21
    private $dispatcher;
22
23
    /**
24
     * @param UserManagerInterface $userManager
25
     * @param EventDispatcherInterface $dispatcher
26
     * @param array $properties
27
     */
28
    public function __construct(UserManagerInterface $userManager, EventDispatcherInterface $dispatcher, array $properties)
29
    {
30
        $this->dispatcher = $dispatcher;
31
        parent::__construct($userManager, $properties);
32
    }
33
34
    public function connect(UserInterface $user, UserResponseInterface $response)
35
    {
36
        $property = $this->getProperty($response);
37
        $username = $response->getUsername();
38
        
39
        $service = $response->getResourceOwner()->getName();
40
        
41
        $setter = 'set' . ucfirst($service);
42
        $setterId = $setter . 'Id';
43
        $setterToken = $setter . 'AccessToken';
44
        
45
        // disconnect previously connected users
46
        if (null !== $previousUser = $this->userManager->findUserBy(array($property => $username))) {
47
            $previousUser->$setterId(null);
48
            $previousUser->$setterToken(null);
49
            $this->userManager->updateUser($previousUser);
50
        }
51
        
52
        // connect current user
53
        $user->$setterId($username);
54
        $user->$setterToken($response->getAccessToken());
55
        
56
        $this->userManager->updateUser($user);
0 ignored issues
show
Compatibility introduced by
$user of type object<Symfony\Component...ore\User\UserInterface> is not a sub-type of object<FOS\UserBundle\Model\UserInterface>. It seems like you assume a child interface of the interface Symfony\Component\Security\Core\User\UserInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
57
    }
58
59
    public function loadUserByOAuthUserResponse(UserResponseInterface $response)
60
    {
61
        $id = $response->getUsername();
62
        $user = $this->userManager->findUserBy(array($this->getProperty($response) => $id));
63
64
        return $this->isUserExisting($user) ? $this->initExistingUser($response) : $this->createUser($response, $id);
65
    }
66
67
    /**
68
     * @param UserInterface|null $user
69
     *
70
     * @return bool
71
     */
72
    private function isUserExisting($user)
73
    {
74
        return null !== $user;
75
    }
76
77
    /**
78
     * @param UserResponseInterface $response
79
     *
80
     * @return UserInterface
81
     */
82
    private function initExistingUser(UserResponseInterface $response)
83
    {
84
        $user = parent::loadUserByOAuthUserResponse($response);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (loadUserByOAuthUserResponse() instead of initExistingUser()). Are you sure this is correct? If so, you might want to change this to $this->loadUserByOAuthUserResponse().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
85
86
        $serviceName = $response->getResourceOwner()->getName();
87
        $setter = 'set' . ucfirst($serviceName) . 'AccessToken';
88
89
        // update access token
90
        $user->$setter($response->getAccessToken());
91
92
        return $user;
93
    }
94
95
    /**
96
     * @param UserResponseInterface $response
97
     * @param int $id
98
     *
99
     * @return User
100
     */
101
    public function createUser(UserResponseInterface $response, $id)
102
    {
103
        $service = $response->getResourceOwner()->getName();
104
        $setter = 'set' . ucfirst($service);
105
        $setterId = $setter . 'Id';
106
        $setterToken = $setter . 'AccessToken';
107
108
        /** @var User $user */
109
        $user = $this->userManager->createUser();
110
        $user->$setterId($id);
111
        $user->$setterToken($response->getAccessToken());
112
113
        $user->setUsername($id);
114
        $user->setEmail($response->getEmail() !== null ? $response->getEmail() : $id . '@nomail.com');
115
        $user->setPlainPassword($id);
116
        $user->setEnabled(true);
117
        $this->userManager->updateUser($user);
118
119
        $this->dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, new Request(), new Response()));
120
121
        return $user;
122
    }
123
}
124