mirror of
https://github.com/coder/coder.git
synced 2026-06-03 04:58:23 +00:00
18945a7949
Fixes https://github.com/coder/internal/issues/933 Refactors CLI tests that check the `--auth` flag parsing for various public clouds into a unit test that just creates the agent Client and asserts on the type. Testing that the agent client actually authenticates correctly with these auth types is well covered by Coderd tests, so we don't need to retread that ground here, and the deleted tests were flaky on Windows.
114 lines
3.0 KiB
Go
114 lines
3.0 KiB
Go
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/tidwall/gjson"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/cli/cliui"
|
|
"github.com/coder/coder/v2/codersdk/agentsdk"
|
|
"github.com/coder/serpent"
|
|
)
|
|
|
|
func externalAuth() *serpent.Command {
|
|
return &serpent.Command{
|
|
Use: "external-auth",
|
|
Short: "Manage external authentication",
|
|
Long: "Authenticate with external services inside of a workspace.",
|
|
Handler: func(i *serpent.Invocation) error {
|
|
return i.Command.HelpHandler(i)
|
|
},
|
|
Children: []*serpent.Command{
|
|
externalAuthAccessToken(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func externalAuthAccessToken() *serpent.Command {
|
|
var extra string
|
|
agentAuth := &AgentAuth{}
|
|
cmd := &serpent.Command{
|
|
Use: "access-token <provider>",
|
|
Short: "Print auth for an external provider",
|
|
Long: "Print an access-token for an external auth provider. " +
|
|
"The access-token will be validated and sent to stdout with exit code 0. " +
|
|
"If a valid access-token cannot be obtained, the URL to authenticate will be sent to stdout with exit code 1\n" + FormatExamples(
|
|
Example{
|
|
Description: "Ensure that the user is authenticated with GitHub before cloning.",
|
|
Command: `#!/usr/bin/env sh
|
|
|
|
OUTPUT=$(coder external-auth access-token github)
|
|
if [ $? -eq 0 ]; then
|
|
echo "Authenticated with GitHub"
|
|
else
|
|
echo "Please authenticate with GitHub:"
|
|
echo $OUTPUT
|
|
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\"",
|
|
},
|
|
),
|
|
Middleware: serpent.Chain(
|
|
serpent.RequireNArgs(1),
|
|
),
|
|
Options: serpent.OptionSet{{
|
|
Name: "Extra",
|
|
Flag: "extra",
|
|
Description: "Extract a field from the \"extra\" properties of the OAuth token.",
|
|
Value: serpent.StringOf(&extra),
|
|
}},
|
|
|
|
Handler: func(inv *serpent.Invocation) error {
|
|
ctx := inv.Context()
|
|
|
|
ctx, stop := inv.SignalNotifyContext(ctx, StopSignals...)
|
|
defer stop()
|
|
|
|
client, err := agentAuth.CreateClient()
|
|
if err != nil {
|
|
return xerrors.Errorf("create agent client: %w", err)
|
|
}
|
|
|
|
extAuth, err := client.ExternalAuth(ctx, agentsdk.ExternalAuthRequest{
|
|
ID: inv.Args[0],
|
|
})
|
|
if err != nil {
|
|
return xerrors.Errorf("get external auth token: %w", err)
|
|
}
|
|
if extAuth.URL != "" {
|
|
_, err = inv.Stdout.Write([]byte(extAuth.URL))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return cliui.ErrCanceled
|
|
}
|
|
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
|
|
},
|
|
}
|
|
agentAuth.AttachOptions(cmd, false)
|
|
return cmd
|
|
}
|