forked from QuantumNous/new-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecure_verification.go
More file actions
60 lines (55 loc) · 1.84 KB
/
Copy pathsecure_verification.go
File metadata and controls
60 lines (55 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package middleware
import (
"errors"
"net/http"
"strings"
"github.com/QuantumNous/new-api/service"
"github.com/gin-gonic/gin"
)
// SecureVerificationRequired protects channel key disclosure. Other sensitive
// operations validate their narrower proof scopes in their controller.
func SecureVerificationRequired() gin.HandlerFunc {
return func(c *gin.Context) {
if !RequireSecurityProof(c, "channel.key.read", []string{"2fa", "passkey"}) {
return
}
c.Set("secure_verified", true)
c.Next()
}
}
// RequireSecurityProof validates a proof against the authenticated dashboard
// session and writes the shared proof error contract on failure.
func RequireSecurityProof(c *gin.Context, requiredScope string, allowedMethods []string) bool {
identity, ok := GetSessionAuthIdentity(c)
if !ok {
securityProofError(c, "SECURITY_PROOF_INVALID", "安全验证状态无效")
return false
}
raw := strings.TrimSpace(c.GetHeader("X-Security-Proof"))
if raw == "" {
securityProofError(c, "SECURITY_PROOF_REQUIRED", "需要安全验证")
return false
}
if _, err := service.VerifySecurityProof(raw, identity, requiredScope, allowedMethods); err != nil {
switch {
case errors.Is(err, service.ErrAuthTokenExpired):
securityProofError(c, "SECURITY_PROOF_EXPIRED", "安全验证已过期")
case errors.Is(err, service.ErrProofScope):
securityProofError(c, "SECURITY_PROOF_SCOPE_MISMATCH", "安全验证范围不匹配")
case errors.Is(err, service.ErrProofMethod):
securityProofError(c, "SECURITY_PROOF_METHOD_MISMATCH", "安全验证方式不匹配")
default:
securityProofError(c, "SECURITY_PROOF_INVALID", "安全验证状态无效")
}
return false
}
return true
}
func securityProofError(c *gin.Context, code, message string) {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": message,
"code": code,
})
c.Abort()
}