1<?php
2/*
3 * Copyright 2010 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18namespace Google\Auth\tests;
19
20use Google\Auth\Credentials\AppIdentityCredentials;
21use Google\Auth\Credentials\GCECredentials;
22use Google\Auth\Credentials\ServiceAccountCredentials;
23use Google\Auth\Credentials\ServiceAccountJwtAccessCredentials;
24use Google\Auth\Credentials\UserRefreshCredentials;
25use Google\Auth\CredentialsLoader;
26use Google\Auth\FetchAuthTokenInterface;
27use Google\Auth\OAuth2;
28
29class FetchAuthTokenTest extends BaseTest
30{
31    private $scopes = ['https://www.googleapis.com/auth/drive.readonly'];
32
33    /** @dataProvider provideMakeHttpClient */
34    public function testMakeHttpClient($fetcherClass)
35    {
36        $mockFetcher = $this->getMockBuilder($fetcherClass)
37            ->disableOriginalConstructor()
38            ->getMock();
39
40        $mockFetcher
41            ->expects($this->once())
42            ->method('fetchAuthToken')
43            ->will($this->returnCallback(function ($httpHandler) {
44                return $httpHandler();
45            }));
46
47        $httpHandlerCalled = false;
48        $httpHandler = function () use (&$httpHandlerCalled) {
49            $httpHandlerCalled = true;
50            return ['access_token' => 'xyz'];
51        };
52
53        $tokenCallbackCalled = false;
54        $tokenCallback = function ($cacheKey, $accessToken) use (&$tokenCallbackCalled) {
55            $tokenCallbackCalled = true;
56            $this->assertEquals('xyz', $accessToken);
57        };
58
59        $client = CredentialsLoader::makeHttpClient(
60            $mockFetcher,
61            [
62                'base_url' => 'https://www.googleapis.com/books/v1/',
63                'base_uri' => 'https://www.googleapis.com/books/v1/',
64                'exceptions' => false,
65                'defaults' => ['exceptions' => false]
66            ],
67            $httpHandler,
68            $tokenCallback
69        );
70
71        $response = $client->get(
72            'volumes?q=Henry+David+Thoreau&country=US'
73        );
74
75        $this->assertEquals(401, $response->getStatusCode());
76        $this->assertTrue($httpHandlerCalled);
77        $this->assertTrue($tokenCallbackCalled);
78    }
79
80    public function provideMakeHttpClient()
81    {
82        return [
83            ['Google\Auth\Credentials\AppIdentityCredentials'],
84            ['Google\Auth\Credentials\GCECredentials'],
85            ['Google\Auth\Credentials\ServiceAccountCredentials'],
86            ['Google\Auth\Credentials\ServiceAccountJwtAccessCredentials'],
87            ['Google\Auth\Credentials\UserRefreshCredentials'],
88            ['Google\Auth\OAuth2'],
89        ];
90    }
91
92    public function testAppIdentityCredentialsGetLastReceivedToken()
93    {
94        $class = new \ReflectionClass(
95            'Google\Auth\Credentials\AppIdentityCredentials'
96        );
97        $property = $class->getProperty('lastReceivedToken');
98        $property->setAccessible(true);
99
100        $credentials = new AppIdentityCredentials();
101        $property->setValue($credentials, [
102            'access_token' => 'xyz',
103            'expiration_time' => strtotime('2001'),
104        ]);
105
106        $this->assertGetLastReceivedToken($credentials);
107    }
108
109    public function testGCECredentialsGetLastReceivedToken()
110    {
111        $class = new \ReflectionClass(
112            'Google\Auth\Credentials\GCECredentials'
113        );
114        $property = $class->getProperty('lastReceivedToken');
115        $property->setAccessible(true);
116
117        $credentials = new GCECredentials();
118        $property->setValue($credentials, [
119            'access_token' => 'xyz',
120            'expires_at' => strtotime('2001'),
121        ]);
122
123        $this->assertGetLastReceivedToken($credentials);
124    }
125
126    public function testServiceAccountCredentialsGetLastReceivedToken()
127    {
128        $jsonPath = sprintf(
129            '%s/fixtures/.config/%s',
130            __DIR__,
131            CredentialsLoader::WELL_KNOWN_PATH
132        );
133
134        $class = new \ReflectionClass(
135            'Google\Auth\Credentials\ServiceAccountCredentials'
136        );
137        $property = $class->getProperty('auth');
138        $property->setAccessible(true);
139
140        $credentials = new ServiceAccountCredentials($this->scopes, $jsonPath);
141        $property->setValue($credentials, $this->getOAuth2Mock());
142
143        $this->assertGetLastReceivedToken($credentials);
144    }
145
146    public function testServiceAccountJwtAccessCredentialsGetLastReceivedToken()
147    {
148        $jsonPath = sprintf(
149            '%s/fixtures/.config/%s',
150            __DIR__,
151            CredentialsLoader::WELL_KNOWN_PATH
152        );
153
154        $class = new \ReflectionClass(
155            'Google\Auth\Credentials\ServiceAccountJwtAccessCredentials'
156        );
157        $property = $class->getProperty('auth');
158        $property->setAccessible(true);
159
160        $credentials = new ServiceAccountJwtAccessCredentials($jsonPath);
161        $property->setValue($credentials, $this->getOAuth2Mock());
162
163        $this->assertGetLastReceivedToken($credentials);
164    }
165
166    public function testUserRefreshCredentialsGetLastReceivedToken()
167    {
168        $jsonPath = sprintf(
169            '%s/fixtures2/.config/%s',
170            __DIR__,
171            CredentialsLoader::WELL_KNOWN_PATH
172        );
173
174        $class = new \ReflectionClass(
175            'Google\Auth\Credentials\UserRefreshCredentials'
176        );
177        $property = $class->getProperty('auth');
178        $property->setAccessible(true);
179
180        $credentials = new UserRefreshCredentials($this->scopes, $jsonPath);
181        $property->setValue($credentials, $this->getOAuth2Mock());
182
183        $this->assertGetLastReceivedToken($credentials);
184    }
185
186    private function getOAuth2()
187    {
188        $oauth = new OAuth2([
189            'access_token' => 'xyz',
190            'expires_at' => strtotime('2001'),
191        ]);
192
193        $this->assertGetLastReceivedToken($oauth);
194    }
195
196    private function getOAuth2Mock()
197    {
198        $mock = $this->getMockBuilder('Google\Auth\OAuth2')
199            ->disableOriginalConstructor()
200            ->getMock();
201
202        $mock
203            ->expects($this->once())
204            ->method('getLastReceivedToken')
205            ->will($this->returnValue([
206                'access_token' => 'xyz',
207                'expires_at' => strtotime('2001'),
208            ]));
209
210        return $mock;
211    }
212
213    private function assertGetLastReceivedToken(FetchAuthTokenInterface $fetcher)
214    {
215        $accessToken = $fetcher->getLastReceivedToken();
216
217        $this->assertNotNull($accessToken);
218        $this->assertArrayHasKey('access_token', $accessToken);
219        $this->assertArrayHasKey('expires_at', $accessToken);
220
221        $this->assertEquals('xyz', $accessToken['access_token']);
222        $this->assertEquals(strtotime('2001'), $accessToken['expires_at']);
223    }
224}
225