5074344c16
Add embed visitor principals (X-Embed-Visitor), widen sessions.user_id, embed MCP OAuth/approval routes, OAuth callback context detachment, and CloneContext principal preservation for async QA streams.
143 lines
4.3 KiB
Go
143 lines
4.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/Tencent/WeKnora/internal/application/repository"
|
|
apperrors "github.com/Tencent/WeKnora/internal/errors"
|
|
"github.com/Tencent/WeKnora/internal/types"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func testSessionScopeContext(tenantID uint64, userID string) context.Context {
|
|
ctx := context.WithValue(context.Background(), types.TenantIDContextKey, tenantID)
|
|
if userID != "" {
|
|
ctx = context.WithValue(ctx, types.UserIDContextKey, userID)
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
func testAPISessionScopeContext(tenantID uint64, externalUserID string) context.Context {
|
|
ctx := context.WithValue(context.Background(), types.TenantIDContextKey, tenantID)
|
|
ctx = context.WithValue(ctx, types.UserIDContextKey, "system-7")
|
|
return types.WithPrincipal(ctx, types.Principal{
|
|
Type: types.PrincipalAPIExternalUser,
|
|
ID: externalUserID,
|
|
})
|
|
}
|
|
|
|
func newTestSessionService(t *testing.T) (*sessionService, *gorm.DB) {
|
|
t.Helper()
|
|
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
require.NoError(t, db.AutoMigrate(&types.Session{}))
|
|
|
|
return &sessionService{
|
|
sessionRepo: repository.NewSessionRepository(db),
|
|
}, db
|
|
}
|
|
|
|
func TestGetSessionIsScopedToCurrentUser(t *testing.T) {
|
|
svc, db := newTestSessionService(t)
|
|
aliceSession := &types.Session{
|
|
TenantID: 1,
|
|
UserID: "alice",
|
|
Title: "alice private session",
|
|
}
|
|
require.NoError(t, db.Create(aliceSession).Error)
|
|
bobSession := &types.Session{
|
|
TenantID: 1,
|
|
UserID: "bob",
|
|
Title: "bob private session",
|
|
}
|
|
require.NoError(t, db.Create(bobSession).Error)
|
|
legacySession := &types.Session{
|
|
TenantID: 1,
|
|
Title: "legacy tenant session",
|
|
}
|
|
require.NoError(t, db.Create(legacySession).Error)
|
|
|
|
_, err := svc.GetSession(testSessionScopeContext(1, "bob"), aliceSession.ID)
|
|
require.ErrorIs(t, err, apperrors.ErrSessionNotFound)
|
|
|
|
got, err := svc.GetSession(testSessionScopeContext(1, "bob"), bobSession.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, bobSession.ID, got.ID)
|
|
|
|
got, err = svc.GetSession(testSessionScopeContext(1, "bob"), legacySession.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, legacySession.ID, got.ID)
|
|
}
|
|
|
|
func TestUpdateSessionIsScopedToCurrentUserAndAllowsNoOp(t *testing.T) {
|
|
svc, db := newTestSessionService(t)
|
|
aliceSession := &types.Session{
|
|
TenantID: 1,
|
|
UserID: "alice",
|
|
Title: "alice private session",
|
|
Description: "original description",
|
|
}
|
|
require.NoError(t, db.Create(aliceSession).Error)
|
|
|
|
err := svc.UpdateSession(testSessionScopeContext(1, "bob"), &types.Session{
|
|
ID: aliceSession.ID,
|
|
TenantID: 1,
|
|
Title: "bob update attempt",
|
|
Description: "should not be saved",
|
|
})
|
|
require.ErrorIs(t, err, apperrors.ErrSessionNotFound)
|
|
|
|
var unchanged types.Session
|
|
require.NoError(t, db.First(&unchanged, "id = ?", aliceSession.ID).Error)
|
|
require.Equal(t, aliceSession.Title, unchanged.Title)
|
|
require.Equal(t, aliceSession.Description, unchanged.Description)
|
|
|
|
err = svc.UpdateSession(testSessionScopeContext(1, "alice"), &types.Session{
|
|
ID: aliceSession.ID,
|
|
TenantID: 1,
|
|
Title: aliceSession.Title,
|
|
Description: aliceSession.Description,
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestGetSessionIsScopedToAPIExternalUser(t *testing.T) {
|
|
svc, db := newTestSessionService(t)
|
|
aliceSession := &types.Session{
|
|
TenantID: 1,
|
|
UserID: "api_external_user:7:alice",
|
|
Title: "alice api session",
|
|
}
|
|
require.NoError(t, db.Create(aliceSession).Error)
|
|
bobSession := &types.Session{
|
|
TenantID: 1,
|
|
UserID: "api_external_user:7:bob",
|
|
Title: "bob api session",
|
|
}
|
|
require.NoError(t, db.Create(bobSession).Error)
|
|
tenantSession := &types.Session{
|
|
TenantID: 1,
|
|
UserID: "system-7",
|
|
Title: "tenant api session",
|
|
}
|
|
require.NoError(t, db.Create(tenantSession).Error)
|
|
|
|
_, err := svc.GetSession(testAPISessionScopeContext(1, "7:alice"), bobSession.ID)
|
|
require.ErrorIs(t, err, apperrors.ErrSessionNotFound)
|
|
|
|
got, err := svc.GetSession(testAPISessionScopeContext(1, "7:alice"), aliceSession.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, aliceSession.ID, got.ID)
|
|
|
|
_, err = svc.GetSession(testAPISessionScopeContext(1, "7:alice"), tenantSession.ID)
|
|
require.ErrorIs(t, err, apperrors.ErrSessionNotFound)
|
|
|
|
got, err = svc.GetSession(testSessionScopeContext(1, "system-7"), tenantSession.ID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, tenantSession.ID, got.ID)
|
|
}
|