fix(admin): close PR review blockers
Keep bot credentials out of durable command results, fail bot deletion closed when session revocation fails, reject invalid scam/fake states at every write boundary, and make direct collectible grants a single replayable PostgreSQL aggregate. Also lock admin gift sender/message limits and add regression coverage for rollback, replay, moderation constraints, and credential redaction.
This commit is contained in:
parent
90792cdfab
commit
234061ef83
30 changed files with 859 additions and 93 deletions
|
|
@ -201,6 +201,9 @@ func (s *ChannelStore) SetChannelScamFake(_ context.Context, channelID int64, sc
|
|||
if channelID == 0 {
|
||||
return domain.Channel{}, domain.ErrChannelInvalid
|
||||
}
|
||||
if scam && fake {
|
||||
return domain.Channel{}, domain.ErrPeerModerationFlagsInvalid
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
channel, ok := s.channels[channelID]
|
||||
|
|
|
|||
40
internal/store/memory/moderation_flags_test.go
Normal file
40
internal/store/memory/moderation_flags_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package memory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
func TestModerationStoresRejectScamAndFakeTogether(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
users := NewUserStore()
|
||||
user, err := users.Create(ctx, domain.User{Phone: "+15550009999", FirstName: "Flag"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := users.SetScamFake(ctx, user.ID, true, true); !errors.Is(err, domain.ErrPeerModerationFlagsInvalid) {
|
||||
t.Fatalf("user SetScamFake error=%v", err)
|
||||
}
|
||||
gotUser, found, err := users.ByID(ctx, user.ID)
|
||||
if err != nil || !found || gotUser.Scam || gotUser.Fake {
|
||||
t.Fatalf("user after rejected flags=%+v found=%v err=%v", gotUser, found, err)
|
||||
}
|
||||
|
||||
channels := NewChannelStore()
|
||||
created, err := channels.CreateChannel(ctx, domain.CreateChannelRequest{
|
||||
CreatorUserID: user.ID, Title: "Flags", Megagroup: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := channels.SetChannelScamFake(ctx, created.Channel.ID, true, true); !errors.Is(err, domain.ErrPeerModerationFlagsInvalid) {
|
||||
t.Fatalf("channel SetChannelScamFake error=%v", err)
|
||||
}
|
||||
gotChannel, err := channels.GetChannelByID(ctx, created.Channel.ID)
|
||||
if err != nil || gotChannel.Scam || gotChannel.Fake {
|
||||
t.Fatalf("channel after rejected flags=%+v err=%v", gotChannel, err)
|
||||
}
|
||||
}
|
||||
|
|
@ -298,6 +298,9 @@ func (s *UserStore) SetSupport(_ context.Context, userID int64, support bool) (d
|
|||
|
||||
// SetScamFake 设置/取消用户的 scam 与 fake 标记(与 postgres 语义一致)。
|
||||
func (s *UserStore) SetScamFake(_ context.Context, userID int64, scam, fake bool) (domain.User, error) {
|
||||
if scam && fake {
|
||||
return domain.User{}, domain.ErrPeerModerationFlagsInvalid
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
u, ok := s.byID[userID]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue