Skip to content

Commit

Permalink
Merge pull request #1782 from winfredLIN/fix-issue1758
Browse files Browse the repository at this point in the history
fix-issue1758: create audit plan failed
  • Loading branch information
ColdWaterLW authored Sep 7, 2023
2 parents 9e4e38c + 0ed270d commit f8d8833
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
6 changes: 4 additions & 2 deletions sqle/api/controller/v1/audit_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,11 @@ func CreateAuditPlan(c echo.Context) error {
}

// generate token
// 为了控制JWT Token的长度,保证其长度不超过数据表定义的长度上限(255字符)
// 因此使用MD5算法将变长的 currentUserName 和 Name 转换为固定长度
j := utils.NewJWT(utils.JWTSecretKey)
t, err := j.CreateToken(currentUserName, time.Now().Add(tokenExpire).Unix(),
utils.WithAuditPlanName(req.Name))
t, err := j.CreateToken(utils.Md5(currentUserName), time.Now().Add(tokenExpire).Unix(),
utils.WithAuditPlanName(utils.Md5(req.Name)))
if err != nil {
return controller.JSONBaseErrorReq(c, errors.New(errors.DataConflict, err))
}
Expand Down
4 changes: 3 additions & 1 deletion sqle/api/middleware/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ func ScannerVerifier() echo.MiddlewareFunc {
}
projectName := c.Param("project_name")
apnInParam := c.Param("audit_plan_name")
if apnInToken != apnInParam {
// 由于对生成的JWT Token的负载使用MD5算法进行预处理,因此在验证的时候也需要对param中的apn使用MD5处理
// 为了兼容老版本的JWT Token需要增加不经MD5处理的apnInParam和apnInToken的判断
if apnInToken != apnInParam && apnInToken != utils.Md5(apnInParam) {
return echo.NewHTTPError(http.StatusInternalServerError, errAuditPlanMisMatch.Error())
}

Expand Down
78 changes: 78 additions & 0 deletions sqle/api/middleware/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,81 @@ func TestScannerVerifier(t *testing.T) {
assert.NoError(t, err)
}
}

func TestScannerVerifierIssue1758(t *testing.T) {
e := echo.New()

jwt := utils.NewJWT(utils.JWTSecretKey)
apName120 := "aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbb120"
projectName := "default"
userName := "admin"
assert.Equal(t, 120, len(apName120))
h := func(c echo.Context) error {
return c.HTML(http.StatusOK, "hello, world")
}

mw := ScannerVerifier()
newContextFunc := func(token, apName string) (echo.Context, *httptest.ResponseRecorder) {
req := httptest.NewRequest(http.MethodGet, "/:audit_plan_name/", nil)
req.Header.Set(echo.HeaderAuthorization, token)
res := httptest.NewRecorder()
ctx := e.NewContext(req, res)
ctx.SetParamNames("audit_plan_name", "project_name")
ctx.SetParamValues(apName, projectName)
return ctx, res
}
{ // test check success
token, err := jwt.CreateToken(utils.Md5(userName), time.Now().Add(1*time.Hour).Unix(), utils.WithAuditPlanName(utils.Md5(apName120)))
assert.NoError(t, err)

mockDB, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
assert.NoError(t, err)
model.InitMockStorage(mockDB)
mock.ExpectQuery("SELECT `audit_plans`.* FROM `audit_plans` LEFT JOIN projects ON projects.id = audit_plans.project_id WHERE `audit_plans`.`deleted_at` IS NULL AND ((projects.name = ? AND audit_plans.name = ?))").
WithArgs(projectName, apName120).
WillReturnRows(sqlmock.NewRows([]string{"name", "token"}).AddRow(userName, token))
mock.ExpectClose()

ctx, res := newContextFunc(token, apName120) //这里模拟上下文不需要哈希
err = mw(h)(ctx)
assert.NoError(t, err)
assert.Contains(t, res.Body.String(), "hello, world")

mockDB.Close()
err = mock.ExpectationsWereMet()
assert.NoError(t, err)
}
{ // test audit plan name don't match the token
token, err := jwt.CreateToken(utils.Md5(userName), time.Now().Add(1*time.Hour).Unix(), utils.WithAuditPlanName(utils.Md5(apName120)))
assert.NoError(t, err)
ctx, _ := newContextFunc(token, fmt.Sprintf("%s_modified", apName120))
err = mw(h)(ctx)
assert.Contains(t, err.Error(), errAuditPlanMisMatch.Error())
}
{ // test unknown token
token, err := jwt.CreateToken(utils.Md5(userName), time.Now().Add(1*time.Hour).Unix())
assert.NoError(t, err)
ctx, _ := newContextFunc(token, apName120)
err = mw(h)(ctx)
assert.Contains(t, err.Error(), "unknown token")
}
{ // test old token
token, err := jwt.CreateToken(userName, time.Now().Add(1*time.Hour).Unix(), utils.WithAuditPlanName(apName120))
assert.NoError(t, err)
mockDB, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
assert.NoError(t, err)
model.InitMockStorage(mockDB)
mock.ExpectQuery("SELECT `audit_plans`.* FROM `audit_plans` LEFT JOIN projects ON projects.id = audit_plans.project_id WHERE `audit_plans`.`deleted_at` IS NULL AND ((projects.name = ? AND audit_plans.name = ?))").
WithArgs(projectName, apName120).
WillReturnRows(sqlmock.NewRows([]string{"name", "token"}).AddRow(userName, token))
mock.ExpectClose()

ctx, _ := newContextFunc(token, apName120)
err = mw(h)(ctx)
assert.NoError(t, err)

mockDB.Close()
err = mock.ExpectationsWereMet()
assert.NoError(t, err)
}
}

0 comments on commit f8d8833

Please sign in to comment.