Files
new-api/model/external_identity_claim_test.go
Calcium-Ion 31d70fca39 refactor(auth): replace dashboard sessions with stateless tokens and session control (#6329)
* refactor(auth): replace dashboard sessions with stateless tokens

* feat(auth): harden session issuance and distributed enforcement

* fix(proxy): preserve trusted proxy compatibility defaults

* refactor: address dashboard auth review feedback

* refactor: remove classic frontend and flatten web app
2026-07-20 16:48:43 +08:00

92 lines
3.5 KiB
Go

package model
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
func TestExternalIdentityClaimEnforcesSingleOwnerAtomically(t *testing.T) {
truncateTables(t)
first := User{Username: "telegram-owner-one", Password: "password", AffCode: "telegram-owner-one"}
second := User{Username: "telegram-owner-two", Password: "password", AffCode: "telegram-owner-two"}
require.NoError(t, DB.Create(&first).Error)
require.NoError(t, DB.Create(&second).Error)
require.NoError(t, DB.Transaction(func(tx *gorm.DB) error {
return ClaimExternalIdentityWithTx(tx, ExternalIdentityProviderTelegram, "telegram-123", first.Id)
}))
err := DB.Transaction(func(tx *gorm.DB) error {
return ClaimExternalIdentityWithTx(tx, ExternalIdentityProviderTelegram, "telegram-123", second.Id)
})
assert.ErrorIs(t, err, ErrExternalIdentityAlreadyClaimed)
err = DB.Transaction(func(tx *gorm.DB) error {
return ClaimExternalIdentityWithTx(tx, ExternalIdentityProviderTelegram, "telegram-456", first.Id)
})
assert.ErrorIs(t, err, ErrExternalIdentityAlreadyClaimed)
var claims []ExternalIdentityClaim
require.NoError(t, DB.Find(&claims).Error)
require.Len(t, claims, 1)
assert.Equal(t, first.Id, claims[0].UserId)
assert.Equal(t, "telegram-123", claims[0].Subject)
require.NoError(t, DB.Transaction(func(tx *gorm.DB) error {
return ReleaseExternalIdentityWithTx(tx, ExternalIdentityProviderTelegram, first.Id)
}))
require.NoError(t, DB.Transaction(func(tx *gorm.DB) error {
return ClaimExternalIdentityWithTx(tx, ExternalIdentityProviderTelegram, "telegram-123", second.Id)
}))
}
func TestClearTelegramBindingReleasesIdentityClaim(t *testing.T) {
truncateTables(t)
user := User{Username: "telegram-unbind", Password: "password", TelegramId: "telegram-unbind-id"}
require.NoError(t, DB.Create(&user).Error)
require.NoError(t, DB.Transaction(func(tx *gorm.DB) error {
return ClaimExternalIdentityWithTx(tx, ExternalIdentityProviderTelegram, user.TelegramId, user.Id)
}))
require.NoError(t, user.ClearBinding(ExternalIdentityProviderTelegram))
assert.Empty(t, user.TelegramId)
var count int64
require.NoError(t, DB.Model(&ExternalIdentityClaim{}).Where("user_id = ?", user.Id).Count(&count).Error)
assert.Zero(t, count)
}
func TestInitializeExternalIdentityClaimsIsIdempotent(t *testing.T) {
truncateTables(t)
user := User{Username: "telegram-legacy", Password: "password", TelegramId: "telegram-legacy-id"}
require.NoError(t, DB.Create(&user).Error)
require.NoError(t, InitializeExternalIdentityClaims())
require.NoError(t, InitializeExternalIdentityClaims())
var claim ExternalIdentityClaim
require.NoError(t, DB.Where("provider = ? AND subject = ?", ExternalIdentityProviderTelegram, user.TelegramId).
First(&claim).Error)
assert.Equal(t, user.Id, claim.UserId)
}
func TestInitializeExternalIdentityClaimsRejectsAmbiguousLegacyBindings(t *testing.T) {
truncateTables(t)
first := User{Username: "telegram-legacy-one", Password: "password", TelegramId: "duplicate-telegram-id", AffCode: "telegram-legacy-one"}
second := User{Username: "telegram-legacy-two", Password: "password", TelegramId: "duplicate-telegram-id", AffCode: "telegram-legacy-two"}
require.NoError(t, DB.Create(&first).Error)
require.NoError(t, DB.Create(&second).Error)
err := InitializeExternalIdentityClaims()
assert.ErrorIs(t, err, ErrExternalIdentityAlreadyClaimed)
var count int64
require.NoError(t, DB.Model(&ExternalIdentityClaim{}).Count(&count).Error)
assert.Zero(t, count)
}