Skip to content

Commit ef25743

Browse files
committed
Fix the OAuth authentication
Signed-off-by: pacoorozco <paco@pacoorozco.info>
1 parent 3226d21 commit ef25743

3 files changed

Lines changed: 53 additions & 17 deletions

File tree

internal/app/oauth.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ func (app *App) AuthenticateFromToken(ctx context.Context) (*http.Client, error)
4040
}
4141

4242
type AuthenticationOptions struct {
43-
// Hostname of the redirect URL.
44-
// You can set this if your provider does not accept localhost.
45-
// Default to localhost.
46-
RedirectURLHostname string
43+
// URL of the redirect URL to use for authentication.
44+
// It has the form of "http://localhost:12345".
45+
RedirectURL string
4746

4847
// Hostname and port which the local server binds to.
4948
// You can set port number to 0 to allocate a free port.
@@ -62,7 +61,7 @@ func (app *App) AuthenticateFromWeb(ctx context.Context, authOptions Authenticat
6261
ClientSecret: app.Config.APIAppCredentials.ClientSecret,
6362
Logf: app.Logger.Debugf,
6463
LocalServerBindAddress: []string{authOptions.LocalServerBindAddress},
65-
RedirectURLHostname: authOptions.RedirectURLHostname,
64+
RedirectURL: authOptions.RedirectURL,
6665
}
6766

6867
token, err := oauth.GetToken(ctx, cfg)

internal/cli/auth/auth.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package auth
33
import (
44
"context"
55
"fmt"
6+
"net/url"
67

78
"github.com/spf13/cobra"
89

@@ -18,6 +19,7 @@ type AuthCmd struct {
1819
Port int
1920
LocalBindAddress string
2021
RedirectURLHostname string
22+
RedirectURL string
2123
}
2224

2325
func NewCommand(globalFlags *flags.GlobalFlags) *cobra.Command {
@@ -33,7 +35,14 @@ func NewCommand(globalFlags *flags.GlobalFlags) *cobra.Command {
3335

3436
authCmd.Flags().IntVar(&cmd.Port, "port", 0, "port on which the auth server will listen (default 0)")
3537
authCmd.Flags().StringVar(&cmd.LocalBindAddress, "local-bind-address", "127.0.0.1", "local address on which the auth server will listen")
36-
authCmd.Flags().StringVar(&cmd.RedirectURLHostname, "redirect-url-hostname", "localhost", "hostname of the redirect URL")
38+
39+
// Declare the version flag and then you can deprecate it.
40+
authCmd.Flags().StringVar(&cmd.RedirectURLHostname, "redirect-url-hostname", "", "hostname of the redirect URL")
41+
err := authCmd.Flags().MarkDeprecated("redirect-url-hostname", "use --redirect-url instead")
42+
if err != nil {
43+
panic(fmt.Sprintf("error marking flag --redirect-url-hostname as deprecated: %v", err))
44+
}
45+
authCmd.Flags().StringVar(&cmd.RedirectURL, "redirect-url", "", "URL of the redirect URL to use for authentication, (e.g. http://localhost:12345)")
3746

3847
return authCmd
3948
}
@@ -48,12 +57,43 @@ func (cmd *AuthCmd) Run(cobraCmd *cobra.Command, args []string) error {
4857
_ = cli.Stop()
4958
}()
5059

60+
// TODO: Remove this check in the v6 release.
61+
// --redirect-url-hostname is deprecated, so we keep it for backward compatibility.
62+
if cmd.RedirectURLHostname != "" && cmd.Port == 0 {
63+
return fmt.Errorf("--port is required when using --redirect-url-hostname")
64+
}
65+
if cmd.RedirectURL != "" && cmd.RedirectURLHostname != "" {
66+
return fmt.Errorf("--redirect-url and --redirect-url-hostname cannot be used together")
67+
}
68+
// End of TODO
69+
70+
// Validate the redirect URL if it is set.
71+
if cmd.RedirectURL != "" {
72+
_, err := url.ParseRequestURI(cmd.RedirectURL)
73+
if err != nil {
74+
return fmt.Errorf("invalid redirect URL '%s'", cmd.RedirectURL)
75+
}
76+
}
77+
78+
// If redirect URL is set, we require the port to be specified as well.
79+
if cmd.RedirectURL != "" && cmd.Port == 0 {
80+
return fmt.Errorf("--port is required when using --redirect-url")
81+
}
82+
5183
// customize authentication options based on the command line parameters
5284
authOptions := app.AuthenticationOptions{}
5385
authOptions.LocalServerBindAddress = fmt.Sprintf("%s:%d", cmd.LocalBindAddress, cmd.Port)
5486

87+
// TODO: Remove this check in the v6 release.
88+
// If redirect URL hostname is set, we use it to construct the redirect URL.
5589
if cmd.RedirectURLHostname != "" {
56-
authOptions.RedirectURLHostname = cmd.RedirectURLHostname
90+
authOptions.RedirectURL = fmt.Sprintf("http://%s:%d", cmd.RedirectURLHostname, cmd.Port)
91+
}
92+
// End of TODO
93+
94+
// If redirect URL is set, we use it to construct the redirect URL.
95+
if cmd.RedirectURL != "" {
96+
authOptions.RedirectURL = cmd.RedirectURL
5797
}
5898

5999
_, err = cli.AuthenticateFromWeb(ctx, authOptions)

internal/oauth/oauth.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,22 @@ var (
4242

4343
// Config represents a config for the OAuth 2.0 flow.
4444
type Config struct {
45-
// OAuth's application ID.
45+
// ClientID is the application's ID.
4646
ClientID string
47-
// OAuth's application secret.
47+
// ClientSecret is the application's secret.
4848
ClientSecret string
4949

5050
// Logger function for debug.
5151
Logf func(format string, args ...interface{})
5252

53-
// Candidates of hostname and port which the local server binds to.
53+
// LocalServerBindAddress is a list of candidates of hostname and port which the local server binds to.
5454
// You can set port number to 0 to allocate a free port.
5555
// If multiple addresses are given, it will try the ports in order.
5656
// If nil or an empty slice is given, it defaults to "127.0.0.1:0" i.e., a free port.
5757
LocalServerBindAddress []string
5858

59-
// Hostname of the redirect URL.
60-
// You can set this if your provider does not accept localhost.
61-
// Default to localhost.
62-
RedirectURLHostname string
59+
// RedirectURL is the URL to redirect users going through the OAuth flow, after the resource owner's URLs.
60+
RedirectURL string
6361

6462
oAuth2Config *oauth2.Config
6563
}
@@ -108,7 +106,7 @@ func (c *Config) validateAndSetDefaults() error {
108106
PhotosLibraryEditAppCreatedDataScope,
109107
},
110108
Endpoint: GoogleAuthEndpoint,
111-
RedirectURL: c.RedirectURLHostname,
109+
RedirectURL: c.RedirectURL,
112110
}
113111

114112
return nil
@@ -123,7 +121,6 @@ func (c *Config) getTokenFromWeb(ctx context.Context) (*oauth2.Token, error) {
123121
LocalServerReadyChan: ready,
124122
Logf: c.Logf,
125123
LocalServerBindAddress: c.LocalServerBindAddress,
126-
RedirectURLHostname: c.RedirectURLHostname,
127124
}
128125

129126
var token *oauth2.Token
@@ -132,7 +129,7 @@ func (c *Config) getTokenFromWeb(ctx context.Context) (*oauth2.Token, error) {
132129
select {
133130
case url := <-ready:
134131
fmt.Printf("\nVisit the URL below in a browser:\n\n%s\n\n", url)
135-
fmt.Printf("If you need to open the URL from another machine, you should use the --local-bind-address and --redirect-url-hostname flags.\n\n")
132+
fmt.Printf("To connect from another machine, use --local-bind-address, --port and --redirect-url.\n\n")
136133
return nil
137134
case <-ctx.Done():
138135
return fmt.Errorf("context done while waiting for authorization: %w", ctx.Err())

0 commit comments

Comments
 (0)