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 }