Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove default ports + Add RedirectPath #117

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions oauth2cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (
"fmt"
"net/http"

"github.com/int128/oauth2cli/oauth2params"
"golang.org/x/oauth2"

"github.com/int128/oauth2cli/oauth2params"
)

var noopMiddleware = func(h http.Handler) http.Handler { return h }
Expand Down Expand Up @@ -56,6 +57,9 @@ type Config struct {
// You can set this if your provider does not accept localhost.
// Default to localhost.
RedirectURLHostname string
// RedirectURLPath is the path of the redirect URL.
// Default to /.
RedirectURLPath string
// Options for an authorization request.
// You can set oauth2.AccessTypeOffline and the PKCE options here.
AuthCodeOptions []oauth2.AuthCodeOption
Expand Down Expand Up @@ -138,13 +142,12 @@ func (c *Config) validateAndSetDefaults() error {
//
// This performs the following steps:
//
// 1. Start a local server at the port.
// 2. Open a browser and navigate it to the local server.
// 3. Wait for the user authorization.
// 4. Receive a code via an authorization response (HTTP redirect).
// 5. Exchange the code and a token.
// 6. Return the code.
//
// 1. Start a local server at the port.
// 2. Open a browser and navigate it to the local server.
// 3. Wait for the user authorization.
// 4. Receive a code via an authorization response (HTTP redirect).
// 5. Exchange the code and a token.
// 6. Return the code.
func GetToken(ctx context.Context, c Config) (*oauth2.Token, error) {
if err := c.validateAndSetDefaults(); err != nil {
return nil, fmt.Errorf("invalid config: %w", err)
Expand Down
33 changes: 27 additions & 6 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"net"
"net/http"
"path"
"sync"
"time"

Expand Down Expand Up @@ -94,11 +95,26 @@ func receiveCodeViaLocalServer(ctx context.Context, c *Config) (string, error) {
}

func computeRedirectURL(l net.Listener, c *Config) string {
hostPort := fmt.Sprintf("%s:%d", c.RedirectURLHostname, l.Addr().(*net.TCPAddr).Port)
port := l.Addr().(*net.TCPAddr).Port
scheme := "http"
if c.LocalServerCertFile != "" {
return "https://" + hostPort
scheme = "https"
}
return "http://" + hostPort

isDefaultPort := false
if (scheme == "https" && port == 443) || (scheme == "http" && port == 80) {
isDefaultPort = true
}

u := fmt.Sprintf("%s://%s:%d", scheme, c.RedirectURLHostname, port)
if isDefaultPort {
u = fmt.Sprintf("%s://%s", scheme, c.RedirectURLHostname)
}

if c.RedirectURLPath != "" {
u = u + path.Join("/", c.RedirectURLPath)
}
return u
}

type authorizationResponse struct {
Expand All @@ -114,16 +130,21 @@ type localServerHandler struct {

func (h *localServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
redirectPath := "/"
if h.config.RedirectURLPath != "" {
redirectPath = h.config.RedirectURLPath
}

switch {
case r.Method == "GET" && r.URL.Path == "/" && q.Get("error") != "":
case r.Method == "GET" && r.URL.Path == redirectPath && q.Get("error") != "":
h.onceRespCh.Do(func() {
h.respCh <- h.handleErrorResponse(w, r)
})
case r.Method == "GET" && r.URL.Path == "/" && q.Get("code") != "":
case r.Method == "GET" && r.URL.Path == redirectPath && q.Get("code") != "":
h.onceRespCh.Do(func() {
h.respCh <- h.handleCodeResponse(w, r)
})
case r.Method == "GET" && r.URL.Path == "/":
case r.Method == "GET" && r.URL.Path == redirectPath:
h.handleIndex(w, r)
default:
http.NotFound(w, r)
Expand Down