| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package auth | |
| 6 | |
| 7 import ( | |
| 8 "flag" | |
| 9 "fmt" | |
| 10 "net/http" | |
| 11 "os" | |
| 12 | |
| 13 "github.com/maruel/subcommands" | |
| 14 ) | |
| 15 | |
| 16 // Flags defines command line flags related to authentication. | |
| 17 type Flags struct { | |
| 18 defaults Options | |
| 19 serviceAccountJSON string | |
| 20 } | |
| 21 | |
| 22 // Register adds auth related flags to a FlagSet. | |
| 23 func (fl *Flags) Register(f *flag.FlagSet) { | |
| 24 f.StringVar(&fl.serviceAccountJSON, "service-account-json", "", "Path to
JSON file with service account credentials to use.") | |
| 25 } | |
| 26 | |
| 27 // Options return instance of Options struct with values set accordingly to | |
| 28 // parsed command line flags. | |
| 29 func (fl *Flags) Options() (Options, error) { | |
| 30 opts := fl.defaults | |
| 31 if fl.serviceAccountJSON != "" { | |
| 32 opts.Method = ServiceAccountMethod | |
| 33 opts.ServiceAccountJSONPath = fl.serviceAccountJSON | |
| 34 } | |
| 35 return opts, nil | |
| 36 } | |
| 37 | |
| 38 // SubcommandLogin returns subcommands.Command that can be used to perform | |
| 39 // interactive login. | |
| 40 func SubcommandLogin(opts Options, name string) *subcommands.Command { | |
| 41 return &subcommands.Command{ | |
| 42 UsageLine: name, | |
| 43 ShortDesc: "performs interactive login flow", | |
| 44 LongDesc: "Performs interactive login flow and caches obtained
credentials", | |
| 45 CommandRun: func() subcommands.CommandRun { | |
| 46 c := &loginRun{} | |
| 47 c.flags.defaults = opts | |
| 48 c.flags.Register(&c.Flags) | |
| 49 return c | |
| 50 }, | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 type loginRun struct { | |
| 55 subcommands.CommandRunBase | |
| 56 flags Flags | |
| 57 } | |
| 58 | |
| 59 func (c *loginRun) Run(subcommands.Application, []string) int { | |
| 60 opts, err := c.flags.Options() | |
| 61 if err != nil { | |
| 62 fmt.Fprintf(os.Stderr, "%s\n", err.Error()) | |
| 63 return 1 | |
| 64 } | |
| 65 client, err := AuthenticatedClient(InteractiveLogin, NewAuthenticator(op
ts)) | |
| 66 if err != nil { | |
| 67 fmt.Fprintf(os.Stderr, "Login failed: %s\n", err.Error()) | |
| 68 return 2 | |
| 69 } | |
| 70 err = reportIdentity(client) | |
| 71 if err != nil { | |
| 72 return 3 | |
| 73 } | |
| 74 return 0 | |
| 75 } | |
| 76 | |
| 77 // SubcommandLogout returns subcommands.Command that can be used to purge cached | |
| 78 // credentials. | |
| 79 func SubcommandLogout(opts Options, name string) *subcommands.Command { | |
| 80 return &subcommands.Command{ | |
| 81 UsageLine: name, | |
| 82 ShortDesc: "removes cached credentials", | |
| 83 LongDesc: "Removes cached credentials from the disk", | |
| 84 CommandRun: func() subcommands.CommandRun { | |
| 85 c := &logoutRun{} | |
| 86 c.flags.defaults = opts | |
| 87 c.flags.Register(&c.Flags) | |
| 88 return c | |
| 89 }, | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 type logoutRun struct { | |
| 94 subcommands.CommandRunBase | |
| 95 flags Flags | |
| 96 } | |
| 97 | |
| 98 func (c *logoutRun) Run(a subcommands.Application, args []string) int { | |
| 99 opts, err := c.flags.Options() | |
| 100 if err != nil { | |
| 101 fmt.Fprintf(os.Stderr, "%s\n", err.Error()) | |
| 102 return 1 | |
| 103 } | |
| 104 err = NewAuthenticator(opts).PurgeCredentialsCache() | |
| 105 if err != nil { | |
| 106 fmt.Fprintln(os.Stderr, err) | |
| 107 return 2 | |
| 108 } | |
| 109 return 0 | |
| 110 } | |
| 111 | |
| 112 // SubcommandInfo returns subcommand.Command that can be used to print current | |
| 113 // cached credentials. | |
| 114 func SubcommandInfo(opts Options, name string) *subcommands.Command { | |
| 115 return &subcommands.Command{ | |
| 116 UsageLine: name, | |
| 117 ShortDesc: "prints an email address associated with currently ca
ched token", | |
| 118 LongDesc: "Prints an email address associated with currently ca
ched token", | |
| 119 CommandRun: func() subcommands.CommandRun { | |
| 120 c := &infoRun{} | |
| 121 c.flags.defaults = opts | |
| 122 c.flags.Register(&c.Flags) | |
| 123 return c | |
| 124 }, | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 type infoRun struct { | |
| 129 subcommands.CommandRunBase | |
| 130 flags Flags | |
| 131 } | |
| 132 | |
| 133 func (c *infoRun) Run(a subcommands.Application, args []string) int { | |
| 134 opts, err := c.flags.Options() | |
| 135 if err != nil { | |
| 136 fmt.Fprintf(os.Stderr, "%s\n", err.Error()) | |
| 137 return 1 | |
| 138 } | |
| 139 client, err := AuthenticatedClient(SilentLogin, NewAuthenticator(opts)) | |
| 140 if err == ErrLoginRequired { | |
| 141 fmt.Fprintln(os.Stderr, "Not logged in") | |
| 142 return 2 | |
| 143 } else if err != nil { | |
| 144 fmt.Fprintln(os.Stderr, err) | |
| 145 return 3 | |
| 146 } | |
| 147 err = reportIdentity(client) | |
| 148 if err != nil { | |
| 149 return 4 | |
| 150 } | |
| 151 return 0 | |
| 152 } | |
| 153 | |
| 154 // reportIdentity prints identity associated with credentials that the client | |
| 155 // puts into each request (if any). | |
| 156 func reportIdentity(c *http.Client) error { | |
| 157 service := NewGroupsService("", c, nil) | |
| 158 ident, err := service.FetchCallerIdentity() | |
| 159 if err != nil { | |
| 160 fmt.Fprintf(os.Stderr, "Failed to fetch current identity: %s\n",
err) | |
| 161 return err | |
| 162 } | |
| 163 fmt.Printf("Logged in to %s as %s\n", service.ServiceURL(), ident) | |
| 164 return nil | |
| 165 } | |
| OLD | NEW |