fix device decrypt flow and delete_account response stability
Build docker and publish / build (20.15.1) (push) Failing after 8m0s
Build docker and publish / build (20.15.1) (push) Failing after 8m0s
This commit is contained in:
@@ -24,17 +24,28 @@ import (
|
||||
const (
|
||||
noWritten = -1
|
||||
defaultStatus = http.StatusOK
|
||||
|
||||
ctxDeviceDecryptStatusKey = "device_decrypt_status"
|
||||
ctxDeviceDecryptReasonKey = "device_decrypt_reason"
|
||||
ctxEncryptedQueryKey = "encrypted_query"
|
||||
ctxDecryptedQueryKey = "decrypted_query"
|
||||
ctxEncryptedBodyKey = "encrypted_request_body"
|
||||
ctxDecryptedBodyKey = "decrypted_request_body"
|
||||
)
|
||||
|
||||
func DeviceMiddleware(srvCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||
return func(c *gin.Context) {
|
||||
|
||||
if !srvCtx.Config.Device.Enable {
|
||||
c.Set(ctxDeviceDecryptStatusKey, "skipped")
|
||||
c.Set(ctxDeviceDecryptReasonKey, "device_encryption_disabled")
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
if srvCtx.Config.Device.SecuritySecret == "" {
|
||||
c.Set(ctxDeviceDecryptStatusKey, "failed")
|
||||
c.Set(ctxDeviceDecryptReasonKey, "device_secret_empty")
|
||||
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.SecretIsEmpty), "Secret is empty"))
|
||||
c.Abort()
|
||||
return
|
||||
@@ -48,12 +59,22 @@ func DeviceMiddleware(srvCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||
|
||||
loginType, ok := ctx.Value(constant.CtxLoginType).(string)
|
||||
if !ok || loginType != "device" {
|
||||
c.Set(ctxDeviceDecryptStatusKey, "skipped")
|
||||
if ok {
|
||||
c.Set(ctxDeviceDecryptReasonKey, fmt.Sprintf("login_type_%s_not_device", loginType))
|
||||
} else {
|
||||
c.Set(ctxDeviceDecryptReasonKey, "login_type_not_found")
|
||||
}
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
rw := NewResponseWriter(c, srvCtx)
|
||||
if !rw.Decrypt() {
|
||||
c.Set(ctxDeviceDecryptStatusKey, "failed")
|
||||
if _, exists := c.Get(ctxDeviceDecryptReasonKey); !exists {
|
||||
c.Set(ctxDeviceDecryptReasonKey, "decrypt_failed")
|
||||
}
|
||||
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidCiphertext), "Invalid ciphertext"))
|
||||
c.Abort()
|
||||
return
|
||||
@@ -112,13 +133,21 @@ func (rw *ResponseWriter) Encrypt() {
|
||||
|
||||
func (rw *ResponseWriter) Decrypt() bool {
|
||||
if !rw.encryption {
|
||||
rw.c.Set(ctxDeviceDecryptStatusKey, "skipped")
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, "response_encryption_disabled")
|
||||
return true
|
||||
}
|
||||
|
||||
//判断url链接中是否存在data和iv数据,存在就进行解密并设置回去
|
||||
query := rw.c.Request.URL.Query()
|
||||
originalRawQuery := rw.c.Request.URL.RawQuery
|
||||
dataStr := query.Get("data")
|
||||
timeStr := query.Get("time")
|
||||
hasEncryptedQuery := dataStr != "" && timeStr != ""
|
||||
queryDecrypted := false
|
||||
if hasEncryptedQuery {
|
||||
rw.c.Set(ctxEncryptedQueryKey, originalRawQuery)
|
||||
}
|
||||
if dataStr != "" && timeStr != "" {
|
||||
decrypt, err := pkgaes.Decrypt(dataStr, rw.encryptionKey, timeStr)
|
||||
if err == nil {
|
||||
@@ -132,42 +161,73 @@ func (rw *ResponseWriter) Decrypt() bool {
|
||||
query.Del("time")
|
||||
rw.c.Request.RequestURI = fmt.Sprintf("%s?%s", rw.c.Request.RequestURI[:strings.Index(rw.c.Request.RequestURI, "?")], query.Encode())
|
||||
rw.c.Request.URL.RawQuery = query.Encode()
|
||||
rw.c.Set(ctxDecryptedQueryKey, query.Encode())
|
||||
queryDecrypted = true
|
||||
}
|
||||
} else {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, fmt.Sprintf("query_decrypt_failed:%v", err))
|
||||
}
|
||||
}
|
||||
|
||||
//判断body是否存在数据,存在就尝试解密,并设置回去
|
||||
body, err := io.ReadAll(rw.c.Request.Body)
|
||||
if err != nil {
|
||||
if queryDecrypted {
|
||||
rw.c.Set(ctxDeviceDecryptStatusKey, "success")
|
||||
} else {
|
||||
rw.c.Set(ctxDeviceDecryptStatusKey, "skipped")
|
||||
}
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, fmt.Sprintf("read_body_failed:%v", err))
|
||||
return true
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
if queryDecrypted {
|
||||
rw.c.Set(ctxDeviceDecryptStatusKey, "success")
|
||||
} else {
|
||||
rw.c.Set(ctxDeviceDecryptStatusKey, "skipped")
|
||||
if hasEncryptedQuery {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, "query_decrypt_failed")
|
||||
} else {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, "empty_body")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
rw.c.Set(ctxEncryptedBodyKey, string(body))
|
||||
|
||||
params := map[string]interface{}{}
|
||||
err = json.Unmarshal(body, ¶ms)
|
||||
data := params["data"]
|
||||
nonce := params["time"]
|
||||
if err != nil || data == nil {
|
||||
if err != nil {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, fmt.Sprintf("body_unmarshal_failed:%v", err))
|
||||
} else {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, "body_data_field_missing")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
str, ok := data.(string)
|
||||
if !ok {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, "body_data_not_string")
|
||||
return false
|
||||
}
|
||||
iv, ok := nonce.(string)
|
||||
if !ok {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, "body_time_not_string")
|
||||
return false
|
||||
}
|
||||
|
||||
decrypt, err := pkgaes.Decrypt(str, rw.encryptionKey, iv)
|
||||
if err != nil {
|
||||
rw.c.Set(ctxDeviceDecryptReasonKey, fmt.Sprintf("body_decrypt_failed:%v", err))
|
||||
return false
|
||||
}
|
||||
rw.c.Request.Body = io.NopCloser(bytes.NewBuffer([]byte(decrypt)))
|
||||
rw.c.Set(ctxDecryptedBodyKey, decrypt)
|
||||
rw.c.Set(ctxDeviceDecryptStatusKey, "success")
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user