From 8621bb2670a904557a565b83b167614f4cdb2c33 Mon Sep 17 00:00:00 2001 From: smail Date: Sat, 5 Sep 2026 08:29:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=85=A5=E7=AB=99=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E7=A6=81=E7=94=A8=E8=B4=A6=E5=8F=B7=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E4=B8=8EPOP3=E8=B6=8A=E6=9D=83=E9=98=B2=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/listen/pop3_server/action.go | 4 +++ server/listen/pop3_server/action_test.go | 25 +++++++++++++++++++ .../listen/smtp_server/audit_persistence.go | 4 +-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/server/listen/pop3_server/action.go b/server/listen/pop3_server/action.go index b4c52f3..de4b717 100644 --- a/server/listen/pop3_server/action.go +++ b/server/listen/pop3_server/action.go @@ -144,6 +144,10 @@ func (a action) Uidl(session *gopop.Session, msg string) ([]gopop.UidlItem, erro reqId := cast.ToInt64(msg) if reqId > 0 { + info, err := detail.GetEmailDetail(session.Ctx.(*context.Context), cast.ToInt(reqId), false) + if err != nil || info == nil { + return nil, errors2.New("no such message") + } log.WithContext(session.Ctx).Debugf("Uidl \n %+v", reqId) return []gopop.UidlItem{ { diff --git a/server/listen/pop3_server/action_test.go b/server/listen/pop3_server/action_test.go index 2ff8796..2eb6989 100644 --- a/server/listen/pop3_server/action_test.go +++ b/server/listen/pop3_server/action_test.go @@ -72,3 +72,28 @@ func TestActionUserPreservesFullEmailIdentifier(t *testing.T) { t.Fatalf("POP3 user identifier = %q, want full email identifier", session.User) } } + +func TestActionUidlOwnershipValidation(t *testing.T) { + testRoot := t.TempDir() + config.Instance = &config.Config{DbType: config.DBTypeSQLite, DbDSN: filepath.Join(testRoot, "pop3_uidl.db")} + if err := db.Init(""); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if db.Instance != nil { + _ = db.Instance.Close() + } + }) + + a := action{} + session := &gopop.Session{ + Ctx: &context.Context{ + UserID: 1, + }, + } + // 查询未授权/不存在的邮件 ID 应返回错误 + _, err := a.Uidl(session, "99999") + if err == nil { + t.Fatal("expected error for unauthorized/non-existent message UIDL query, got nil") + } +} diff --git a/server/listen/smtp_server/audit_persistence.go b/server/listen/smtp_server/audit_persistence.go index 36ccf83..5ebe9e2 100644 --- a/server/listen/smtp_server/audit_persistence.go +++ b/server/listen/smtp_server/audit_persistence.go @@ -153,7 +153,7 @@ func resolveIncomingUsers(ctx *context.Context, email *parsemail.Email, emailTyp accounts := incomingAccounts(email, reallyTo) var users []*models.User if len(accounts) > 0 { - where, params, err := builder.ToSQL(builder.In("LOWER(account)", accounts)) + where, params, err := builder.ToSQL(builder.And(builder.In("LOWER(account)", accounts), builder.Eq{"disabled": 0})) if err != nil { return nil, false, err } @@ -175,7 +175,7 @@ func resolveIncomingUsers(ctx *context.Context, email *parsemail.Email, emailTyp } log.WithContext(ctx).Infof("收件人不存在但DKIM验证通过,转交管理员: recipient_count=%d", len(accounts)) - if err := db.Instance.Table(&models.User{}).Where("is_admin=1").Find(&users); err != nil { + if err := db.Instance.Table(&models.User{}).Where("is_admin=1 AND disabled=0").Find(&users); err != nil { return nil, false, err } if len(users) == 0 {