Smail/backend/services/credentials/protocol_grant_test.go
smail 8899e74a66
Some checks are pending
Security Checks / security (push) Waiting to run
修复邮件授权码撤销后旧协议连接仍可操作并补充回归验收
2026-09-21 01:57:23 +08:00

92 lines
2.6 KiB
Go

package credentials
import (
"encoding/json"
"testing"
"git.pcux.cn/xuans/Smail/models"
)
func TestProtocolGrantTracksCredentialChanges(t *testing.T) {
for _, change := range []string{"revoke", "rotate", "disable_enable", "delete", "hash", "version", "database"} {
t.Run(change, func(t *testing.T) {
s := newFixture(t)
if err := s.SetProtocolEnabled(1, ProtocolSMTP, true); err != nil {
t.Fatal(err)
}
code, err := s.GenerateProtocolCode(1, ProtocolSMTP)
if err != nil {
t.Fatal(err)
}
grant, err := s.CheckClientOrProtocolGrant(1, ProtocolSMTP, code)
if err != nil || !grant.Valid(s.engine) {
t.Fatalf("授权快照无效:%v", err)
}
data, err := json.Marshal(grant)
if err != nil || string(data) != "{}" {
t.Fatal("授权快照泄漏内部字段")
}
switch change {
case "revoke":
err = s.RevokeProtocolCode(1, ProtocolSMTP)
case "rotate":
_, err = s.GenerateProtocolCode(1, ProtocolSMTP)
case "disable_enable":
err = s.SetProtocolEnabled(1, ProtocolSMTP, false)
if err == nil {
err = s.SetProtocolEnabled(1, ProtocolSMTP, true)
}
case "delete":
_, err = s.engine.Where("user_id = ?", 1).Delete(&models.ProtocolCredential{})
case "hash":
_, err = s.engine.Where("user_id = ?", 1).Cols("code_hash").Update(&models.ProtocolCredential{CodeHash: "replacement"})
case "version":
_, err = s.engine.Where("user_id = ?", 1).Incr("code_version", 1).Update(&models.ProtocolCredential{})
case "database":
if grant.Valid(newFixture(t).engine) {
t.Fatal("数据库切换后沿用旧授权")
}
return
}
if err != nil {
t.Fatal(err)
}
if grant.Valid(s.engine) {
t.Fatal("失效的凭据快照仍然有效")
}
})
}
}
func TestClientGrantRevocationPreservesOtherClients(t *testing.T) {
s := newFixture(t)
first, item, err := s.CreateClientCredential(1, "被撤销客户端")
if err != nil {
t.Fatal(err)
}
second, _, err := s.CreateClientCredential(1, "保留客户端")
if err != nil {
t.Fatal(err)
}
for _, protocol := range SupportedProtocols() {
grant, err := s.CheckClientOrProtocolGrant(1, protocol, first)
if err != nil || !grant.Valid(s.engine) {
t.Fatalf("客户端授权失败:%v", err)
}
}
firstGrant, err := s.CheckClientOrProtocolGrant(1, ProtocolIMAP, first)
if err != nil {
t.Fatal(err)
}
secondGrant, err := s.CheckClientOrProtocolGrant(1, ProtocolIMAP, second)
if err != nil {
t.Fatal(err)
}
if err := s.RevokeClientCredential(1, item.ID); err != nil {
t.Fatal(err)
}
if firstGrant.Valid(s.engine) || !secondGrant.Valid(s.engine) {
t.Fatal("客户端撤销范围不正确")
}
}