mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
be1c06dec9
- Adds a new API endpoint `GET /api/v2/users/oidc-claims` that returns only the **merged claims** (not the separate id_token/userinfo breakdown). Scoped exclusively to the authenticated user's own identity — no user parameter, so users cannot view each other's claims. - Adds a new CLI command:** `coder users oidc-claims` that hits the above endpoint. - The existing owner-only debug endpoint is preserved unchanged for admins who need the full claim breakdown. > 🤖 This PR was created with the help of Coder Agents, and will be reviewed by my human. 🧑💻
80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/cli/cliui"
|
|
"github.com/coder/coder/v2/codersdk"
|
|
"github.com/coder/serpent"
|
|
)
|
|
|
|
func (r *RootCmd) userOIDCClaims() *serpent.Command {
|
|
formatter := cliui.NewOutputFormatter(
|
|
cliui.ChangeFormatterData(
|
|
cliui.TableFormat([]claimRow{}, []string{"key", "value"}),
|
|
func(data any) (any, error) {
|
|
resp, ok := data.(codersdk.OIDCClaimsResponse)
|
|
if !ok {
|
|
return nil, xerrors.Errorf("expected type %T, got %T", resp, data)
|
|
}
|
|
rows := make([]claimRow, 0, len(resp.Claims))
|
|
for k, v := range resp.Claims {
|
|
rows = append(rows, claimRow{
|
|
Key: k,
|
|
Value: fmt.Sprintf("%v", v),
|
|
})
|
|
}
|
|
return rows, nil
|
|
},
|
|
),
|
|
cliui.JSONFormat(),
|
|
)
|
|
|
|
cmd := &serpent.Command{
|
|
Use: "oidc-claims",
|
|
Short: "Display the OIDC claims for the authenticated user.",
|
|
Long: FormatExamples(
|
|
Example{
|
|
Description: "Display your OIDC claims",
|
|
Command: "coder users oidc-claims",
|
|
},
|
|
Example{
|
|
Description: "Display your OIDC claims as JSON",
|
|
Command: "coder users oidc-claims -o json",
|
|
},
|
|
),
|
|
Middleware: serpent.Chain(
|
|
serpent.RequireNArgs(0),
|
|
),
|
|
Handler: func(inv *serpent.Invocation) error {
|
|
client, err := r.InitClient(inv)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := client.UserOIDCClaims(inv.Context())
|
|
if err != nil {
|
|
return xerrors.Errorf("get oidc claims: %w", err)
|
|
}
|
|
|
|
out, err := formatter.Format(inv.Context(), resp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = fmt.Fprintln(inv.Stdout, out)
|
|
return err
|
|
},
|
|
}
|
|
|
|
formatter.AttachOptions(&cmd.Options)
|
|
return cmd
|
|
}
|
|
|
|
type claimRow struct {
|
|
Key string `json:"-" table:"key,default_sort"`
|
|
Value string `json:"-" table:"value"`
|
|
}
|