Skip to content
Merged
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
9 changes: 7 additions & 2 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,17 @@ func oauthResource(server string, meta map[string]any) string {
func registerPublicClient(endpoint string, redirectURIs, grantTypes, responseTypes []string) (map[string]any, error) {
body := map[string]any{
"client_name": "life-ustc-cli",
"redirect_uris": redirectURIs,
"application_type": "native",
"token_endpoint_auth_method": "none",
"grant_types": grantTypes,
"response_types": responseTypes,
"scope": oauthScope,
}
if len(redirectURIs) > 0 {
body["redirect_uris"] = redirectURIs
}
if len(responseTypes) > 0 {
body["response_types"] = responseTypes
}
data, _ := json.Marshal(body)
client := &http.Client{Timeout: 15 * time.Second}
resp, err := client.Post(endpoint, "application/json", bytes.NewReader(data))
Expand Down
70 changes: 70 additions & 0 deletions internal/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package auth
import (
"crypto/rand"
"crypto/rsa"
"encoding/json"
"net"
"net/http"
"net/http/httptest"
Expand All @@ -15,6 +16,75 @@ import (
"github.com/go-jose/go-jose/v4/jwt"
)

func TestRegisterPublicClientUsesNativeApplicationType(t *testing.T) {
requests := make(chan map[string]any, 1)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
requests <- body
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
_, _ = w.Write([]byte(`{"client_id":"client-1"}`))
}))
t.Cleanup(server.Close)

_, err := registerPublicClient(
server.URL,
[]string{"http://127.0.0.1:46289/callback"},
[]string{"authorization_code", "refresh_token"},
[]string{"code"},
)
if err != nil {
t.Fatal(err)
}
body := <-requests
if body["application_type"] != "native" {
t.Fatalf("application_type = %#v, want native", body["application_type"])
}
redirectURIs, ok := body["redirect_uris"].([]any)
if !ok || len(redirectURIs) != 1 || redirectURIs[0] != "http://127.0.0.1:46289/callback" {
t.Fatalf("redirect_uris = %#v", body["redirect_uris"])
}
}

func TestRegisterPublicClientOmitsUnusedDeviceRedirectMetadata(t *testing.T) {
requests := make(chan map[string]any, 1)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
requests <- body
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"client_id":"device-client"}`))
}))
t.Cleanup(server.Close)

_, err := registerPublicClient(
server.URL,
nil,
[]string{"urn:ietf:params:oauth:grant-type:device_code", "refresh_token"},
nil,
)
if err != nil {
t.Fatal(err)
}
body := <-requests
if body["application_type"] != "native" {
t.Fatalf("application_type = %#v, want native", body["application_type"])
}
if _, ok := body["redirect_uris"]; ok {
t.Fatalf("redirect_uris should be omitted, got %#v", body["redirect_uris"])
}
if _, ok := body["response_types"]; ok {
t.Fatalf("response_types should be omitted, got %#v", body["response_types"])
}
}

func TestOAuthCallbackHandlerDeliversOnlyFirstRequest(t *testing.T) {
results := make(chan callbackResult, 1)
handler := oauthCallbackHandler(results)
Expand Down
4 changes: 2 additions & 2 deletions internal/auth/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ func LoginDeviceCode(server string) (*config.Credential, error) {
// Register client
clientInfo, err := registerPublicClient(
regEndpoint,
[]string{"http://localhost/callback"},
nil,
[]string{"urn:ietf:params:oauth:grant-type:device_code", "refresh_token"},
[]string{"code"},
nil,
)
if err != nil {
return nil, err
Expand Down