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 |