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\Middleware;
19
20use GuzzleHttp\Psr7\Query;
21use Psr\Http\Message\RequestInterface;
22
23/**
24 * SimpleMiddleware is a Guzzle Middleware that implements Google's Simple API
25 * access.
26 *
27 * Requests are accessed using the Simple API access developer key.
28 */
29class SimpleMiddleware
30{
31    /**
32     * @var array<mixed>
33     */
34    private $config;
35
36    /**
37     * Create a new Simple plugin.
38     *
39     * The configuration array expects one option
40     * - key: required, otherwise InvalidArgumentException is thrown
41     *
42     * @param array<mixed> $config Configuration array
43     */
44    public function __construct(array $config)
45    {
46        if (!isset($config['key'])) {
47            throw new \InvalidArgumentException('requires a key to have been set');
48        }
49
50        $this->config = array_merge(['key' => null], $config);
51    }
52
53    /**
54     * Updates the request query with the developer key if auth is set to simple.
55     *
56     *   use Google\Auth\Middleware\SimpleMiddleware;
57     *   use GuzzleHttp\Client;
58     *   use GuzzleHttp\HandlerStack;
59     *
60     *   $my_key = 'is not the same as yours';
61     *   $middleware = new SimpleMiddleware(['key' => $my_key]);
62     *   $stack = HandlerStack::create();
63     *   $stack->push($middleware);
64     *
65     *   $client = new Client([
66     *       'handler' => $stack,
67     *       'base_uri' => 'https://www.googleapis.com/discovery/v1/',
68     *       'auth' => 'simple'
69     *   ]);
70     *
71     *   $res = $client->get('drive/v2/rest');
72     *
73     * @param callable $handler
74     * @return \Closure
75     */
76    public function __invoke(callable $handler)
77    {
78        return function (RequestInterface $request, array $options) use ($handler) {
79            // Requests using "auth"="scoped" will be authorized.
80            if (!isset($options['auth']) || $options['auth'] !== 'simple') {
81                return $handler($request, $options);
82            }
83
84            $query = Query::parse($request->getUri()->getQuery());
85            $params = array_merge($query, $this->config);
86            $uri = $request->getUri()->withQuery(Query::build($params));
87            $request = $request->withUri($uri);
88
89            return $handler($request, $options);
90        };
91    }
92}
93