1// Copyright 2017 Google LLC.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package option contains options for Google API clients.
6package option
7
8import (
9	"net/http"
10
11	"golang.org/x/oauth2"
12	"google.golang.org/api/internal"
13	"google.golang.org/grpc"
14)
15
16// A ClientOption is an option for a Google API client.
17type ClientOption interface {
18	Apply(*internal.DialSettings)
19}
20
21// WithTokenSource returns a ClientOption that specifies an OAuth2 token
22// source to be used as the basis for authentication.
23func WithTokenSource(s oauth2.TokenSource) ClientOption {
24	return withTokenSource{s}
25}
26
27type withTokenSource struct{ ts oauth2.TokenSource }
28
29func (w withTokenSource) Apply(o *internal.DialSettings) {
30	o.TokenSource = w.ts
31}
32
33type withCredFile string
34
35func (w withCredFile) Apply(o *internal.DialSettings) {
36	o.CredentialsFile = string(w)
37}
38
39// WithCredentialsFile returns a ClientOption that authenticates
40// API calls with the given service account or refresh token JSON
41// credentials file.
42func WithCredentialsFile(filename string) ClientOption {
43	return withCredFile(filename)
44}
45
46// WithServiceAccountFile returns a ClientOption that uses a Google service
47// account credentials file to authenticate.
48//
49// Deprecated: Use WithCredentialsFile instead.
50func WithServiceAccountFile(filename string) ClientOption {
51	return WithCredentialsFile(filename)
52}
53
54// WithCredentialsJSON returns a ClientOption that authenticates
55// API calls with the given service account or refresh token JSON
56// credentials.
57func WithCredentialsJSON(p []byte) ClientOption {
58	return withCredentialsJSON(p)
59}
60
61type withCredentialsJSON []byte
62
63func (w withCredentialsJSON) Apply(o *internal.DialSettings) {
64	o.CredentialsJSON = make([]byte, len(w))
65	copy(o.CredentialsJSON, w)
66}
67
68// WithEndpoint returns a ClientOption that overrides the default endpoint
69// to be used for a service.
70func WithEndpoint(url string) ClientOption {
71	return withEndpoint(url)
72}
73
74type withEndpoint string
75
76func (w withEndpoint) Apply(o *internal.DialSettings) {
77	o.Endpoint = string(w)
78}
79
80// WithScopes returns a ClientOption that overrides the default OAuth2 scopes
81// to be used for a service.
82func WithScopes(scope ...string) ClientOption {
83	return withScopes(scope)
84}
85
86type withScopes []string
87
88func (w withScopes) Apply(o *internal.DialSettings) {
89	o.Scopes = make([]string, len(w))
90	copy(o.Scopes, w)
91}
92
93// WithUserAgent returns a ClientOption that sets the User-Agent.
94func WithUserAgent(ua string) ClientOption {
95	return withUA(ua)
96}
97
98type withUA string
99
100func (w withUA) Apply(o *internal.DialSettings) { o.UserAgent = string(w) }
101
102// WithHTTPClient returns a ClientOption that specifies the HTTP client to use
103// as the basis of communications. This option may only be used with services
104// that support HTTP as their communication transport. When used, the
105// WithHTTPClient option takes precedent over all other supplied options.
106func WithHTTPClient(client *http.Client) ClientOption {
107	return withHTTPClient{client}
108}
109
110type withHTTPClient struct{ client *http.Client }
111
112func (w withHTTPClient) Apply(o *internal.DialSettings) {
113	o.HTTPClient = w.client
114}
115
116// WithGRPCConn returns a ClientOption that specifies the gRPC client
117// connection to use as the basis of communications. This option many only be
118// used with services that support gRPC as their communication transport. When
119// used, the WithGRPCConn option takes precedent over all other supplied
120// options.
121func WithGRPCConn(conn *grpc.ClientConn) ClientOption {
122	return withGRPCConn{conn}
123}
124
125type withGRPCConn struct{ conn *grpc.ClientConn }
126
127func (w withGRPCConn) Apply(o *internal.DialSettings) {
128	o.GRPCConn = w.conn
129}
130
131// WithGRPCDialOption returns a ClientOption that appends a new grpc.DialOption
132// to an underlying gRPC dial. It does not work with WithGRPCConn.
133func WithGRPCDialOption(opt grpc.DialOption) ClientOption {
134	return withGRPCDialOption{opt}
135}
136
137type withGRPCDialOption struct{ opt grpc.DialOption }
138
139func (w withGRPCDialOption) Apply(o *internal.DialSettings) {
140	o.GRPCDialOpts = append(o.GRPCDialOpts, w.opt)
141}
142
143// WithGRPCConnectionPool returns a ClientOption that creates a pool of gRPC
144// connections that requests will be balanced between.
145// This is an EXPERIMENTAL API and may be changed or removed in the future.
146func WithGRPCConnectionPool(size int) ClientOption {
147	return withGRPCConnectionPool(size)
148}
149
150type withGRPCConnectionPool int
151
152func (w withGRPCConnectionPool) Apply(o *internal.DialSettings) {
153	balancer := grpc.RoundRobin(internal.NewPoolResolver(int(w), o))
154	o.GRPCDialOpts = append(o.GRPCDialOpts, grpc.WithBalancer(balancer))
155}
156
157// WithAPIKey returns a ClientOption that specifies an API key to be used
158// as the basis for authentication.
159//
160// API Keys can only be used for JSON-over-HTTP APIs, including those under
161// the import path google.golang.org/api/....
162func WithAPIKey(apiKey string) ClientOption {
163	return withAPIKey(apiKey)
164}
165
166type withAPIKey string
167
168func (w withAPIKey) Apply(o *internal.DialSettings) { o.APIKey = string(w) }
169
170// WithAudiences returns a ClientOption that specifies an audience to be used
171// as the audience field ("aud") for the JWT token authentication.
172func WithAudiences(audience ...string) ClientOption {
173	return withAudiences(audience)
174}
175
176type withAudiences []string
177
178func (w withAudiences) Apply(o *internal.DialSettings) {
179	o.Audiences = make([]string, len(w))
180	copy(o.Audiences, w)
181}
182
183// WithoutAuthentication returns a ClientOption that specifies that no
184// authentication should be used. It is suitable only for testing and for
185// accessing public resources, like public Google Cloud Storage buckets.
186// It is an error to provide both WithoutAuthentication and any of WithAPIKey,
187// WithTokenSource, WithCredentialsFile or WithServiceAccountFile.
188func WithoutAuthentication() ClientOption {
189	return withoutAuthentication{}
190}
191
192type withoutAuthentication struct{}
193
194func (w withoutAuthentication) Apply(o *internal.DialSettings) { o.NoAuth = true }
195
196// WithQuotaProject returns a ClientOption that specifies the project used
197// for quota and billing purposes.
198//
199// For more information please read:
200// https://cloud.google.com/apis/docs/system-parameters
201func WithQuotaProject(quotaProject string) ClientOption {
202	return withQuotaProject(quotaProject)
203}
204
205type withQuotaProject string
206
207func (w withQuotaProject) Apply(o *internal.DialSettings) {
208	o.QuotaProject = string(w)
209}
210
211// WithRequestReason returns a ClientOption that specifies a reason for
212// making the request, which is intended to be recorded in audit logging.
213// An example reason would be a support-case ticket number.
214//
215// For more information please read:
216// https://cloud.google.com/apis/docs/system-parameters
217func WithRequestReason(requestReason string) ClientOption {
218	return withRequestReason(requestReason)
219}
220
221type withRequestReason string
222
223func (w withRequestReason) Apply(o *internal.DialSettings) {
224	o.RequestReason = string(w)
225}
226
227// WithTelemetryDisabled returns a ClientOption that disables default telemetry (OpenCensus)
228// settings on gRPC and HTTP clients.
229// An example reason would be to bind custom telemetry that overrides the defaults.
230func WithTelemetryDisabled() ClientOption {
231	return withTelemetryDisabledOption{}
232}
233
234type withTelemetryDisabledOption struct{}
235
236func (w withTelemetryDisabledOption) Apply(o *internal.DialSettings) {
237	o.TelemetryDisabled = true
238}
239