1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/service/backchannel_logout_service_test.go
chan 31d107ff2e feat(user): support fixed UUID registration and enhance bulk import results
- Added support for fixed UUIDs during bulk registration (Search-first + ExternalID mapping)
- Implemented idempotency and visibility restoration for soft-deleted users
- Enhanced bulk upload UI to show 'New/Updated/Unchanged' status and modified fields
- Added logic to reclaim identifiers (login_id) from colliding records
- Added frontend E2E and backend unit tests for UUID integrity and conflict handling
- Fixed i18n, formatting, and mock tests to satisfy code-check
- Applied 'go fix' for 'omitzero' tags and general Go standards
2026-06-01 15:34:08 +09:00

86 lines
2.4 KiB
Go

package service
import (
"context"
"encoding/json"
"io"
"net/http"
"testing"
"github.com/go-jose/go-jose/v4"
josejwt "github.com/go-jose/go-jose/v4/jwt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestBackchannelLogoutService_BuildLogoutToken(t *testing.T) {
t.Setenv("BACKCHANNEL_LOGOUT_ISSUER", "https://sso.example.com/oidc")
svc, err := NewBackchannelLogoutService()
require.NoError(t, err)
token, err := svc.BuildLogoutToken("client-1", "user-1", "sid-1")
require.NoError(t, err)
require.NotEmpty(t, token)
jwksRaw, err := svc.MarshalPublicJWKS()
require.NoError(t, err)
var jwks struct {
Keys []jose.JSONWebKey `json:"keys"`
}
require.NoError(t, json.Unmarshal(jwksRaw, &jwks))
require.Len(t, jwks.Keys, 1)
parsed, err := josejwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.RS256})
require.NoError(t, err)
var claims struct {
Issuer string `json:"iss"`
Subject string `json:"sub"`
Aud any `json:"aud"`
Iat int64 `json:"iat"`
Jti string `json:"jti"`
Sid string `json:"sid"`
Events map[string]any `json:"events"`
}
require.NoError(t, parsed.Claims(jwks.Keys[0].Key, &claims))
assert.Equal(t, "https://sso.example.com/oidc", claims.Issuer)
assert.Equal(t, "user-1", claims.Subject)
switch aud := claims.Aud.(type) {
case string:
assert.Equal(t, "client-1", aud)
case []any:
assert.Len(t, aud, 1)
assert.Equal(t, "client-1", aud[0])
default:
t.Fatalf("unexpected aud type: %T", claims.Aud)
}
assert.NotZero(t, claims.Iat)
assert.NotEmpty(t, claims.Jti)
assert.Equal(t, "sid-1", claims.Sid)
_, ok := claims.Events[backchannelLogoutEventURI]
assert.True(t, ok)
}
func TestBackchannelLogoutService_SendLogoutToken(t *testing.T) {
var body string
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
assert.Equal(t, "application/x-www-form-urlencoded", r.Header.Get("Content-Type"))
raw, _ := io.ReadAll(r.Body)
body = string(raw)
w.WriteHeader(http.StatusNoContent)
})
svc, err := NewBackchannelLogoutService()
require.NoError(t, err)
svc.HTTPClient = clientForHandler(handler)
statusCode, err := svc.SendLogoutToken(context.Background(), "https://rp.example.com/backchannel-logout", "signed-token")
require.NoError(t, err)
assert.Equal(t, http.StatusNoContent, statusCode)
assert.Equal(t, "logout_token=signed-token", body)
}