fix: sync temp auth key expiry boundaries

This commit is contained in:
A 2026-07-13 23:04:15 +08:00
parent 305e8a0008
commit 20a310f6ca
50 changed files with 3626 additions and 335 deletions

View file

@ -17,6 +17,19 @@ type revokeCaptureSessions struct {
closedRawAuthKeyIDs [][8]byte
}
type expiringCaptureSessions struct {
*captureSessions
expiresAt int
}
type metadataBlindSessions struct {
SessionBinder
}
func (s *expiringCaptureSessions) AuthKeyExpiresAtForSession([8]byte, int64) (int, bool) {
return s.expiresAt, true
}
func (s *revokeCaptureSessions) CloseSessionsForBusinessAuthKey(authKeyID [8]byte) int {
s.mu.Lock()
defer s.mu.Unlock()
@ -31,6 +44,76 @@ func (s *revokeCaptureSessions) CloseSessionsForRawAuthKeyExcept(authKeyID [8]by
return 1
}
func TestCachedRawTemporarySessionReResolvesDurableBinding(t *testing.T) {
tempAuthKeyID := [8]byte{0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76}
permAuthKeyID := [8]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
base := &captureSessions{}
base.BindAuthKeyForSession(tempAuthKeyID, 554, tempAuthKeyID)
sessions := &expiringCaptureSessions{
captureSessions: base,
expiresAt: int(time.Now().Add(time.Hour).Unix()),
}
auth := &captureAuthService{
resolvedAuthKeyID: permAuthKeyID,
hasResolved: true,
userID: 1000000001,
}
r := New(Config{TempKeyResolveCacheTTL: time.Minute}, Deps{
Auth: auth,
Files: &fakeFiles{},
Sessions: sessions,
}, zaptest.NewLogger(t), clock.System)
var in bin.Buffer
if err := (&tg.UploadSaveFilePartRequest{FileID: 19, FilePart: 0, Bytes: []byte{1}}).Encode(&in); err != nil {
t.Fatalf("encode: %v", err)
}
if _, err := r.Dispatch(context.Background(), tempAuthKeyID, 554, &in); err != nil {
t.Fatalf("dispatch: %v", err)
}
if auth.resolveCount != 1 {
t.Fatalf("ResolveAuthKey calls = %d, want 1 for cached raw temporary session", auth.resolveCount)
}
got := sessions.snapshot()
if got.authKeyID != permAuthKeyID || got.userID != 1000000001 {
t.Fatalf("session = auth %x user %d, want perm/user", got.authKeyID, got.userID)
}
}
func TestCachedRawSessionWithoutMetadataFailsClosedToDurableResolver(t *testing.T) {
tempAuthKeyID := [8]byte{0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75}
permAuthKeyID := [8]byte{0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35}
// captureSessions intentionally has no RawAuthKeyMetadataProvider capability.
// Missing metadata is not evidence that raw is permanent.
base := &captureSessions{}
base.BindAuthKeyForSession(tempAuthKeyID, 553, tempAuthKeyID)
sessions := &metadataBlindSessions{SessionBinder: base}
auth := &captureAuthService{
resolvedAuthKeyID: permAuthKeyID,
hasResolved: true,
userID: 1000000001,
}
r := New(Config{TempKeyResolveCacheTTL: time.Minute}, Deps{
Auth: auth,
Files: &fakeFiles{},
Sessions: sessions,
}, zaptest.NewLogger(t), clock.System)
var in bin.Buffer
if err := (&tg.UploadSaveFilePartRequest{FileID: 18, FilePart: 0, Bytes: []byte{1}}).Encode(&in); err != nil {
t.Fatalf("encode: %v", err)
}
if _, err := r.Dispatch(context.Background(), tempAuthKeyID, 553, &in); err != nil {
t.Fatalf("dispatch: %v", err)
}
if auth.resolveCount != 1 {
t.Fatalf("ResolveAuthKey calls = %d, want 1 without metadata proof", auth.resolveCount)
}
if got := base.snapshot(); got.authKeyID != permAuthKeyID || got.userID != 1000000001 {
t.Fatalf("session = auth %x user %d, want canonical perm/user", got.authKeyID, got.userID)
}
}
// TestTempKeyResolveCacheHitsWithinTTL 验证TempKeyResolveCacheTTL>0 时,同一 temp key 的连续
// 请求在 TTL 内只解析一次(首帧走 !hasCached 解析 1 次、次帧 hasCached 解析并填缓存 1 次,之后命中
// 缓存不再打 ResolveAuthKey。固化「缓存生效」语义与现有「TTL=0 每帧重校验」的安全测试互补。