diff --git a/gdrive.go b/gdrive.go index c1a817e7..3e01ac61 100644 --- a/gdrive.go +++ b/gdrive.go @@ -45,6 +45,11 @@ func main() { Patterns: []string{"--service-account"}, Description: "Oauth service account filename, used for server to server communication without user interaction (filename path is relative to config dir)", }, + cli.StringFlag{ + Name: "oauthCredentials", + Patterns: []string{"--oauth-credentials"}, + Description: "Oauth Credentials file as downloaded from https://console.cloud.google.com/apis/credentials", + }, } handlers := []*cli.Handler{ diff --git a/handlers_drive.go b/handlers_drive.go index 7bda872f..c637b712 100644 --- a/handlers_drive.go +++ b/handlers_drive.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "io" "io/ioutil" @@ -17,6 +18,7 @@ import ( const ClientId = "367116221053-7n0vf5akeru7on6o2fjinrecpdoe99eg.apps.googleusercontent.com" const ClientSecret = "1qsNodXNaWq1mQuBjUjmvhoO" const TokenFilename = "token_v2.json" +const OauthCredentialsFilename = "oauthClient.json" const DefaultCacheFileName = "file_cache.json" func listHandler(ctx cli.Context) { @@ -340,21 +342,55 @@ func aboutExportHandler(ctx cli.Context) { checkErr(err) } +func getOauthAppCredentials(credsPath string) (clientId, clientSecret string, err error) { + clientId = ClientId + clientSecret = ClientSecret + if _, err := os.Stat(credsPath); os.IsNotExist(err) { + return "", "", err + } + var oauthCredentials struct { + Installed struct { + ClientId string `json:"client_id"` + ClientSecret string `json:"client_secret"` + } `json:"installed"` + } + content, err := ioutil.ReadFile(credsPath) + if err != nil { + return "", "", err + } + json.Unmarshal(content, &oauthCredentials) + clientId = oauthCredentials.Installed.ClientId + clientSecret = oauthCredentials.Installed.ClientSecret + + return clientId, clientSecret, nil +} + func getOauthClient(args cli.Arguments) (*http.Client, error) { + clientId := ClientId + clientSecret := ClientSecret + configDir := getConfigDir(args) + + credsPath := ConfigFilePath(configDir, OauthCredentialsFilename) + if args.String("oauthCredentials") != "" { + credsPath = args.String("oauthCrendentials") + } + clientId, clientSecret, err := getOauthAppCredentials(credsPath) + if err != nil { + ExitF("Failed to load oauth app credentials:") + } + if args.String("refreshToken") != "" && args.String("accessToken") != "" { ExitF("Access token not needed when refresh token is provided") } if args.String("refreshToken") != "" { - return auth.NewRefreshTokenClient(ClientId, ClientSecret, args.String("refreshToken")), nil + return auth.NewRefreshTokenClient(clientId, clientSecret, args.String("refreshToken")), nil } if args.String("accessToken") != "" { - return auth.NewAccessTokenClient(ClientId, ClientSecret, args.String("accessToken")), nil + return auth.NewAccessTokenClient(clientId, clientSecret, args.String("accessToken")), nil } - configDir := getConfigDir(args) - if args.String("serviceAccount") != "" { serviceAccountPath := ConfigFilePath(configDir, args.String("serviceAccount")) serviceAccountClient, err := auth.NewServiceAccountClient(serviceAccountPath) @@ -365,7 +401,7 @@ func getOauthClient(args cli.Arguments) (*http.Client, error) { } tokenPath := ConfigFilePath(configDir, TokenFilename) - return auth.NewFileSourceClient(ClientId, ClientSecret, tokenPath, authCodePrompt) + return auth.NewFileSourceClient(clientId, clientSecret, tokenPath, authCodePrompt) } func getConfigDir(args cli.Arguments) string {