Completed
Push — master ( 2b347b...3bf2b4 )
by Brian
11s
created

AbstractProvider::userFromTokenAndSecret()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 2
1
<?php
2
3
namespace SocialiteProviders\Manager\OAuth1;
4
5
use Laravel\Socialite\One\AbstractProvider as BaseProvider;
6
use SocialiteProviders\Manager\SocialiteWasCalled;
7
use SocialiteProviders\Manager\ConfigTrait;
8
use SocialiteProviders\Manager\Contracts\ConfigInterface as Config;
9
use Symfony\Component\HttpFoundation\RedirectResponse;
10
11
abstract class AbstractProvider extends BaseProvider
12
{
13
    use ConfigTrait;
14
15
    /**
16
     * Indicates if the session state should be utilized.
17
     *
18
     * @var bool
19
     */
20
    protected $stateless = true;
21
22
    /**
23
     * @var array
24
     */
25
    protected $credentialsResponseBody;
26
27
    public static function serviceContainerKey($providerName)
28
    {
29
        return SocialiteWasCalled::SERVICE_CONTAINER_PREFIX.$providerName;
30
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function user()
36
    {
37
        if (!$this->hasNecessaryVerifier()) {
38
            throw new \InvalidArgumentException('Invalid request. Missing OAuth verifier.');
39
        }
40
41
        $token = $this->getToken();
42
        $tokenCredentials = $token['tokenCredentials'];
43
44
        $user = $this->mapUserToObject((array) $this->server->getUserDetails($tokenCredentials));
0 ignored issues
show
Bug introduced by
The method mapUserToObject() does not seem to exist on object<SocialiteProvider...Auth1\AbstractProvider>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
45
46
        $user->setToken($tokenCredentials->getIdentifier(), $tokenCredentials->getSecret());
47
48
        if ($user instanceof User) {
49
            parse_str($token['credentialsResponseBody'], $credentialsResponseBody);
50
51
            if (!$credentialsResponseBody || !is_array($credentialsResponseBody)) {
52
                throw new CredentialsException('Unable to parse token credentials response.');
53
            }
54
55
            $user->setAccessTokenResponseBody($credentialsResponseBody);
56
        }
57
58
        return $user;
59
    }
60
    
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function userFromTokenAndSecret($token, $secret)
65
    {
66
        $tokenCredentials = new TokenCredentials();
67
68
        $tokenCredentials->setIdentifier($token);
69
        $tokenCredentials->setSecret($secret);
70
71
        $user = $this->mapUserToObject((array)$this->server->getUserDetails($tokenCredentials));
0 ignored issues
show
Bug introduced by
The method mapUserToObject() does not seem to exist on object<SocialiteProvider...Auth1\AbstractProvider>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
72
73
        $user->setToken($tokenCredentials->getIdentifier(), $tokenCredentials->getSecret());
74
75
        return $user;
76
    }
77
78
    /**
79
     * Redirect the user to the authentication page for the provider.
80
     *
81
     * @return RedirectResponse
82
     */
83
    public function redirect()
84
    {
85
        if (!$this->isStateless()) {
86
            $this->request->getSession()->put(
0 ignored issues
show
Bug introduced by
The method put() does not seem to exist on object<Symfony\Component...ssion\SessionInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87
                'oauth.temp', $temp = $this->server->getTemporaryCredentials()
88
            );
89
        } else {
90
            $temp = $this->server->getTemporaryCredentials();
91
            $this->request->session()->put('oauth_temp', serialize($temp));
0 ignored issues
show
Bug introduced by
The method put() does not seem to exist on object<Symfony\Component...ssion\SessionInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
92
        }
93
94
        return new RedirectResponse($this->server->getAuthorizationUrl($temp));
95
    }
96
97
    /**
98
     * Get the token credentials for the request.
99
     *
100
     * @return \League\OAuth1\Client\Credentials\TokenCredentials
101
     */
102
    protected function getToken()
103
    {
104
        if (!$this->isStateless()) {
105
            $temp = $this->request->getSession()->get('oauth.temp');
106
107
            return $this->server->getTokenCredentials(
108
                $temp, $this->request->get('oauth_token'), $this->request->get('oauth_verifier')
109
            );
110
        } else {
111
            $temp = unserialize($this->request->session()->get('oauth_temp'));
112
113
            return $this->server->getTokenCredentials(
114
                $temp, $this->request->get('oauth_token'), $this->request->get('oauth_verifier')
115
            );
116
        }
117
    }
118
119
    /**
120
     * Indicates that the provider should operate as stateless.
121
     *
122
     * @return $this
123
     */
124
    public function stateless($stateless = true)
125
    {
126
        $this->stateless = $stateless;
127
128
        return $this;
129
    }
130
131
    /**
132
     * Determine if the provider is operating as stateless.
133
     *
134
     * @return bool
135
     */
136
    protected function isStateless()
137
    {
138
        if (defined('SOCIALITEPROVIDERS_STATELESS')) {
139
            return true;
140
        }
141
142
        return $this->stateless;
143
    }
144
145
    /**
146
     * Set the scopes of the requested access.
147
     *
148
     * @param array $scopes
149
     *
150
     * @return $this
151
     */
152
    public function scopes(array $scopes)
153
    {
154
        $this->server = $this->server->scopes($scopes);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class League\OAuth1\Client\Server\Server as the method scopes() does only exist in the following sub-classes of League\OAuth1\Client\Server\Server: SocialiteProviders\Manager\OAuth1\Server. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
155
156
        return $this;
157
    }
158
159
    /**
160
     * Set the custom parameters of the request.
161
     *
162
     * @param array $parameters
163
     *
164
     * @return $this
165
     */
166
    public function with(array $parameters)
167
    {
168
        $this->server = $this->server->with($parameters);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class League\OAuth1\Client\Server\Server as the method with() does only exist in the following sub-classes of League\OAuth1\Client\Server\Server: SocialiteProviders\Manager\OAuth1\Server. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
169
170
        return $this;
171
    }
172
173
    /**
174
     * @param Config $config
175
     *
176
     * @return $this
177
     */
178
    public function setConfig(Config $config)
179
    {
180
        $this->config = $this->server->setConfig($config);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class League\OAuth1\Client\Server\Server as the method setConfig() does only exist in the following sub-classes of League\OAuth1\Client\Server\Server: SocialiteProviders\Manager\OAuth1\Server. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
181
182
        return $this;
183
    }
184
}
185