Ctrl K
ComunidadGuías…

cli/useroidcclaims_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package cli_test

import (
	"bytes"
	"encoding/json"
	"testing"

	"github.com/golang-jwt/jwt/v4"
	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/coder/coder/v2/cli/clitest"
	"github.com/coder/coder/v2/coderd"
	"github.com/coder/coder/v2/coderd/coderdtest"
	"github.com/coder/coder/v2/coderd/coderdtest/oidctest"
	"github.com/coder/coder/v2/codersdk"
	"github.com/coder/coder/v2/testutil"
)

func TestUserOIDCClaims(t *testing.T) {
	t.Parallel()

	newOIDCTest := func(t *testing.T) (*oidctest.FakeIDP, *codersdk.Client) {
		t.Helper()

		fake := oidctest.NewFakeIDP(t,
			oidctest.WithServing(),
		)
		cfg := fake.OIDCConfig(t, nil, func(cfg *coderd.OIDCConfig) {
			cfg.AllowSignups = true
		})
		ownerClient := coderdtest.New(t, &coderdtest.Options{
			OIDCConfig: cfg,
		})
		return fake, ownerClient
	}

	t.Run("OwnClaims", func(t *testing.T) {
		t.Parallel()

		fake, ownerClient := newOIDCTest(t)
		claims := jwt.MapClaims{
			"email":          "alice@coder.com",
			"email_verified": true,
			"sub":            uuid.NewString(),
			"groups":         []string{"admin", "eng"},
		}
		userClient, loginResp := fake.Login(t, ownerClient, claims)
		defer loginResp.Body.Close()

		inv, root := clitest.New(t, "users", "oidc-claims", "-o", "json")
		clitest.SetupConfig(t, userClient, root)

		buf := bytes.NewBuffer(nil)
		inv.Stdout = buf
		err := inv.WithContext(testutil.Context(t, testutil.WaitMedium)).Run()
		require.NoError(t, err)

		var resp codersdk.OIDCClaimsResponse
		err = json.Unmarshal(buf.Bytes(), &resp)
		require.NoError(t, err, "unmarshal JSON output")
		require.NotEmpty(t, resp.Claims, "claims should not be empty")
		assert.Equal(t, "alice@coder.com", resp.Claims["email"])
	})

	t.Run("Table", func(t *testing.T) {
		t.Parallel()

		fake, ownerClient := newOIDCTest(t)
		claims := jwt.MapClaims{
			"email":          "bob@coder.com",
			"email_verified": true,
			"sub":            uuid.NewString(),
		}
		userClient, loginResp := fake.Login(t, ownerClient, claims)
		defer loginResp.Body.Close()

		inv, root := clitest.New(t, "users", "oidc-claims")
		clitest.SetupConfig(t, userClient, root)

		buf := bytes.NewBuffer(nil)
		inv.Stdout = buf
		err := inv.WithContext(testutil.Context(t, testutil.WaitMedium)).Run()
		require.NoError(t, err)

		output := buf.String()
		require.Contains(t, output, "email")
		require.Contains(t, output, "bob@coder.com")
	})

	t.Run("NotOIDCUser", func(t *testing.T) {
		t.Parallel()

		client := coderdtest.New(t, nil)
		_ = coderdtest.CreateFirstUser(t, client)

		inv, root := clitest.New(t, "users", "oidc-claims")
		clitest.SetupConfig(t, client, root)

		err := inv.WithContext(testutil.Context(t, testutil.WaitMedium)).Run()
		require.Error(t, err)
		require.Contains(t, err.Error(), "not an OIDC user")
	})

	// Verify that two different OIDC users each only see their own
	// claims. The endpoint has no user parameter, so there is no way
	// to request another user's claims by design.
	t.Run("OnlyOwnClaims", func(t *testing.T) {
		t.Parallel()

		aliceFake, aliceOwnerClient := newOIDCTest(t)
		aliceClaims := jwt.MapClaims{
			"email":          "alice-isolation@coder.com",
			"email_verified": true,
			"sub":            uuid.NewString(),
		}
		aliceClient, aliceLoginResp := aliceFake.Login(t, aliceOwnerClient, aliceClaims)
		defer aliceLoginResp.Body.Close()

		bobFake, bobOwnerClient := newOIDCTest(t)
		bobClaims := jwt.MapClaims{
			"email":          "bob-isolation@coder.com",
			"email_verified": true,
			"sub":            uuid.NewString(),
		}
		bobClient, bobLoginResp := bobFake.Login(t, bobOwnerClient, bobClaims)
		defer bobLoginResp.Body.Close()

		ctx := testutil.Context(t, testutil.WaitMedium)

		// Alice sees her own claims.
		aliceResp, err := aliceClient.UserOIDCClaims(ctx)
		require.NoError(t, err)
		assert.Equal(t, "alice-isolation@coder.com", aliceResp.Claims["email"])

		// Bob sees his own claims.
		bobResp, err := bobClient.UserOIDCClaims(ctx)
		require.NoError(t, err)
		assert.Equal(t, "bob-isolation@coder.com", bobResp.Claims["email"])
	})

	t.Run("ClaimsNeverNull", func(t *testing.T) {
		t.Parallel()

		fake, ownerClient := newOIDCTest(t)
		// Use minimal claims — just enough for OIDC login.
		claims := jwt.MapClaims{
			"email":          "minimal@coder.com",
			"email_verified": true,
			"sub":            uuid.NewString(),
		}
		userClient, loginResp := fake.Login(t, ownerClient, claims)
		defer loginResp.Body.Close()

		ctx := testutil.Context(t, testutil.WaitMedium)
		resp, err := userClient.UserOIDCClaims(ctx)
		require.NoError(t, err)
		require.NotNil(t, resp.Claims, "claims should never be nil, expected empty map")
	})
}