Skip to content

Commit

Permalink
oauth2: support for Google Service Accounts
Browse files Browse the repository at this point in the history
Fixes #879.

Allows using Google Service Accounts.
However, it is a little awkward to use them because
we still need an init/mount point on disk.
WIP that I'll get to perhaps when the school break
is on.
  • Loading branch information
odeke-em committed Feb 12, 2017
1 parent 7d3d7fa commit 8eb5d20
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ drive init ~/gdrive
cd ~/gdrive
```
If you have Google Service Account credentials, make sure the path to that file is set by
environment variable `GOOGLE_APPLICATION_CREDENTIALS`, and make sure that your project has Google Drive
enabled in order to use it. For more information, you can read
+ https://developers.google.com/accounts/docs/application-default-credentials
+ https://github.com/odeke-em/drive/issues/879
### De Initializing
The opposite of `drive init`, it will remove your credentials locally as well as configuration associated files.
Expand Down
14 changes: 11 additions & 3 deletions src/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package drive

import (
"errors"
"fmt"
"io"
"os"
"path"
Expand Down Expand Up @@ -193,9 +194,16 @@ func (opts *Options) rcPath() (string, error) {
}

func New(context *config.Context, opts *Options) *Commands {
var r *Remote
var rem *Remote
var err error
if context != nil {
r = NewRemoteContext(context)
rem, err = NewRemoteContext(context)
} else {
rem, err = NewRemoteContextFromServiceAccount()
}

if err != nil {
panic(fmt.Errorf("failed to initialize remoteContext: %v", err))
}

stdin, stdout, stderr := os.Stdin, os.Stdout, os.Stderr
Expand Down Expand Up @@ -236,7 +244,7 @@ func New(context *config.Context, opts *Options) *Commands {

return &Commands{
context: context,
rem: r,
rem: rem,
opts: opts,
log: logger,
mkdirAllCache: expirableCache.New(),
Expand Down
29 changes: 26 additions & 3 deletions src/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,38 @@ type Remote struct {
progressChan chan int
}

func NewRemoteContext(context *config.Context) *Remote {
// NewRemoteContextFromServiceAccount returns a remote initialized
// with credentials from a Google Service Account.
// For more information about these accounts, see:
// https://developers.google.com/identity/protocols/OAuth2ServiceAccount
// https://developers.google.com/accounts/docs/application-default-credentials
// You'll also need to set in your environment, key `GOOGLE_APPLICATION_CREDENTIALS`.
func NewRemoteContextFromServiceAccount() (*Remote, error) {
client, err := google.DefaultClient(context.TODO(), DriveScope)
if err != nil {
return nil, err
}
return remoteFromClient(client)
}

func NewRemoteContext(context *config.Context) (*Remote, error) {
client := newOAuthClient(context)
service, _ := drive.New(client)
return remoteFromClient(client)
}

func remoteFromClient(client *http.Client) (*Remote, error) {
service, err := drive.New(client)
if err != nil {
return nil, err
}

progressChan := make(chan int)
return &Remote{
rem := &Remote{
progressChan: progressChan,
service: service,
client: client,
}
return rem, nil
}

func hasExportLinks(f *File) bool {
Expand Down

0 comments on commit 8eb5d20

Please sign in to comment.