github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/cmd/camtool/googinit.go (about)

     1  /*
     2  Copyright 2014 The Camlistore Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bufio"
    21  	"encoding/json"
    22  	"flag"
    23  	"fmt"
    24  	"strings"
    25  
    26  	"camlistore.org/pkg/blobserver/google/drive"
    27  	"camlistore.org/pkg/cmdmain"
    28  	"camlistore.org/pkg/googlestorage"
    29  	"camlistore.org/third_party/code.google.com/p/goauth2/oauth"
    30  )
    31  
    32  type googinitCmd struct {
    33  	storageType string
    34  }
    35  
    36  func init() {
    37  	cmdmain.RegisterCommand("googinit", func(flags *flag.FlagSet) cmdmain.CommandRunner {
    38  		cmd := new(googinitCmd)
    39  		flags.StringVar(&cmd.storageType, "type", "drive", "Storage type: drive or cloud")
    40  		return cmd
    41  	})
    42  }
    43  
    44  func (c *googinitCmd) Describe() string {
    45  	return "Init Google Drive or Google Cloud Storage."
    46  }
    47  
    48  func (c *googinitCmd) Usage() {
    49  	fmt.Fprintf(cmdmain.Stderr, "Usage: camtool [globalopts] googinit [commandopts] \n")
    50  }
    51  
    52  func (c *googinitCmd) RunCommand(args []string) error {
    53  	var (
    54  		err          error
    55  		clientId     string
    56  		clientSecret string
    57  		transport    *oauth.Transport
    58  	)
    59  
    60  	if c.storageType != "drive" && c.storageType != "cloud" {
    61  		return cmdmain.UsageError("Invalid storage type.")
    62  	}
    63  
    64  	if clientId, clientSecret, err = getClientInfo(); err != nil {
    65  		return err
    66  	}
    67  
    68  	switch c.storageType {
    69  	case "drive":
    70  		transport = drive.MakeOauthTransport(clientId, clientSecret, "")
    71  	case "cloud":
    72  		transport = googlestorage.MakeOauthTransport(clientId, clientSecret, "")
    73  	}
    74  
    75  	var accessCode string
    76  	if accessCode, err = getAccessCode(transport.Config); err != nil {
    77  		return err
    78  	}
    79  	if _, err = transport.Exchange(accessCode); err != nil {
    80  		return err
    81  	}
    82  
    83  	fmt.Fprintf(cmdmain.Stdout, "\nYour Google auth object:\n\n")
    84  	enc := json.NewEncoder(cmdmain.Stdout)
    85  	authObj := map[string]string{
    86  		"client_id":     transport.ClientId,
    87  		"client_secret": transport.ClientSecret,
    88  		"refresh_token": transport.RefreshToken,
    89  	}
    90  	enc.Encode(authObj)
    91  	fmt.Fprint(cmdmain.Stdout, "\n")
    92  	return nil
    93  }
    94  
    95  // Prompt the user for an input line.  Return the given input.
    96  func prompt(promptText string) (string, error) {
    97  	fmt.Fprint(cmdmain.Stdout, promptText)
    98  	input := bufio.NewReader(cmdmain.Stdin)
    99  	line, _, err := input.ReadLine()
   100  	if err != nil {
   101  		return "", fmt.Errorf("Failed to read line: %v", err)
   102  	}
   103  	return strings.TrimSpace(string(line)), nil
   104  }
   105  
   106  // Provide the authorization link, then prompt for the resulting access code
   107  func getAccessCode(config *oauth.Config) (string, error) {
   108  	fmt.Fprintf(cmdmain.Stdout, "In order to obtain an access code, you will need to navigate to the following URL:\n\n")
   109  	fmt.Fprintf(cmdmain.Stdout, "https://accounts.google.com/o/oauth2/auth?client_id=%s&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=%s&response_type=code\n\n",
   110  		config.ClientId, config.Scope)
   111  	return prompt("Please enter the access code provided by that page:")
   112  }
   113  
   114  // Prompt for client id / secret
   115  func getClientInfo() (string, string, error) {
   116  	fmt.Fprintf(cmdmain.Stdout, "Please provide the client id and client secret \n")
   117  	fmt.Fprintf(cmdmain.Stdout, "(You can find these at http://code.google.com/apis/console > your project > API Access)\n")
   118  	var (
   119  		err          error
   120  		clientId     string
   121  		clientSecret string
   122  	)
   123  	if clientId, err = prompt("Client ID:"); err != nil {
   124  		return "", "", err
   125  	}
   126  	if clientSecret, err = prompt("Client Secret:"); err != nil {
   127  		return "", "", err
   128  	}
   129  	return clientId, clientSecret, nil
   130  }