优化结构
This commit is contained in:
@@ -210,7 +210,7 @@ func (h *Dictionary) Details(c *gin.Context) {
|
||||
func (h *Dictionary) Tree(byType bool) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
rawID := c.Query("sysDictionaryID")
|
||||
id, parseErr := strconv.ParseUint(rawID, 10, 32)
|
||||
var id uint64
|
||||
typ := ""
|
||||
if byType {
|
||||
typ = c.Query("type")
|
||||
@@ -221,9 +221,13 @@ func (h *Dictionary) Tree(byType bool) gin.HandlerFunc {
|
||||
} else if rawID == "" {
|
||||
Fail(c, "字典ID不能为空")
|
||||
return
|
||||
} else if parseErr != nil {
|
||||
Fail(c, "字典ID格式错误")
|
||||
return
|
||||
} else {
|
||||
var parseErr error
|
||||
id, parseErr = strconv.ParseUint(rawID, 10, 32)
|
||||
if parseErr != nil {
|
||||
Fail(c, "字典ID格式错误")
|
||||
return
|
||||
}
|
||||
}
|
||||
items, err := h.service.DictionaryTree(c.Request.Context(), uint(id), typ)
|
||||
if err != nil {
|
||||
|
||||
@@ -27,29 +27,20 @@ func NewPublic(auth *systemservice.AuthService, system *systemservice.SystemConf
|
||||
return &Public{auth: auth, system: system, settings: settings, store: &captchaStore{service: settings}}
|
||||
}
|
||||
|
||||
func (h *Public) captchaConfig() (int, int, int) {
|
||||
config := h.settings.CaptchaSettings()
|
||||
return config.KeyLong, config.ImageWidth, config.ImageHeight
|
||||
}
|
||||
|
||||
func (h *Public) Captcha(c *gin.Context) {
|
||||
keyLong, width, height := h.captchaConfig()
|
||||
security, err := h.settings.CurrentSecurity(c.Request.Context())
|
||||
if err != nil || security == nil {
|
||||
Fail(c, "安全服务暂不可用")
|
||||
return
|
||||
}
|
||||
openCaptcha := true
|
||||
if security != nil {
|
||||
keyLong, width, height = security.KeyLong, security.ImgWidth, security.ImgHeight
|
||||
ttl := time.Duration(security.CaptchaTimeout) * time.Second
|
||||
failures, counterErr := h.settings.EnsureLoginIPCounter(c.Request.Context(), c.ClientIP(), ttl)
|
||||
if counterErr != nil {
|
||||
Fail(c, "安全服务暂不可用")
|
||||
return
|
||||
}
|
||||
openCaptcha = security.CaptchaOpen == 0 || failures > security.CaptchaOpen
|
||||
keyLong, width, height := security.KeyLong, security.ImgWidth, security.ImgHeight
|
||||
ttl := time.Duration(security.CaptchaTimeout) * time.Second
|
||||
failures, counterErr := h.settings.EnsureLoginIPCounter(c.Request.Context(), c.ClientIP(), ttl)
|
||||
if counterErr != nil {
|
||||
Fail(c, "安全服务暂不可用")
|
||||
return
|
||||
}
|
||||
openCaptcha := security.CaptchaOpen == 0 || failures > security.CaptchaOpen
|
||||
driver := base64Captcha.NewDriverDigit(height, width, keyLong, 0.7, 80)
|
||||
id, picture, _, err := base64Captcha.NewCaptcha(driver, h.store).Generate()
|
||||
if err != nil {
|
||||
|
||||
@@ -81,7 +81,7 @@ func (h *SystemConfig) Reload(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *SystemConfig) ServerInfo(c *gin.Context) {
|
||||
server, err := h.system.ServerInfo()
|
||||
server, err := h.system.ServerInfo(c.Request.Context())
|
||||
if err != nil {
|
||||
Fail(c, "获取失败")
|
||||
return
|
||||
|
||||
@@ -87,8 +87,22 @@ func OperationAudit(runtime *config.Store, recorder *systemservice.AuditRecorder
|
||||
responseBody = "[超出记录长度]"
|
||||
}
|
||||
errorMessage := c.Errors.ByType(gin.ErrorTypePrivate).String()
|
||||
operationBody := operationRequestBody(requestBody, c.GetHeader("Content-Type"), maxBytes)
|
||||
if routecatalog.BodyPolicyFor(c.Request.Method, path) == routecatalog.BodyPolicyPaymentConfig {
|
||||
operationBody := ""
|
||||
capturedBody := false
|
||||
if c.Request.Method != http.MethodGet {
|
||||
if value, ok := c.Get(ctxReqBodyKey); ok {
|
||||
// AccessLog has already captured, redacted, summarized, and bounded the
|
||||
// request body. Treat that value as final so audit does not process it a
|
||||
// second time.
|
||||
operationBody = stringValue(value)
|
||||
capturedBody = true
|
||||
} else {
|
||||
operationBody = operationRequestBody(requestBody, c.GetHeader("Content-Type"), maxBytes)
|
||||
}
|
||||
} else {
|
||||
operationBody = operationRequestBody(requestBody, c.GetHeader("Content-Type"), maxBytes)
|
||||
}
|
||||
if !capturedBody && routecatalog.BodyPolicyFor(c.Request.Method, path) == routecatalog.BodyPolicyPaymentConfig {
|
||||
operationBody = paymentConfigSummary(requestBody)
|
||||
}
|
||||
if err := recorder.RecordOperationRequest(c.Request.Context(), &dto.OperationRecordRequest{IP: c.ClientIP(), Method: c.Request.Method, Path: path, Status: status, LatencyMS: time.Since(started).Milliseconds(), Agent: c.Request.UserAgent(), ErrorMessage: errorMessage, Body: operationBody, Response: responseBody, UserID: userID, RequestID: stringValue(requestID), TraceID: stringValueFromContext(c, "trace_id"), DeviceID: c.GetHeader("X-Device-Id")}); err != nil {
|
||||
@@ -105,7 +119,11 @@ func operationQueryBody(raw string) []byte {
|
||||
values := make(map[string]string, len(parsed))
|
||||
for key, items := range parsed {
|
||||
if len(items) > 0 {
|
||||
values[key] = items[len(items)-1]
|
||||
value := items[len(items)-1]
|
||||
if isSensitivePayloadKey(key) {
|
||||
value = redactedValue
|
||||
}
|
||||
values[key] = value
|
||||
}
|
||||
}
|
||||
body, _ := json.Marshal(&values)
|
||||
|
||||
@@ -23,6 +23,16 @@ func TestOperationQueryBodyPreservesEncodedSeparators(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperationQueryBodyRedactsSensitiveValues(t *testing.T) {
|
||||
var values map[string]string
|
||||
if err := json.Unmarshal(operationQueryBody("token=secret-token&name=alice"), &values); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if values["token"] != redactedValue || values["name"] != "alice" {
|
||||
t.Fatalf("unexpected redacted query body: %#v", values)
|
||||
}
|
||||
}
|
||||
|
||||
func runErrorAudit(t *testing.T, path, response string, logger *slog.Logger) {
|
||||
t.Helper()
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
Reference in New Issue
Block a user