diff --git a/google/example_test.go b/google/example_test.go index 380bd47..434a373 100644 --- a/google/example_test.go +++ b/google/example_test.go @@ -44,6 +44,34 @@ func Example_webServer() { client.Get("...") } +func Example_serviceAccountsJSON() { + // Your credentials should be obtained from the Google + // Developer Console (https://console.developers.google.com). + // Navigate to your project, then see the "Credentials" page + // under "APIs & Auth". + // To create a service account client, click "Create new Client ID", + // select "Service Account", and click "Create Client ID". A JSON + // key file will then be downloaded to your computer. + config, err := google.NewServiceAccountJSONConfig( + "/path/to/your-project-key.json", + "https://www.googleapis.com/auth/bigquery", + ) + if err != nil { + log.Fatal(err) + } + // Initiate an http.Client. The following GET request will be + // authorized and authenticated on the behalf of + // your service account. + client := http.Client{Transport: config.NewTransport()} + client.Get("...") + + // If you would like to impersonate a user, you can + // create a transport with a subject. The following GET + // request will be made on the behalf of user@example.com. + client = http.Client{Transport: config.NewTransportWithUser("user@example.com")} + client.Get("...") +} + func Example_serviceAccounts() { // Your credentials should be obtained from the Google // Developer Console (https://console.developers.google.com). diff --git a/google/google.go b/google/google.go index e170415..eb55f4a 100644 --- a/google/google.go +++ b/google/google.go @@ -15,6 +15,7 @@ package google import ( "encoding/json" + "io/ioutil" "net/http" "path" "time" @@ -61,6 +62,30 @@ func NewServiceAccountConfig(opts *oauth2.JWTOptions) (*oauth2.JWTConfig, error) return oauth2.NewJWTConfig(opts, uriGoogleToken) } +// NewServiceAccountJSONConfig creates a new JWT config from a +// JSON key file downloaded from the Google Developers Console. +// See the "Credentials" page under "APIs & Auth" for your project +// at https://console.developers.google.com. +func NewServiceAccountJSONConfig(filename string, scopes ...string) (*oauth2.JWTConfig, error) { + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + var key struct { + Email string `json:"client_email"` + PrivateKey string `json:"private_key"` + } + if err := json.Unmarshal(b, &key); err != nil { + return nil, err + } + opts := &oauth2.JWTOptions{ + Email: key.Email, + PrivateKey: []byte(key.PrivateKey), + Scopes: scopes, + } + return NewServiceAccountConfig(opts) +} + // NewComputeEngineConfig creates a new config that can fetch tokens // from Google Compute Engine instance's metaserver. If no account is // provided, default is used.