-
Notifications
You must be signed in to change notification settings - Fork 63
Expand file tree
/
Copy patherrors.go
More file actions
98 lines (84 loc) · 2.54 KB
/
Copy patherrors.go
File metadata and controls
98 lines (84 loc) · 2.54 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package main
import (
"fmt"
"log"
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
func respondError(c *gin.Context, code int, publicMsg string, internalErr error) {
correlationID := responseCorrelationID(c)
if internalErr != nil {
log.Printf(
"[ERROR] correlation_id=%s status=%d error=%s internal=%v",
correlationID,
code,
publicMsg,
internalErr,
)
}
c.JSON(code, gin.H{
"error": publicMsg,
"correlation_id": correlationID,
})
}
func respondVerificationFailure(c *gin.Context, verifyResp *VerifyResponse) {
if verifyResp == nil {
respondError(c, http.StatusBadGateway, "verification_unavailable", fmt.Errorf("missing verifier response"))
return
}
internalErr := fmt.Errorf("verifier rejected payment: code=%s error=%s", verifyResp.ErrorCode, verifyResp.Error)
code, publicMsg := verifierFailureResponse(verifyResp)
respondError(c, code, publicMsg, internalErr)
}
func verifierFailureResponse(verifyResp *VerifyResponse) (int, string) {
switch verifyResp.ErrorCode {
case "chain_id_mismatch":
return http.StatusBadRequest, "chain_id_mismatch"
case "nonce_already_used":
return http.StatusConflict, "nonce_already_used"
case "timestamp_expired", "timestamp_future", "timestamp_missing":
return http.StatusBadRequest, "invalid_timestamp"
case "invalid_signature":
return http.StatusForbidden, "invalid_signature"
}
// Backward compatibility for older verifier responses without error_code.
if strings.HasPrefix(verifyResp.Error, "E007") ||
strings.HasPrefix(verifyResp.Error, "E008") ||
strings.HasPrefix(verifyResp.Error, "E009") {
return http.StatusBadRequest, "invalid_timestamp"
}
return http.StatusForbidden, "invalid_signature"
}
func isVerifierBusinessRejection(verifyResp *VerifyResponse) bool {
if verifyResp == nil {
return false
}
switch verifyResp.ErrorCode {
case "chain_id_mismatch",
"nonce_already_used",
"timestamp_expired",
"timestamp_future",
"timestamp_missing",
"invalid_signature":
return true
default:
return false
}
}
func responseCorrelationID(c *gin.Context) string {
if value, exists := c.Get("correlation_id"); exists {
if correlationID, ok := value.(string); ok && correlationID != "" {
return safeCorrelationID(correlationID)
}
}
if c.Request != nil {
if correlationID, ok := c.Request.Context().Value(CorrelationIDKey).(string); ok && correlationID != "" {
return safeCorrelationID(correlationID)
}
if correlationID := c.GetHeader("X-Correlation-ID"); correlationID != "" {
return safeCorrelationID(correlationID)
}
}
return "unknown"
}