1<?php
2/*
3 * Copyright 2015 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\Credentials;
19
20use Google\Auth\CredentialsLoader;
21use Google\Auth\GetQuotaProjectInterface;
22use Google\Auth\OAuth2;
23
24/**
25 * Authenticates requests using User Refresh credentials.
26 *
27 * This class allows authorizing requests from user refresh tokens.
28 *
29 * This the end of the result of a 3LO flow.  E.g, the end result of
30 * 'gcloud auth login' saves a file with these contents in well known
31 * location
32 *
33 * @see [Application Default Credentials](http://goo.gl/mkAHpZ)
34 */
35class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjectInterface
36{
37    /**
38     * The OAuth2 instance used to conduct authorization.
39     *
40     * @var OAuth2
41     */
42    protected $auth;
43
44    /**
45     * The quota project associated with the JSON credentials
46     *
47     * @var string
48     */
49    protected $quotaProject;
50
51    /**
52     * Create a new UserRefreshCredentials.
53     *
54     * @param string|string[] $scope the scope of the access request, expressed
55     *   either as an Array or as a space-delimited String.
56     * @param string|array<mixed> $jsonKey JSON credential file path or JSON credentials
57     *   as an associative array
58     */
59    public function __construct(
60        $scope,
61        $jsonKey
62    ) {
63        if (is_string($jsonKey)) {
64            if (!file_exists($jsonKey)) {
65                throw new \InvalidArgumentException('file does not exist');
66            }
67            $json = file_get_contents($jsonKey);
68            if (!$jsonKey = json_decode((string) $json, true)) {
69                throw new \LogicException('invalid json for auth config');
70            }
71        }
72        if (!array_key_exists('client_id', $jsonKey)) {
73            throw new \InvalidArgumentException(
74                'json key is missing the client_id field'
75            );
76        }
77        if (!array_key_exists('client_secret', $jsonKey)) {
78            throw new \InvalidArgumentException(
79                'json key is missing the client_secret field'
80            );
81        }
82        if (!array_key_exists('refresh_token', $jsonKey)) {
83            throw new \InvalidArgumentException(
84                'json key is missing the refresh_token field'
85            );
86        }
87        $this->auth = new OAuth2([
88            'clientId' => $jsonKey['client_id'],
89            'clientSecret' => $jsonKey['client_secret'],
90            'refresh_token' => $jsonKey['refresh_token'],
91            'scope' => $scope,
92            'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI,
93        ]);
94        if (array_key_exists('quota_project_id', $jsonKey)) {
95            $this->quotaProject = (string) $jsonKey['quota_project_id'];
96        }
97    }
98
99    /**
100     * @param callable $httpHandler
101     *
102     * @return array<mixed> {
103     *     A set of auth related metadata, containing the following
104     *
105     *     @type string $access_token
106     *     @type int $expires_in
107     *     @type string $scope
108     *     @type string $token_type
109     *     @type string $id_token
110     * }
111     */
112    public function fetchAuthToken(callable $httpHandler = null)
113    {
114        return $this->auth->fetchAuthToken($httpHandler);
115    }
116
117    /**
118     * @return string
119     */
120    public function getCacheKey()
121    {
122        return $this->auth->getClientId() . ':' . $this->auth->getCacheKey();
123    }
124
125    /**
126     * @return array<mixed>
127     */
128    public function getLastReceivedToken()
129    {
130        return $this->auth->getLastReceivedToken();
131    }
132
133    /**
134     * Get the quota project used for this API request
135     *
136     * @return string|null
137     */
138    public function getQuotaProject()
139    {
140        return $this->quotaProject;
141    }
142}
143