Completed
Pull Request — master (#157)
by
unknown
08:36
created

AbstractProvider::getTemporaryCredentials()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace SocialiteProviders\Manager\OAuth1;
4
5
use Illuminate\Http\RedirectResponse;
6
use Laravel\Socialite\One\AbstractProvider as BaseProvider;
7
use League\OAuth1\Client\Credentials\TokenCredentials;
8
use SocialiteProviders\Manager\ConfigTrait;
9
use SocialiteProviders\Manager\Contracts\ConfigInterface as Config;
10
use SocialiteProviders\Manager\Contracts\OAuth1\ProviderInterface;
11
use SocialiteProviders\Manager\SocialiteWasCalled;
12
13
abstract class AbstractProvider extends BaseProvider implements ProviderInterface
14
{
15
    use ConfigTrait;
16
17
    /**
18
     * Indicates if the session state should be utilized.
19
     *
20
     * @var bool
21
     */
22
    protected $stateless = true;
23
24
    /**
25
     * @var array
26
     */
27
    protected $credentialsResponseBody;
28
29
    /**
30
     * @param string $providerName
31
     *
32
     * @return string
33
     */
34
    public static function serviceContainerKey($providerName)
35
    {
36
        return SocialiteWasCalled::SERVICE_CONTAINER_PREFIX.$providerName;
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function user()
43
    {
44
        if (!$this->hasNecessaryVerifier()) {
45
            throw new \InvalidArgumentException('Invalid request. Missing OAuth verifier.');
46
        }
47
48
        $token = $this->getToken();
49
        $tokenCredentials = $token['tokenCredentials'];
50
51
        $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...
52
53
        $user->setToken($tokenCredentials->getIdentifier(), $tokenCredentials->getSecret());
54
55
        if ($user instanceof User) {
56
            parse_str($token['credentialsResponseBody'], $credentialsResponseBody);
57
58
            if (!$credentialsResponseBody || !is_array($credentialsResponseBody)) {
59
                throw new CredentialsException('Unable to parse token credentials response.');
60
            }
61
62
            $user->setAccessTokenResponseBody($credentialsResponseBody);
63
        }
64
65
        return $user;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function userFromTokenAndSecret($token, $secret)
72
    {
73
        $tokenCredentials = new TokenCredentials();
74
75
        $tokenCredentials->setIdentifier($token);
76
        $tokenCredentials->setSecret($secret);
77
78
        $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...
79
80
        $user->setToken($tokenCredentials->getIdentifier(), $tokenCredentials->getSecret());
81
82
        return $user;
83
    }
84
85
    /**
86
     * Redirect the user to the authentication page for the provider.
87
     *
88
     * @return RedirectResponse
89
     */
90
    public function redirect()
91
    {
92
        if (!$this->isStateless()) {
93
            $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...
94
                'oauth.temp', $temp = $this->server->getTemporaryCredentials()
95
            );
96
        } else {
97
            $temp = $this->server->getTemporaryCredentials();
98
            $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...
99
        }
100
101
        return new RedirectResponse($this->server->getAuthorizationUrl($temp));
102
    }
103
104
    /**
105
     * Returns temporary credentials for stateless auth.
106
     *
107
     * @return array
108
     */
109
    public function getTemporaryCredentials()
110
    {
111
        $temp = $this->server->getTemporaryCredentials();
112
113
        return [
114
            'identifier' => $temp->getIdentifier(),
115
            'secret' => $temp->getSecret(),
116
        ];
117
    }
118
119
    /**
120
     * Indicates that the provider should operate as stateless.
121
     *
122
     * @param mixed $stateless
123
     *
124
     * @return $this
125
     */
126
    public function stateless($stateless = true)
127
    {
128
        $this->stateless = $stateless;
129
130
        return $this;
131
    }
132
133
    /**
134
     * Set the scopes of the requested access.
135
     *
136
     * @param array $scopes
137
     *
138
     * @return $this
139
     */
140
    public function scopes(array $scopes)
141
    {
142
        $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...
143
144
        return $this;
145
    }
146
147
    /**
148
     * Set the custom parameters of the request.
149
     *
150
     * @param array $parameters
151
     *
152
     * @return $this
153
     */
154
    public function with(array $parameters)
155
    {
156
        $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...
157
158
        return $this;
159
    }
160
161
    /**
162
     * @param Config $config
163
     *
164
     * @return $this
165
     */
166
    public function setConfig(Config $config)
167
    {
168
        $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...
169
170
        return $this;
171
    }
172
173
    /**
174
     * Get the token credentials for the request.
175
     *
176
     * @return \League\OAuth1\Client\Credentials\TokenCredentials
177
     */
178
    protected function getToken()
179
    {
180
        if (!$this->isStateless()) {
181
            $temp = $this->request->getSession()->get('oauth.temp');
182
183
            return $this->server->getTokenCredentials(
184
                $temp, $this->request->get('oauth_token'), $this->request->get('oauth_verifier')
185
            );
186
        }
187
        $temp = unserialize($this->request->session()->get('oauth_temp'));
188
189
        return $this->server->getTokenCredentials(
190
                $temp, $this->request->get('oauth_token'), $this->request->get('oauth_verifier')
191
            );
192
    }
193
194
    /**
195
     * Determine if the provider is operating as stateless.
196
     *
197
     * @return bool
198
     */
199
    protected function isStateless()
200
    {
201
        if (defined('SOCIALITEPROVIDERS_STATELESS')) {
202
            return true;
203
        }
204
205
        return $this->stateless;
206
    }
207
}
208