Skip to content

fix(auth): classify SQLite busy separately from credential failures - #3348

Open
HW618 wants to merge 1 commit into
OpenListTeam:mainfrom
HW618:fix/sqlite-webdav-lock-starvation
Open

HW618 wants to merge 1 commit into
OpenListTeam:mainfrom
HW618:fix/sqlite-webdav-lock-starvation

Conversation

@HW618

@HW618 HW618 commented Nov 7, 2026 •

Copy link
Copy Markdown

Summary / 摘要

Rebased onto latest main as a single commit for easier review.

Unify authentication failure handling so SQLite lock contention and other infrastructure errors are not treated as bad credentials, and shorten WebDAV dead-props transaction scope to reduce SQLite lock starvation.

  • Map DB busy / nested-tx failures to 503 (Subsonic code 0) without advancing lockout counters
  • Keep credential failures (unknown user, wrong password, LDAP unmatched) as 401/400 with lockout counting
  • Restrict LDAP auto-register fallback to local RecordNotFound only
  • Hide internal DB/LDAP details from unauthenticated clients
  • Shorten WebDAV PROPFIND dead-props handling so long remote I/O is not held inside a DB transaction
  • Align Emby/Subsonic AppKey and session lookup paths with the same classification rules

SQLite DSN / WAL: this PR no longer changes bootstrap drivers. Upstream #3344 already enables WAL/busy_timeout via appendDSNParams; this branch adopts that.

Error class Client result Counts toward lockout
SQLITE_BUSY / nested tx / schema-locked 503 / Subsonic 0 No
Unknown user / wrong password / LDAP unmatched 401 / 400 Yes
Other DB / LDAP infrastructure errors 500 with generic message No
  • This PR has breaking changes.
  • This PR changes public API, config, storage format, or migration behavior.
  • This PR requires corresponding changes in related repositories.

Related Issues / 关联 Issue

Relates to #3298 / #3342. Supersedes the earlier multi-commit / merge history on this PR head.

Testing / 测试

  • Targeted Go tests:
    • go test ./internal/errs/ ./server/common/ ./server/ ./server/handles/ ./server/middlewares/ ./server/webdav/ ./internal/op/ -count=1
  • Manual / 手动测试:
    • Local image openlist:auth-classify-local-test
    • Temporary container smoke on 127.0.0.1:15244 (isolated data; not production volume)
    • Wrong password / missing user → 401; empty username → 400; LDAP disabled → 403; WebDAV bad Basic → 401; successful admin login + /api/me
    • No panic / unexpected 500 in smoke logs

Checklist / 检查清单

  • I have read CONTRIBUTING.
  • I confirm this contribution follows the repository license, contribution policy, and code of conduct.
  • I have formatted changed code with gofmt where applicable (avoided whole-file emby.go alignment churn outside semantic edits).
  • I have requested review from relevant maintainers or code owners where applicable.

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content.

Tools used:

  • Gemini
  • Other: Cursor Agent

Usage scope:

  • Code generation

  • Refactoring

  • Tests

  • Review assistance

  • I have reviewed and validated all AI-assisted content included in this PR.

  • I have ensured that all AI-assisted commits include Co-Authored-By attribution (latest squash commit follows AGENTS.md: no invented trailer for unlisted assistants).

  • I can reproduce all AI-assisted content included in this PR without any AI tools.

@jyxjjj jyxjjj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] ClassifyAuthError 漏掉了 LDAP 用户不存在的凭据失败。HandleLdapLogin 在查询不到用户时返回普通 error,既不是 ErrFailedLdapAuth,也不是 gorm.ErrRecordNotFound。开启 LDAP 后,用不存在的用户名请求 WebDAV,会从原来的 401 且累计失败次数,变成 500 且完全不计数,FTP/SFTP 也会漏掉计数。要把 LDAP 的无匹配用户结果明确标成鉴权失败,保持 401 和失败次数,连接、查询及数据库故障再走服务错误分支。


Reviewed or refined by GPT-6.1-Sol Medium

@HW618
HW618 force-pushed the fix/sqlite-webdav-lock-starvation branch from b2f07fd to 46d5739 Compare November 13, 2026 04:09
- Shorten WebDAV dead-props transactions so PROPFIND does not hold long DB locks
- Map SQLITE_BUSY / nested-tx failures to 503 (Subsonic code 0) without lockout
- Keep unknown user, wrong password, and LDAP unmatched results as auth failures
- Restrict LDAP auto-register fallback to local RecordNotFound only
- Hide infrastructure error details from unauthenticated clients
- Align Emby/Subsonic AppKey and session lookups with the same classification

Co-authored-by: Cursor <cursoragent@cursor.com>
@HW618
HW618 force-pushed the fix/sqlite-webdav-lock-starvation branch from 46d5739 to 85ad51c Compare November 13, 2026 05:52
@HW618 HW618 changed the title fix(webdav,bootstrap,auth): avoid SQLite lock starvation and misleading auth errors fix(auth): classify SQLite busy separately from credential failures Nov 13, 2026
@HW618

HW618 commented Nov 13, 2026

Copy link
Copy Markdown
Author

Update for reviewers:

  • Rebased onto latest main and squashed to a single commit (85ad51c5).
  • Removed obsolete local glebarez DSN normalization; WAL/busy_timeout now rely on upstream #3344 appendDSNParams.
  • Diff vs main is now focused on auth classification + WebDAV short transactions only (no bootstrap driver changes).
  • Same tip is also on fork branch fix/auth-busy-classify for local tracking.

@HW618
HW618 requested a review from jyxjjj November 13, 2026 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants