in internal/controller/question_controller.go [384:487]
func (qc *QuestionController) AddQuestion(ctx *gin.Context) {
req := &schema.QuestionAdd{}
errFields := handler.BindAndCheckReturnErr(ctx, req)
if ctx.IsAborted() {
return
}
reject, rejectKey := qc.rateLimitMiddleware.DuplicateRequestRejection(ctx, req)
if reject {
return
}
defer func() {
// If status is not 200 means that the bad request has been returned, so the record should be cleared
if ctx.Writer.Status() != http.StatusOK {
qc.rateLimitMiddleware.DuplicateRequestClear(ctx, rejectKey)
}
}()
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
canList, requireRanks, err := qc.rankService.CheckOperationPermissionsForRanks(ctx, req.UserID, []string{
permission.QuestionAdd,
permission.QuestionEdit,
permission.QuestionDelete,
permission.QuestionClose,
permission.QuestionReopen,
permission.TagUseReservedTag,
permission.TagAdd,
permission.LinkUrlLimit,
})
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
}
linkUrlLimitUser := canList[7]
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin || !linkUrlLimitUser {
captchaPass := qc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionQuestion, req.UserID, req.CaptchaID, req.CaptchaCode)
if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code",
ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
})
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return
}
}
req.CanAdd = canList[0]
req.CanEdit = canList[1]
req.CanDelete = canList[2]
req.CanClose = canList[3]
req.CanReopen = canList[4]
req.CanUseReservedTag = canList[5]
req.CanAddTag = canList[6]
if !req.CanAdd {
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
return
}
// can add tag
hasNewTag, err := qc.questionService.HasNewTag(ctx, req.Tags)
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
}
if !req.CanAddTag && hasNewTag {
lang := handler.GetLang(ctx)
msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[6]})
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
}
errList, err := qc.questionService.CheckAddQuestion(ctx, req)
if err != nil {
errlist, ok := errList.([]*validator.FormErrorField)
if ok {
errFields = append(errFields, errlist...)
}
}
if len(errFields) > 0 {
handler.HandleResponse(ctx, errors.BadRequest(reason.RequestFormatError), errFields)
return
}
req.UserAgent = ctx.GetHeader("User-Agent")
req.IP = ctx.ClientIP()
resp, err := qc.questionService.AddQuestion(ctx, req)
if err != nil {
errlist, ok := resp.([]*validator.FormErrorField)
if ok {
errFields = append(errFields, errlist...)
}
}
if len(errFields) > 0 {
handler.HandleResponse(ctx, errors.BadRequest(reason.RequestFormatError), errFields)
return
}
if !isAdmin || !linkUrlLimitUser {
qc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionQuestion, req.UserID)
}
handler.HandleResponse(ctx, err, resp)
}