mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
feat: allow external auth providers to expose extra metadata (#10157)
This commit is contained in:
@ -1,10 +1,13 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os/signal"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/codersdk/agentsdk"
|
||||
@ -25,7 +28,7 @@ func (r *RootCmd) externalAuth() *clibase.Cmd {
|
||||
}
|
||||
|
||||
func (r *RootCmd) externalAuthAccessToken() *clibase.Cmd {
|
||||
var silent bool
|
||||
var extra string
|
||||
return &clibase.Cmd{
|
||||
Use: "access-token <provider>",
|
||||
Short: "Print auth for an external provider",
|
||||
@ -45,12 +48,16 @@ else
|
||||
fi
|
||||
`,
|
||||
},
|
||||
example{
|
||||
Description: "Obtain an extra property of an access token for additional metadata.",
|
||||
Command: "coder external-auth access-token slack --extra \"authed_user.id\"",
|
||||
},
|
||||
),
|
||||
Options: clibase.OptionSet{{
|
||||
Name: "Silent",
|
||||
Flag: "s",
|
||||
Description: "Do not print the URL or access token.",
|
||||
Value: clibase.BoolOf(&silent),
|
||||
Name: "Extra",
|
||||
Flag: "extra",
|
||||
Description: "Extract a field from the \"extra\" properties of the OAuth token.",
|
||||
Value: clibase.StringOf(&extra),
|
||||
}},
|
||||
|
||||
Handler: func(inv *clibase.Invocation) error {
|
||||
@ -64,27 +71,38 @@ fi
|
||||
return xerrors.Errorf("create agent client: %w", err)
|
||||
}
|
||||
|
||||
token, err := client.ExternalAuth(ctx, agentsdk.ExternalAuthRequest{
|
||||
extAuth, err := client.ExternalAuth(ctx, agentsdk.ExternalAuthRequest{
|
||||
ID: inv.Args[0],
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get external auth token: %w", err)
|
||||
}
|
||||
|
||||
if !silent {
|
||||
if token.URL != "" {
|
||||
_, err = inv.Stdout.Write([]byte(token.URL))
|
||||
} else {
|
||||
_, err = inv.Stdout.Write([]byte(token.AccessToken))
|
||||
}
|
||||
if extAuth.URL != "" {
|
||||
_, err = inv.Stdout.Write([]byte(extAuth.URL))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if token.URL != "" {
|
||||
return cliui.Canceled
|
||||
}
|
||||
if extra != "" {
|
||||
if extAuth.TokenExtra == nil {
|
||||
return xerrors.Errorf("no extra properties found for token")
|
||||
}
|
||||
data, err := json.Marshal(extAuth.TokenExtra)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("marshal extra properties: %w", err)
|
||||
}
|
||||
result := gjson.GetBytes(data, extra)
|
||||
_, err = inv.Stdout.Write([]byte(result.String()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_, err = inv.Stdout.Write([]byte(extAuth.AccessToken))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -46,4 +46,22 @@ func TestExternalAuth(t *testing.T) {
|
||||
clitest.Start(t, inv)
|
||||
pty.ExpectMatch("bananas")
|
||||
})
|
||||
t.Run("SuccessWithExtra", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(context.Background(), w, http.StatusOK, agentsdk.ExternalAuthResponse{
|
||||
AccessToken: "bananas",
|
||||
TokenExtra: map[string]interface{}{
|
||||
"hey": "there",
|
||||
},
|
||||
})
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
url := srv.URL
|
||||
inv, _ := clitest.New(t, "--agent-url", url, "external-auth", "access-token", "github", "--extra", "hey")
|
||||
pty := ptytest.New(t)
|
||||
inv.Stdout = pty.Output()
|
||||
clitest.Start(t, inv)
|
||||
pty.ExpectMatch("there")
|
||||
})
|
||||
}
|
||||
|
@ -19,10 +19,14 @@ USAGE:
|
||||
echo "Please authenticate with GitHub:"
|
||||
echo $OUTPUT
|
||||
fi
|
||||
|
||||
- Obtain an extra property of an access token for additional metadata.:
|
||||
|
||||
$ coder external-auth access-token slack --extra "authed_user.id"
|
||||
|
||||
OPTIONS:
|
||||
--s bool
|
||||
Do not print the URL or access token.
|
||||
--extra string
|
||||
Extract a field from the "extra" properties of the OAuth token.
|
||||
|
||||
———
|
||||
Run `coder --help` for a list of global options.
|
||||
|
Reference in New Issue
Block a user