mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-05 07:26:36 +08:00
refactor(auth): modularize auth plugin with physical subpackages and decoupled services
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package consts defines constants, keys, and TTL values for the auth domain plugin.
|
||||
package consts
|
||||
|
||||
import "time"
|
||||
|
||||
// CAP 默认参数
|
||||
const (
|
||||
DefaultCapChallengeCount = 1
|
||||
DefaultCapChallengeSize = 32
|
||||
DefaultCapChallengeDifficulty = 4
|
||||
DefaultCapChallengeTTL = 10 * time.Minute
|
||||
DefaultCapTokenTTL = 20 * time.Minute
|
||||
|
||||
RedeemTokenIDLength = 8 // 兑换 Token ID 字节长度
|
||||
RedeemVerTokenLength = 15 // 兑换验证 Token 字节长度
|
||||
TokenPartsCount = 2 // 兑换 Token 由两部分组成 (id:token)
|
||||
ValuePartsCount = 2 // 存储值由 scope 和过期时间组成 (expNano|scope)
|
||||
)
|
||||
|
||||
// CAP 动态配置键常量
|
||||
const (
|
||||
ConfigKeyCapLoginEnabled = "cap_login_enabled"
|
||||
ConfigKeyCapChallengeCount = "cap_challenge_count"
|
||||
ConfigKeyCapChallengeSize = "cap_challenge_size"
|
||||
ConfigKeyCapChallengeDifficulty = "cap_challenge_difficulty"
|
||||
ConfigKeyCapChallengeTTL = "cap_challenge_ttl"
|
||||
// ConfigKeyCapTokenTTL 验证码 Token 过期时间键
|
||||
// #nosec G101
|
||||
ConfigKeyCapTokenTTL = "cap_token_ttl"
|
||||
)
|
||||
|
||||
// HTTP 响应错误文案
|
||||
const (
|
||||
ErrCapTokenMissing = "验证码验证失败,缺少验证码凭证" //nolint:gosec // error message constant
|
||||
ErrCapTokenInvalidOrExpired = "验证码校验失败或已过期,请重试" //nolint:gosec // error message constant
|
||||
ErrCapNotConfigured = "captcha is not configured"
|
||||
ErrChallengeGenerateFailed = "生成验证难题失败,请稍后再试"
|
||||
ErrInvalidRequestParams = "无效的参数"
|
||||
ErrSolutionVerifyFailed = "校验验证解答失败,请稍后再试"
|
||||
)
|
||||
|
||||
// Redeem 结果码,属于 redeem 响应 JSON 的对外契约取值,禁止改写取值
|
||||
const (
|
||||
RedeemErrInvalidToken = "invalid_token"
|
||||
RedeemErrNonceStoreFailed = "nonce_store_error"
|
||||
RedeemErrAlreadyRedeemed = "already_redeemed"
|
||||
RedeemErrSettingsLoad = "settings_load_error"
|
||||
RedeemErrTokenStoreFailed = "token_store_error" //nolint:gosec // error code constant
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package consts defines constants, keys, and TTL values for the auth domain plugin.
|
||||
package consts
|
||||
|
||||
import "time"
|
||||
|
||||
// Session and Context Keys
|
||||
const (
|
||||
UserNameKey = "username"
|
||||
UserIDKey = "user_id"
|
||||
UserObjKey = "user_obj"
|
||||
TokenAuthKey = "token_auth" // 标记当前请求是否通过 Access Token 鉴权
|
||||
TokenAdminKey = "token_admin" // Access Token 本身是否具有管理员权限
|
||||
SessionTokenKey = "oauth_session_token" //nolint:gosec // false positive: session state key
|
||||
PasswordHashKey = "password_hash"
|
||||
SystemUsername = "system"
|
||||
)
|
||||
|
||||
// OAuth State Cache Keys and Expirations
|
||||
const (
|
||||
OAuthStateCacheKeyFormat = "oauth:state:%s"
|
||||
OAuthStateCacheKeyExpiration = 10 * time.Minute
|
||||
OAuthStateLimitKeyFormat = "oauth:state:limit:%s"
|
||||
OAuthStateLimitMax = 10
|
||||
)
|
||||
|
||||
// OAuth Purpose Constants
|
||||
const (
|
||||
OAuthPurposeLogin = "login"
|
||||
OAuthPurposeBind = "bind"
|
||||
)
|
||||
|
||||
// Auth Source Types
|
||||
const (
|
||||
AuthSourceTypeOIDC = "oidc"
|
||||
)
|
||||
|
||||
// Cache TTLs
|
||||
const (
|
||||
TokenCacheTTL = 5 * time.Minute
|
||||
UserCacheTTL = 5 * time.Minute
|
||||
)
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package consts defines constants, keys, and TTL values for the auth domain plugin.
|
||||
package consts
|
||||
|
||||
// OAuth and Auth error messages
|
||||
const (
|
||||
ErrInvalidState = "非法登录请求"
|
||||
ErrIDTokenVerifyFailed = "ID Token 验证失败" //nolint:gosec // error message constant
|
||||
ErrIDTokenVerifyFailedFormat = "%s: %w"
|
||||
ErrNonceMismatch = "nonce 不匹配,可能存在重放攻击"
|
||||
ErrNoActiveAuthSource = "未配置可用认证源"
|
||||
ErrServerAddressMissing = "服务器地址 (server_address) 未配置或配置为空,请在后台系统设置中配置后再试"
|
||||
ErrAuthSourceRequired = "认证源不能为空"
|
||||
ErrDiscoveryURLRequired = "OIDC 认证源必须配置 Discovery URL"
|
||||
ErrUsernameGenerateFailed = "无法生成可用用户名"
|
||||
ErrUsernameFromSourceFailed = "无法从认证源获取用户名"
|
||||
ErrAuthSourceDisabled = "认证源未启用"
|
||||
ErrInvalidExternalAccountBindingID = "绑定记录 ID 无效"
|
||||
ErrTokenAuthNotAllowed = "该端点不允许使用访问令牌进行身份验证" //nolint:gosec // error message constant
|
||||
ErrOAuthStateRateLimited = "请求授权过于频繁,请稍后重试"
|
||||
ErrAuthSourceNameRequired = "认证源名称不能为空"
|
||||
ErrAuthSourceNameInvalid = "认证源名称格式不正确"
|
||||
ErrAuthSourceTypeUnsupported = "不支持的认证源类型"
|
||||
ErrAuthSourceDiscoveryURLRequired = "Discovery URL 不能为空"
|
||||
//nolint:gosec // error message constant
|
||||
ErrAuthSourceClientCredentialsRequired = "启用认证源时必须配置 Client ID 和 Client Secret"
|
||||
ErrAuthSourceIDRequired = "认证源 ID 不能为空"
|
||||
ErrUserIDRequired = "用户 ID 不能为空"
|
||||
ErrExternalAccountBindingIncomplete = "外部帐号绑定信息不完整"
|
||||
ErrExternalAccountAlreadyBoundToAnother = "该外部帐号已被其他用户绑定"
|
||||
ErrExternalAccountBindingIDRequired = "外部帐号绑定记录 ID 不能为空"
|
||||
ErrInsufficientPermission = "权限不足"
|
||||
ErrBannedAccount = "账号已被封禁"
|
||||
ErrUnAuthorized = "未登录"
|
||||
)
|
||||
|
||||
// Service 层与鉴权中间件内部错误文案
|
||||
const (
|
||||
ErrUserNotInContext = "auth: user not found in context"
|
||||
ErrEmptyToken = "auth: empty token" //nolint:gosec // error message constant
|
||||
ErrSystemUserTokenNotAllowed = "auth: system user token not allowed" //nolint:gosec // error message constant
|
||||
ErrUnauthorizedInternal = "unauthorized"
|
||||
ErrSystemUserLoginNotAllowed = "system user is not allowed to login"
|
||||
)
|
||||
|
||||
// OAuth 回调会话校验错误文案
|
||||
const (
|
||||
ErrInvalidSessionContext = "invalid session context"
|
||||
ErrSessionMismatchForOAuth = "session mismatch for oauth state"
|
||||
ErrUserContextMismatch = "user context mismatch for oauth binding"
|
||||
)
|
||||
Reference in New Issue
Block a user