Skip to content

Commit

Permalink
Support rport token lifetimes with OAuth
Browse files Browse the repository at this point in the history
  • Loading branch information
morestatic committed Oct 4, 2022
1 parent f7bf563 commit d8278f8
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 10 deletions.
18 changes: 13 additions & 5 deletions internal/pkg/api/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ func (rp *Rport) GetToken(ctx context.Context, tokenLifetime int) (li LoginRespo
}

q := req.URL.Query()
// TODO: should we have this for OAuth?
q.Add("token-lifetime", strconv.Itoa(tokenLifetime))
req.URL.RawQuery = q.Encode()

Expand Down Expand Up @@ -84,7 +83,7 @@ func (rp *Rport) GetTokenViaOAuth(ctx context.Context, tokenLifetime int) (token
}
fmt.Print("\nWaiting for OAuth provider response ... ")

token, err = pollLogin(ctx, rp.BaseURL, loginInfo, oauth.MaxOAuthRetries)
token, err = pollLogin(ctx, rp.BaseURL, loginInfo, oauth.MaxOAuthRetries, tokenLifetime)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -120,11 +119,17 @@ func getAuthSettings(
return authSettings, statusCode, nil
}

func pollLogin(ctx context.Context, baseURL string, loginInfo oauth.DeviceLoginInfo, retries int) (toke string, err error) {
func pollLogin(ctx context.Context, baseURL string, loginInfo oauth.DeviceLoginInfo, retries int, tokenLifetime int) (
token string, err error) {
interval := loginInfo.DeviceAuthInfo.Interval

for attempt := 0; attempt < retries; attempt++ {
loginResponse, statusCode, err := oauth.GetDeviceLogin(ctx, baseURL, loginInfo.LoginURI, loginInfo.DeviceAuthInfo.DeviceCode)
loginResponse, statusCode, err := oauth.GetDeviceLogin(
ctx,
baseURL,
loginInfo.LoginURI,
loginInfo.DeviceAuthInfo.DeviceCode,
tokenLifetime)
if err != nil {
return "", fmt.Errorf("unable to login: %d, %w", statusCode, err)
}
Expand All @@ -140,7 +145,10 @@ func pollLogin(ctx context.Context, baseURL string, loginInfo oauth.DeviceLoginI
interval *= 2
} else if !strings.Contains(loginResponse.ErrorCode, "pending") {
// if not pending and not slow down, then we have an error, otherwise fall through to sleep and retry
return "", fmt.Errorf("unable to login:\n%s\n%s\n%s", loginResponse.ErrorCode, loginResponse.ErrorMessage, loginResponse.ErrorURI)
return "", fmt.Errorf("NOT OK\nunable to login: %s\n%s\n%s",
loginResponse.ErrorCode,
loginResponse.ErrorMessage,
loginResponse.ErrorURI)
}
}

Expand Down
6 changes: 4 additions & 2 deletions internal/pkg/api/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,10 @@ func handleLoginFail(t *testing.T, w http.ResponseWriter, attempts int, failErro
if attempts == 0 {
loginResponse := &oauth.DeviceLoginDetailsResponse{
Data: oauth.DeviceLoginDetails{
Token: "",
ErrorCode: failError,
Token: "",
ErrorCode: failError,
ErrorMessage: "this is the error message",
ErrorURI: "https://more-err-info-here.com",
},
}
writeExpectedResponse(t, w, statusCode, loginResponse)
Expand Down
6 changes: 4 additions & 2 deletions internal/pkg/oauth/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"net/url"
"strconv"
)

const (
Expand Down Expand Up @@ -115,15 +116,16 @@ func GetDeviceAuthSettings(

// GetDeviceLogin will atempt to authorize with the rportd server. The login attempt may
// fail if the user hasn't completed authorization. The login can be retried.
func GetDeviceLogin(ctx context.Context, baseURL string, loginURI string, deviceCode string) (
func GetDeviceLogin(ctx context.Context, baseURL string, loginURI string, deviceCode string, tokenLifetime int) (
loginResponse *DeviceLoginDetails, statusCode int, err error) {
loginReq, err := http.NewRequestWithContext(ctx, http.MethodGet, baseURL+loginURI, nil)
if err != nil {
return nil, 0, err
}

params := url.Values{
"device_code": {deviceCode},
"device_code": {deviceCode},
"token-lifetime": {strconv.Itoa(tokenLifetime)},
}
loginReq.URL.RawQuery = params.Encode()

Expand Down
3 changes: 2 additions & 1 deletion internal/pkg/oauth/oauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,15 @@ func TestShouldLogin(t *testing.T) {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/oauth/login/device", r.URL.EscapedPath())
assert.Equal(t, r.URL.Query().Get("device_code"), "123456")
assert.Equal(t, r.URL.Query().Get("token-lifetime"), "900")
writeExpectedResponse(t, w, tc.statusCode, tc.loginResponse)
}))
defer s.Close()

ctx := context.Background()
cl := api.New(s.URL, nil)

loginResponse, statusCode, err := oauth.GetDeviceLogin(ctx, cl.BaseURL, "/oauth/login/device", "123456")
loginResponse, statusCode, err := oauth.GetDeviceLogin(ctx, cl.BaseURL, "/oauth/login/device", "123456", 900)

if statusCode == http.StatusOK {
require.NoError(t, err)
Expand Down

0 comments on commit d8278f8

Please sign in to comment.