Merge branch 'feat/1.1.1/ai' into test

This commit is contained in:
aichy 2023-07-24 10:45:24 +08:00
commit 7bb7f84432
28 changed files with 865 additions and 223 deletions

View File

@ -149,13 +149,13 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService)
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService)
commentController := controller.NewCommentController(commentService, rankService)
commentController := controller.NewCommentController(commentService, rankService, captchaService)
reportRepo := report.NewReportRepo(dataData, uniqueIDRepo)
reportService := report2.NewReportService(reportRepo, objService)
reportController := controller.NewReportController(reportService, rankService)
reportController := controller.NewReportController(reportService, rankService, captchaService)
serviceVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, notificationQueueService)
voteService := service.NewVoteService(serviceVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService)
voteController := controller.NewVoteController(voteService, rankService)
voteController := controller.NewVoteController(voteService, rankService, captchaService)
followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo)
tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, activityQueueService)
tagController := controller.NewTagController(tagService, tagCommonService, rankService)
@ -175,12 +175,12 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService)
questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, revisionService, metaService, collectionCommon, answerActivityService, emailService, notificationQueueService, activityQueueService, siteInfoCommonService)
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, activityQueueService)
questionController := controller.NewQuestionController(questionService, answerService, rankService, siteInfoCommonService)
answerController := controller.NewAnswerController(answerService, rankService)
questionController := controller.NewQuestionController(questionService, answerService, rankService, siteInfoCommonService, captchaService)
answerController := controller.NewAnswerController(answerService, rankService, captchaService)
searchParser := search_parser.NewSearchParser(tagCommonService, userCommon)
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
searchService := service.NewSearchService(searchParser, searchRepo)
searchController := controller.NewSearchController(searchService)
searchController := controller.NewSearchController(searchService, captchaService)
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, notificationQueueService, activityQueueService)
revisionController := controller.NewRevisionController(serviceRevisionService, rankService)
rankController := controller.NewRankController(rankService)

View File

@ -1,5 +1,5 @@
// Package docs GENERATED BY SWAG; DO NOT EDIT
// This file was generated by swaggo/swag
// Code generated by swaggo/swag. DO NOT EDIT.
package docs
import "github.com/swaggo/swag"
@ -7165,7 +7165,7 @@ const docTemplate = `{
}
},
"selected_level": {
"type": "integer"
"$ref": "#/definitions/schema.PrivilegeLevel"
}
}
},
@ -7664,11 +7664,24 @@ const docTemplate = `{
}
}
},
"schema.PrivilegeLevel": {
"type": "integer",
"enum": [
1,
2,
3
],
"x-enum-varnames": [
"PrivilegeLevel1",
"PrivilegeLevel2",
"PrivilegeLevel3"
]
},
"schema.PrivilegeOption": {
"type": "object",
"properties": {
"level": {
"type": "integer"
"$ref": "#/definitions/schema.PrivilegeLevel"
},
"level_desc": {
"type": "string"
@ -7754,11 +7767,11 @@ const docTemplate = `{
"schema.QuestionPageReq": {
"type": "object",
"properties": {
"inDays": {
"in_days": {
"type": "integer",
"minimum": 1
},
"orderCond": {
"order": {
"type": "string",
"enum": [
"newest",
@ -7772,7 +7785,7 @@ const docTemplate = `{
"type": "integer",
"minimum": 1
},
"pageSize": {
"page_size": {
"type": "integer",
"minimum": 1
},
@ -8083,7 +8096,11 @@ const docTemplate = `{
},
"user_info": {
"description": "user info",
"$ref": "#/definitions/schema.UserBasicInfo"
"allOf": [
{
"$ref": "#/definitions/schema.UserBasicInfo"
}
]
},
"vote_count": {
"type": "integer"
@ -8095,7 +8112,11 @@ const docTemplate = `{
"properties": {
"object": {
"description": "this object",
"$ref": "#/definitions/schema.SearchObject"
"allOf": [
{
"$ref": "#/definitions/schema.SearchObject"
}
]
},
"object_type": {
"description": "object_type",
@ -8737,7 +8758,11 @@ const docTemplate = `{
"properties": {
"avatar": {
"description": "avatar",
"$ref": "#/definitions/schema.AvatarInfo"
"allOf": [
{
"$ref": "#/definitions/schema.AvatarInfo"
}
]
},
"bio": {
"description": "bio",
@ -8804,9 +8829,13 @@ const docTemplate = `{
],
"properties": {
"level": {
"type": "integer",
"maximum": 3,
"minimum": 1
"minimum": 1,
"allOf": [
{
"$ref": "#/definitions/schema.PrivilegeLevel"
}
]
}
}
},
@ -9414,6 +9443,8 @@ var SwaggerInfo = &swag.Spec{
Description: "",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {

View File

@ -7153,7 +7153,7 @@
}
},
"selected_level": {
"type": "integer"
"$ref": "#/definitions/schema.PrivilegeLevel"
}
}
},
@ -7652,11 +7652,24 @@
}
}
},
"schema.PrivilegeLevel": {
"type": "integer",
"enum": [
1,
2,
3
],
"x-enum-varnames": [
"PrivilegeLevel1",
"PrivilegeLevel2",
"PrivilegeLevel3"
]
},
"schema.PrivilegeOption": {
"type": "object",
"properties": {
"level": {
"type": "integer"
"$ref": "#/definitions/schema.PrivilegeLevel"
},
"level_desc": {
"type": "string"
@ -7742,11 +7755,11 @@
"schema.QuestionPageReq": {
"type": "object",
"properties": {
"inDays": {
"in_days": {
"type": "integer",
"minimum": 1
},
"orderCond": {
"order": {
"type": "string",
"enum": [
"newest",
@ -7760,7 +7773,7 @@
"type": "integer",
"minimum": 1
},
"pageSize": {
"page_size": {
"type": "integer",
"minimum": 1
},
@ -8071,7 +8084,11 @@
},
"user_info": {
"description": "user info",
"$ref": "#/definitions/schema.UserBasicInfo"
"allOf": [
{
"$ref": "#/definitions/schema.UserBasicInfo"
}
]
},
"vote_count": {
"type": "integer"
@ -8083,7 +8100,11 @@
"properties": {
"object": {
"description": "this object",
"$ref": "#/definitions/schema.SearchObject"
"allOf": [
{
"$ref": "#/definitions/schema.SearchObject"
}
]
},
"object_type": {
"description": "object_type",
@ -8725,7 +8746,11 @@
"properties": {
"avatar": {
"description": "avatar",
"$ref": "#/definitions/schema.AvatarInfo"
"allOf": [
{
"$ref": "#/definitions/schema.AvatarInfo"
}
]
},
"bio": {
"description": "bio",
@ -8792,9 +8817,13 @@
],
"properties": {
"level": {
"type": "integer",
"maximum": 3,
"minimum": 1
"minimum": 1,
"allOf": [
{
"$ref": "#/definitions/schema.PrivilegeLevel"
}
]
}
}
},

View File

@ -730,7 +730,7 @@ definitions:
$ref: '#/definitions/schema.PrivilegeOption'
type: array
selected_level:
type: integer
$ref: '#/definitions/schema.PrivilegeLevel'
type: object
schema.GetRankPersonalPageResp:
properties:
@ -1081,10 +1081,20 @@ definitions:
content:
type: string
type: object
schema.PrivilegeLevel:
enum:
- 1
- 2
- 3
type: integer
x-enum-varnames:
- PrivilegeLevel1
- PrivilegeLevel2
- PrivilegeLevel3
schema.PrivilegeOption:
properties:
level:
type: integer
$ref: '#/definitions/schema.PrivilegeLevel'
level_desc:
type: string
privileges:
@ -1147,10 +1157,10 @@ definitions:
type: object
schema.QuestionPageReq:
properties:
inDays:
in_days:
minimum: 1
type: integer
orderCond:
order:
enum:
- newest
- active
@ -1161,7 +1171,7 @@ definitions:
page:
minimum: 1
type: integer
pageSize:
page_size:
minimum: 1
type: integer
tag:
@ -1374,7 +1384,8 @@ definitions:
title:
type: string
user_info:
$ref: '#/definitions/schema.UserBasicInfo'
allOf:
- $ref: '#/definitions/schema.UserBasicInfo'
description: user info
vote_count:
type: integer
@ -1382,7 +1393,8 @@ definitions:
schema.SearchResp:
properties:
object:
$ref: '#/definitions/schema.SearchObject'
allOf:
- $ref: '#/definitions/schema.SearchObject'
description: this object
object_type:
description: object_type
@ -1824,7 +1836,8 @@ definitions:
schema.UpdateInfoRequest:
properties:
avatar:
$ref: '#/definitions/schema.AvatarInfo'
allOf:
- $ref: '#/definitions/schema.AvatarInfo'
description: avatar
bio:
description: bio
@ -1871,9 +1884,10 @@ definitions:
schema.UpdatePrivilegesConfigReq:
properties:
level:
allOf:
- $ref: '#/definitions/schema.PrivilegeLevel'
maximum: 3
minimum: 1
type: integer
required:
- level
type: object

29
go.mod
View File

@ -36,14 +36,23 @@ require (
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20221018072427-a15dd1434e05
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20221018072427-a15dd1434e05
github.com/spf13/cobra v1.6.1
<<<<<<< HEAD
github.com/stretchr/testify v1.8.3
=======
github.com/stretchr/testify v1.8.4
>>>>>>> feat/1.1.1/ai
github.com/swaggo/files v1.0.0
github.com/swaggo/gin-swagger v1.5.3
github.com/swaggo/swag v1.8.10
github.com/swaggo/swag v1.16.1
github.com/tidwall/gjson v1.14.4
github.com/yuin/goldmark v1.4.13
<<<<<<< HEAD
golang.org/x/crypto v0.9.0
golang.org/x/net v0.10.0
=======
golang.org/x/crypto v0.11.0
golang.org/x/net v0.12.0
>>>>>>> feat/1.1.1/ai
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.14.2
@ -75,10 +84,10 @@ require (
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/spec v0.20.7 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/geo v0.0.0-20190812012225-f41920e961ce // indirect
@ -134,11 +143,11 @@ require (
go.uber.org/zap v1.23.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/image v0.1.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/tools v0.6.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/tools v0.11.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

54
go.sum
View File

@ -205,18 +205,23 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI=
github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -458,8 +463,8 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@ -696,9 +701,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
@ -707,8 +711,8 @@ github.com/swaggo/files v1.0.0/go.mod h1:N59U6URJLyU1PQgFqPM7wXLMhJx7QAolnvfQkqO
github.com/swaggo/gin-swagger v1.5.3 h1:8mWmHLolIbrhJJTflsaFoZzRBYVmEE7JZGIq08EiC0Q=
github.com/swaggo/gin-swagger v1.5.3/go.mod h1:3XJKSfHjDMB5dBo/0rrTXidPmgLeqsX89Yp4uA50HpI=
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
github.com/swaggo/swag v1.8.10 h1:eExW4bFa52WOjqRzRD58bgWsWfdFJso50lpbeTcmTfo=
github.com/swaggo/swag v1.8.10/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
@ -801,8 +805,9 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -842,8 +847,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -890,8 +895,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -913,7 +918,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -987,9 +992,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -1005,8 +1009,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1074,8 +1078,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -202,6 +202,21 @@ func GetUserInfoFromContext(ctx *gin.Context) (u *entity.UserCacheInfo) {
return u
}
func GetUserIsAdminModerator(ctx *gin.Context) (isAdminModerator bool) {
userInfo, exist := ctx.Get(ctxUUIDKey)
if !exist {
return false
}
u, ok := userInfo.(*entity.UserCacheInfo)
if !ok {
return false
}
if u.RoleID == role.RoleAdminID || u.RoleID == role.RoleModeratorID {
return true
}
return false
}
func GetLoginUserIDInt64FromContext(ctx *gin.Context) (userID int64) {
userIDStr := GetLoginUserIDFromContext(ctx)
return converter.StringToInt64(userIDStr)

View File

@ -6,8 +6,12 @@ import (
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/internal/service/action"
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/pkg/uid"
@ -19,15 +23,19 @@ import (
type AnswerController struct {
answerService *service.AnswerService
rankService *rank.RankService
actionService *action.CaptchaService
}
// NewAnswerController new controller
func NewAnswerController(answerService *service.AnswerService,
func NewAnswerController(
answerService *service.AnswerService,
rankService *rank.RankService,
actionService *action.CaptchaService,
) *AnswerController {
return &AnswerController{
answerService: answerService,
rankService: rankService,
actionService: actionService,
}
}
@ -48,6 +56,19 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) {
}
req.ID = uid.DeShortID(req.ID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := ac.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionDelete, 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
}
}
objectOwner := ac.rankService.CheckOperationObjectOwner(ctx, req.UserID, req.ID)
canList, err := ac.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.AnswerDelete,
@ -63,6 +84,9 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) {
}
err = ac.answerService.RemoveAnswer(ctx, req)
if !isAdmin {
ac.actionService.ActionRecordAdd(ctx, entity.CaptchaActionDelete, req.UserID)
}
handler.HandleResponse(ctx, err, nil)
}
@ -112,6 +136,18 @@ func (ac *AnswerController) Add(ctx *gin.Context) {
}
req.QuestionID = uid.DeShortID(req.QuestionID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := ac.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionAnswer, 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
}
}
can, err := ac.rankService.CheckOperationPermission(ctx, req.UserID, permission.AnswerAdd, "")
if err != nil {
@ -128,6 +164,9 @@ func (ac *AnswerController) Add(ctx *gin.Context) {
handler.HandleResponse(ctx, err, nil)
return
}
if !isAdmin {
ac.actionService.ActionRecordAdd(ctx, entity.CaptchaActionAnswer, req.UserID)
}
info, questionInfo, has, err := ac.answerService.Get(ctx, answerID, req.UserID)
if err != nil {
handler.HandleResponse(ctx, err, nil)
@ -178,6 +217,18 @@ func (ac *AnswerController) Update(ctx *gin.Context) {
}
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
req.QuestionID = uid.DeShortID(req.QuestionID)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := ac.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEdit, 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
}
}
canList, err := ac.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.AnswerEdit,
@ -201,6 +252,9 @@ func (ac *AnswerController) Update(ctx *gin.Context) {
handler.HandleResponse(ctx, err, nil)
return
}
if !isAdmin {
ac.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEdit, req.UserID)
}
_, _, _, err = ac.answerService.Get(ctx, req.ID, req.UserID)
if err != nil {
handler.HandleResponse(ctx, err, nil)

View File

@ -4,7 +4,11 @@ import (
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/action"
"github.com/answerdev/answer/internal/service/comment"
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
@ -17,13 +21,20 @@ import (
type CommentController struct {
commentService *comment.CommentService
rankService *rank.RankService
actionService *action.CaptchaService
}
// NewCommentController new controller
func NewCommentController(
commentService *comment.CommentService,
rankService *rank.RankService) *CommentController {
return &CommentController{commentService: commentService, rankService: rankService}
rankService *rank.RankService,
actionService *action.CaptchaService,
) *CommentController {
return &CommentController{
commentService: commentService,
rankService: rankService,
actionService: actionService,
}
}
// AddComment add comment
@ -43,6 +54,19 @@ func (cc *CommentController) AddComment(ctx *gin.Context) {
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := cc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionComment, 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
}
}
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.CommentAdd,
permission.CommentEdit,
@ -61,6 +85,9 @@ func (cc *CommentController) AddComment(ctx *gin.Context) {
}
resp, err := cc.commentService.AddComment(ctx, req)
if !isAdmin {
cc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionComment, req.UserID)
}
handler.HandleResponse(ctx, err, resp)
}
@ -81,6 +108,18 @@ func (cc *CommentController) RemoveComment(ctx *gin.Context) {
}
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := cc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionDelete, 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
}
}
can, err := cc.rankService.CheckOperationPermission(ctx, req.UserID, permission.CommentDelete, req.CommentID)
if err != nil {
handler.HandleResponse(ctx, err, nil)
@ -92,6 +131,9 @@ func (cc *CommentController) RemoveComment(ctx *gin.Context) {
}
err = cc.commentService.RemoveComment(ctx, req)
if !isAdmin {
cc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionDelete, req.UserID)
}
handler.HandleResponse(ctx, err, nil)
}
@ -113,6 +155,19 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) {
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := cc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEdit, 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
}
}
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.CommentAdd,
permission.CommentEdit,
@ -136,6 +191,9 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) {
}
resp, err := cc.commentService.UpdateComment(ctx, req)
if !isAdmin {
cc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEdit, req.UserID)
}
handler.HandleResponse(ctx, err, resp)
}

View File

@ -7,8 +7,10 @@ import (
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/internal/service/action"
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/internal/service/siteinfo_common"
@ -24,6 +26,7 @@ type QuestionController struct {
answerService *service.AnswerService
rankService *rank.RankService
siteInfoService siteinfo_common.SiteInfoCommonService
actionService *action.CaptchaService
}
// NewQuestionController new controller
@ -32,12 +35,14 @@ func NewQuestionController(
answerService *service.AnswerService,
rankService *rank.RankService,
siteInfoService siteinfo_common.SiteInfoCommonService,
actionService *action.CaptchaService,
) *QuestionController {
return &QuestionController{
questionService: questionService,
answerService: answerService,
rankService: rankService,
siteInfoService: siteInfoService,
actionService: actionService,
}
}
@ -59,6 +64,19 @@ func (qc *QuestionController) RemoveQuestion(ctx *gin.Context) {
req.ID = uid.DeShortID(req.ID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := qc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionDelete, 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
}
}
can, err := qc.rankService.CheckOperationPermission(ctx, req.UserID, permission.QuestionDelete, req.ID)
if err != nil {
handler.HandleResponse(ctx, err, nil)
@ -68,8 +86,10 @@ func (qc *QuestionController) RemoveQuestion(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
return
}
err = qc.questionService.RemoveQuestion(ctx, req)
if !isAdmin {
qc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionDelete, req.UserID)
}
handler.HandleResponse(ctx, err, nil)
}
@ -312,6 +332,19 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) {
}
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
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
}
}
canList, requireRanks, err := qc.rankService.CheckOperationPermissionsForRanks(ctx, req.UserID, []string{
permission.QuestionAdd,
permission.QuestionEdit,
@ -375,7 +408,9 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.BadRequest(reason.RequestFormatError), errFields)
return
}
if !isAdmin {
qc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionQuestion, req.UserID)
}
handler.HandleResponse(ctx, err, resp)
}
@ -500,6 +535,18 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) {
}
req.ID = uid.DeShortID(req.ID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := qc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEdit, 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
}
}
canList, requireRanks, err := qc.rankService.CheckOperationPermissionsForRanks(ctx, req.UserID, []string{
permission.QuestionEdit,
@ -552,6 +599,9 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) {
handler.HandleResponse(ctx, err, resp)
return
}
if !isAdmin {
qc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEdit, req.UserID)
}
handler.HandleResponse(ctx, nil, &schema.UpdateQuestionResp{WaitForReview: !req.NoNeedReview})
}
@ -573,6 +623,18 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) {
}
req.ID = uid.DeShortID(req.ID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := qc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionInvitationAnswer, 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
}
}
canList, err := qc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.AnswerInviteSomeoneToAnswer,
@ -597,6 +659,9 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) {
handler.HandleResponse(ctx, err, nil)
return
}
if !isAdmin {
qc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionInvitationAnswer, req.UserID)
}
handler.HandleResponse(ctx, nil, nil)
}

View File

@ -4,7 +4,11 @@ import (
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/action"
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/internal/service/report"
@ -17,11 +21,20 @@ import (
type ReportController struct {
reportService *report.ReportService
rankService *rank.RankService
actionService *action.CaptchaService
}
// NewReportController new controller
func NewReportController(reportService *report.ReportService, rankService *rank.RankService) *ReportController {
return &ReportController{reportService: reportService, rankService: rankService}
func NewReportController(
reportService *report.ReportService,
rankService *rank.RankService,
actionService *action.CaptchaService,
) *ReportController {
return &ReportController{
reportService: reportService,
rankService: rankService,
actionService: actionService,
}
}
// AddReport add report
@ -42,6 +55,19 @@ func (rc *ReportController) AddReport(ctx *gin.Context) {
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := rc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionReport, 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
}
}
can, err := rc.rankService.CheckOperationPermission(ctx, req.UserID, permission.ReportAdd, "")
if err != nil {
handler.HandleResponse(ctx, err, nil)
@ -53,5 +79,8 @@ func (rc *ReportController) AddReport(ctx *gin.Context) {
}
err = rc.reportService.AddReport(ctx, req)
if !isAdmin {
rc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionReport, req.UserID)
}
handler.HandleResponse(ctx, err, nil)
}

View File

@ -3,19 +3,32 @@ package controller
import (
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/internal/service/action"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/errors"
)
// SearchController tag controller
type SearchController struct {
searchService *service.SearchService
actionService *action.CaptchaService
}
// NewSearchController new controller
func NewSearchController(searchService *service.SearchService) *SearchController {
return &SearchController{searchService: searchService}
func NewSearchController(
searchService *service.SearchService,
actionService *action.CaptchaService,
) *SearchController {
return &SearchController{
searchService: searchService,
actionService: actionService,
}
}
// Search godoc
@ -35,9 +48,32 @@ func (sc *SearchController) Search(ctx *gin.Context) {
return
}
dto.UserID = middleware.GetLoginUserIDFromContext(ctx)
unit := ctx.ClientIP()
if dto.UserID != "" {
unit = dto.UserID
}
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := sc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionSearch, unit, dto.CaptchaID, dto.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
}
}
<<<<<<< HEAD
resp, total, err := sc.searchService.Search(ctx, &dto)
=======
resp, total, extra, err := sc.searchService.Search(ctx, &dto)
if !isAdmin {
sc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionSearch, unit)
}
>>>>>>> feat/1.1.1/ai
handler.HandleResponse(ctx, err, schema.SearchListResp{
Total: total,
SearchResp: resp,

View File

@ -6,6 +6,7 @@ import (
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/internal/service/action"
@ -105,20 +106,22 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP(), 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
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionPassword, ctx.ClientIP(), 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
}
}
resp, err := uc.userService.EmailLogin(ctx, req)
if err != nil {
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP())
_, _ = uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEmail, ctx.ClientIP())
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "e_mail",
ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong),
@ -126,7 +129,9 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.BadRequest(reason.EmailOrPasswordWrong), errFields)
return
}
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP())
if !isAdmin {
uc.actionService.ActionRecordDel(ctx, entity.CaptchaActionPassword, ctx.ClientIP())
}
handler.HandleResponse(ctx, nil, resp)
}
@ -144,16 +149,18 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP(), 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
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEmail, ctx.ClientIP(), 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
}
}
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP())
err := uc.userService.RetrievePassWord(ctx, req)
handler.HandleResponse(ctx, err, nil)
}
@ -181,7 +188,7 @@ func (uc *UserController) UseRePassWord(ctx *gin.Context) {
}
err := uc.userService.UpdatePasswordWhenForgot(ctx, req)
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP())
uc.actionService.ActionRecordDel(ctx, entity.CaptchaActionPassword, ctx.ClientIP())
handler.HandleResponse(ctx, err, nil)
}
@ -234,14 +241,17 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) {
return
}
req.IP = ctx.ClientIP()
captchaPass := uc.actionService.UserRegisterVerifyCaptcha(ctx, 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
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEmail, req.IP, 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
}
}
resp, errFields, err := uc.userService.UserRegisterByEmail(ctx, req)
@ -284,7 +294,7 @@ func (uc *UserController) UserVerifyEmail(ctx *gin.Context) {
return
}
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
uc.actionService.ActionRecordDel(ctx, entity.CaptchaActionEmail, ctx.ClientIP())
handler.HandleResponse(ctx, err, resp)
}
@ -309,22 +319,20 @@ func (uc *UserController) UserVerifyEmailSend(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
return
}
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEmail, ctx.ClientIP(), 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
}
}
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP(),
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
}
_, err := uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
if err != nil {
log.Error(err)
}
err = uc.userService.UserVerifyEmailSend(ctx, userInfo.UserID)
err := uc.userService.UserVerifyEmailSend(ctx, userInfo.UserID)
handler.HandleResponse(ctx, err, nil)
}
@ -345,20 +353,22 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
}
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
req.AccessToken = middleware.ExtractToken(ctx)
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeModifyPass, ctx.ClientIP(),
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
}
_, err := uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeModifyPass, ctx.ClientIP())
if err != nil {
log.Error(err)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionPassword, 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
}
_, err := uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, req.UserID)
if err != nil {
log.Error(err)
}
}
oldPassVerification, err := uc.userService.UserModifyPassWordVerification(ctx, req)
@ -385,7 +395,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
}
err = uc.userService.UserModifyPassword(ctx, req)
if err == nil {
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP())
uc.actionService.ActionRecordDel(ctx, entity.CaptchaActionPassword, req.UserID)
}
handler.HandleResponse(ctx, err, nil)
}
@ -449,9 +459,16 @@ func (uc *UserController) ActionRecord(ctx *gin.Context) {
return
}
req.IP = ctx.ClientIP()
resp := &schema.ActionRecordResp{}
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if isAdmin {
resp.Verify = false
handler.HandleResponse(ctx, nil, resp)
} else {
resp, err := uc.actionService.ActionRecord(ctx, req)
handler.HandleResponse(ctx, err, resp)
}
resp, err := uc.actionService.ActionRecord(ctx, req)
handler.HandleResponse(ctx, err, resp)
}
// UserRegisterCaptcha godoc
@ -519,22 +536,26 @@ func (uc *UserController) UserChangeEmailSendCode(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.BadRequest(reason.EmailIllegalDomainError), nil)
return
}
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP(), 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
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionPassword, 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
}
}
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
resp, err := uc.userService.UserChangeEmailSendCode(ctx, req)
if err != nil {
handler.HandleResponse(ctx, err, resp)
return
}
if !isAdmin {
uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, req.UserID)
}
handler.HandleResponse(ctx, err, nil)
}
@ -561,7 +582,7 @@ func (uc *UserController) UserChangeEmailVerify(ctx *gin.Context) {
}
resp, err := uc.userService.UserChangeEmailVerify(ctx, req.Content)
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
uc.actionService.ActionRecordDel(ctx, entity.CaptchaActionEmail, ctx.ClientIP())
handler.HandleResponse(ctx, err, resp)
}

View File

@ -5,8 +5,11 @@ import (
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/internal/service/action"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/pkg/uid"
"github.com/gin-gonic/gin"
@ -15,13 +18,22 @@ import (
// VoteController activity controller
type VoteController struct {
VoteService *service.VoteService
rankService *rank.RankService
VoteService *service.VoteService
rankService *rank.RankService
actionService *action.CaptchaService
}
// NewVoteController new controller
func NewVoteController(voteService *service.VoteService, rankService *rank.RankService) *VoteController {
return &VoteController{VoteService: voteService, rankService: rankService}
func NewVoteController(
voteService *service.VoteService,
rankService *rank.RankService,
actionService *action.CaptchaService,
) *VoteController {
return &VoteController{
VoteService: voteService,
rankService: rankService,
actionService: actionService,
}
}
// VoteUp godoc
@ -41,6 +53,19 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) {
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := vc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionVote, 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
}
}
can, needRank, err := vc.rankService.CheckVotePermission(ctx, req.UserID, req.ObjectID, true)
if err != nil {
handler.HandleResponse(ctx, err, nil)
@ -52,7 +77,9 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
}
if !isAdmin {
vc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionVote, req.UserID)
}
resp, err := vc.VoteService.VoteUp(ctx, req)
if err != nil {
handler.HandleResponse(ctx, err, schema.ErrTypeToast)
@ -78,6 +105,18 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) {
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
isAdmin := middleware.GetUserIsAdminModerator(ctx)
if !isAdmin {
captchaPass := vc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionVote, 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
}
}
can, needRank, err := vc.rankService.CheckVotePermission(ctx, req.UserID, req.ObjectID, false)
if err != nil {
handler.HandleResponse(ctx, err, nil)
@ -89,7 +128,9 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil)
return
}
if !isAdmin {
vc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionVote, req.UserID)
}
resp, err := vc.VoteService.VoteDown(ctx, req)
if err != nil {
handler.HandleResponse(ctx, err, schema.ErrTypeToast)

View File

@ -0,0 +1,22 @@
package entity
const (
CaptchaActionEmail = "email"
CaptchaActionPassword = "password"
CaptchaActionEditUserinfo = "edit_userinfo"
CaptchaActionQuestion = "question"
CaptchaActionAnswer = "answer"
CaptchaActionComment = "comment"
CaptchaActionEdit = "edit"
CaptchaActionInvitationAnswer = "invitation_answer"
CaptchaActionSearch = "search"
CaptchaActionReport = "report"
CaptchaActionDelete = "delete"
CaptchaActionVote = "vote"
)
type ActionRecordInfo struct {
LastTime int64 `json:"last_time"`
Num int `json:"num"`
Config string `json:"config"`
}

View File

@ -2,11 +2,13 @@ package captcha
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/answerdev/answer/internal/base/data"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/service/action"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
@ -24,26 +26,41 @@ func NewCaptchaRepo(data *data.Data) action.CaptchaRepo {
}
}
func (cr *captchaRepo) SetActionType(ctx context.Context, ip, actionType string, amount int) (err error) {
cacheKey := fmt.Sprintf("ActionRecord:%s@", ip)
err = cr.data.Cache.SetInt64(ctx, cacheKey, int64(amount), 6*time.Minute)
func (cr *captchaRepo) SetActionType(ctx context.Context, unit, actionType, config string, amount int) (err error) {
now := time.Now()
cacheKey := fmt.Sprintf("ActionRecord:%s@%s@%s", unit, actionType, now.Format("2006-1-02"))
value := &entity.ActionRecordInfo{}
value.LastTime = now.Unix()
value.Num = amount
valueStr, err := json.Marshal(value)
if err != nil {
return nil
}
err = cr.data.Cache.SetString(ctx, cacheKey, string(valueStr), 6*time.Minute)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
return
}
func (cr *captchaRepo) GetActionType(ctx context.Context, ip, actionType string) (amount int, err error) {
cacheKey := fmt.Sprintf("ActionRecord:%s@", ip)
res, err := cr.data.Cache.GetInt64(ctx, cacheKey)
func (cr *captchaRepo) GetActionType(ctx context.Context, unit, actionType string) (actioninfo *entity.ActionRecordInfo, err error) {
now := time.Now()
cacheKey := fmt.Sprintf("ActionRecord:%s@%s@%s", unit, actionType, now.Format("2006-1-02"))
actioninfo = &entity.ActionRecordInfo{}
res, err := cr.data.Cache.GetString(ctx, cacheKey)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
return int(res), nil
err = json.Unmarshal([]byte(res), actioninfo)
if err != nil {
return actioninfo, nil
}
return actioninfo, nil
}
func (cr *captchaRepo) DelActionType(ctx context.Context, ip, actionType string) (err error) {
cacheKey := fmt.Sprintf("ActionRecord:%s@", ip)
func (cr *captchaRepo) DelActionType(ctx context.Context, unit, actionType string) (err error) {
now := time.Now()
cacheKey := fmt.Sprintf("ActionRecord:%s@%s@%s", unit, actionType, now.Format("2006-1-02"))
err = cr.data.Cache.Del(ctx, cacheKey)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()

View File

@ -16,7 +16,7 @@ var (
func Test_captchaRepo_DelActionType(t *testing.T) {
captchaRepo := captcha.NewCaptchaRepo(testDataSource)
err := captchaRepo.SetActionType(context.TODO(), ip, actionType, amount)
err := captchaRepo.SetActionType(context.TODO(), ip, actionType, "", amount)
assert.NoError(t, err)
gotAmount, err := captchaRepo.GetActionType(context.TODO(), ip, actionType)

View File

@ -2,9 +2,10 @@ package repo_test
import (
"context"
"testing"
"github.com/answerdev/answer/internal/repo/config"
serviceconfig "github.com/answerdev/answer/internal/service/config"
"testing"
"github.com/answerdev/answer/internal/repo/reason"
"github.com/stretchr/testify/assert"

View File

@ -2,11 +2,12 @@ package repo_test
import (
"context"
"github.com/answerdev/answer/internal/repo/unique"
"log"
"sync"
"testing"
"github.com/answerdev/answer/internal/repo/unique"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/repo/tag"
"github.com/stretchr/testify/assert"

View File

@ -12,7 +12,9 @@ type RemoveAnswerReq struct {
// user id
UserID string `json:"-"`
// whether user can delete it
CanDelete bool `json:"-"`
CanDelete bool `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
const (
@ -21,12 +23,14 @@ const (
)
type AnswerAddReq struct {
QuestionID string `json:"question_id"`
Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"`
HTML string `json:"-"`
UserID string `json:"-"`
CanEdit bool `json:"-"`
CanDelete bool `json:"-"`
QuestionID string `json:"question_id"`
Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"`
HTML string `json:"-"`
UserID string `json:"-"`
CanEdit bool `json:"-"`
CanDelete bool `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
func (req *AnswerAddReq) Check() (errFields []*validator.FormErrorField, err error) {
@ -44,7 +48,9 @@ type AnswerUpdateReq struct {
UserID string `json:"-"`
NoNeedReview bool `json:"-"`
// whether user can edit it
CanEdit bool `json:"-"`
CanEdit bool `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
func (req *AnswerUpdateReq) Check() (errFields []*validator.FormErrorField, err error) {

View File

@ -26,7 +26,9 @@ type AddCommentReq struct {
// whether user can edit it
CanEdit bool `json:"-"`
// whether user can delete it
CanDelete bool `json:"-"`
CanDelete bool `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
func (req *AddCommentReq) Check() (errFields []*validator.FormErrorField, err error) {
@ -39,7 +41,9 @@ type RemoveCommentReq struct {
// comment id
CommentID string `validate:"required" json:"comment_id"`
// user id
UserID string `json:"-"`
UserID string `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
// UpdateCommentReq update comment request
@ -58,7 +62,9 @@ type UpdateCommentReq struct {
// whether user can edit it
CanEdit bool `json:"-"`
// whether user can delete it
CanDelete bool `json:"-"`
CanDelete bool `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
func (req *UpdateCommentReq) Check() (errFields []*validator.FormErrorField, err error) {

View File

@ -20,9 +20,11 @@ const (
// RemoveQuestionReq delete question request
type RemoveQuestionReq struct {
// question id
ID string `validate:"required" json:"id"`
UserID string `json:"-" ` // user_id
IsAdmin bool `json:"-"`
ID string `validate:"required" json:"id"`
UserID string `json:"-" ` // user_id
IsAdmin bool `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
type CloseQuestionReq struct {
@ -63,6 +65,8 @@ type QuestionAdd struct {
// user id
UserID string `json:"-"`
QuestionPermission
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
func (req *QuestionAdd) Check() (errFields []*validator.FormErrorField, err error) {
@ -153,6 +157,8 @@ type QuestionUpdate struct {
UserID string `json:"-"`
NoNeedReview bool `json:"-"`
QuestionPermission
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
type QuestionUpdateInviteUser struct {
@ -160,6 +166,8 @@ type QuestionUpdateInviteUser struct {
InviteUser []string `validate:"omitempty" json:"invite_user"`
UserID string `json:"-"`
QuestionPermission
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
func (req *QuestionUpdate) Check() (errFields []*validator.FormErrorField, err error) {

View File

@ -15,7 +15,9 @@ type AddReportReq struct {
// report content
Content string `validate:"omitempty,gt=0,lte=500" json:"content"`
// user id
UserID string `json:"-"`
UserID string `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
// GetReportListReq get report list all request

View File

@ -6,11 +6,13 @@ import (
)
type SearchDTO struct {
UserID string // UserID current login user ID
Query string `validate:"required,gte=1,lte=60" json:"q" form:"q"` // Query the query string
Page int `validate:"omitempty,min=1" form:"page,default=1" json:"page"` //Query number of pages
Size int `validate:"omitempty,min=1,max=50" form:"size,default=30" json:"size"` //Search page size
Order string `validate:"required,oneof=newest active score relevance" form:"order,default=relevance" json:"order" enums:"newest,active,score,relevance"`
UserID string // UserID current login user ID
Query string `validate:"required,gte=1,lte=60" json:"q" form:"q"` // Query the query string
Page int `validate:"omitempty,min=1" form:"page,default=1" json:"page"` //Query number of pages
Size int `validate:"omitempty,min=1,max=50" form:"size,default=30" json:"size"` //Search page size
Order string `validate:"required,oneof=newest active score relevance" form:"order,default=relevance" json:"order" enums:"newest,active,score,relevance"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
type SearchCondition struct {

View File

@ -164,11 +164,6 @@ const (
NoticeStatusOn = 1
NoticeStatusOff = 2
ActionRecordTypeLogin = "login"
ActionRecordTypeEmail = "e_mail"
ActionRecordTypeFindPass = "find_pass"
ActionRecordTypeModifyPass = "modify_pass"
)
var UserStatusShow = map[int]string{
@ -331,7 +326,7 @@ type UserNoticeSetResp struct {
type ActionRecordReq struct {
// action
Action string `validate:"required,oneof=login e_mail find_pass modify_pass" form:"action"`
Action string `validate:"required,oneof=email password edit_userinfo question answer comment edit invitation_answer search report delete vote" form:"action"`
IP string `json:"-"`
}

View File

@ -1,9 +1,11 @@
package schema
type VoteReq struct {
ObjectID string `validate:"required" form:"object_id" json:"object_id"` // id
IsCancel bool `validate:"omitempty" form:"is_cancel" json:"is_cancel"` // is cancel
UserID string `json:"-"`
ObjectID string `validate:"required" form:"object_id" json:"object_id"` // id
IsCancel bool `validate:"omitempty" form:"is_cancel" json:"is_cancel"` // is cancel
UserID string `json:"-"`
CaptchaID string `json:"captcha_id"` // captcha_id
CaptchaCode string `json:"captcha_code"`
}
type VoteResp struct {

View File

@ -6,6 +6,7 @@ import (
"strings"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/mojocn/base64Captcha"
"github.com/segmentfault/pacman/errors"
@ -17,9 +18,9 @@ type CaptchaRepo interface {
SetCaptcha(ctx context.Context, key, captcha string) (err error)
GetCaptcha(ctx context.Context, key string) (captcha string, err error)
DelCaptcha(ctx context.Context, key string) (err error)
SetActionType(ctx context.Context, ip, actionType string, amount int) (err error)
GetActionType(ctx context.Context, ip, actionType string) (amount int, err error)
DelActionType(ctx context.Context, ip, actionType string) (err error)
SetActionType(ctx context.Context, unit, actionType, config string, amount int) (err error)
GetActionType(ctx context.Context, unit, actionType string) (actioninfo *entity.ActionRecordInfo, err error)
DelActionType(ctx context.Context, unit, actionType string) (err error)
}
// CaptchaService kit service
@ -37,12 +38,8 @@ func NewCaptchaService(captchaRepo CaptchaRepo) *CaptchaService {
// ActionRecord action record
func (cs *CaptchaService) ActionRecord(ctx context.Context, req *schema.ActionRecordReq) (resp *schema.ActionRecordResp, err error) {
resp = &schema.ActionRecordResp{}
num, err := cs.captchaRepo.GetActionType(ctx, req.IP, req.Action)
if err != nil {
num = 0
}
// TODO config num to config file
if num >= 3 {
verificationResult := cs.ValidationStrategy(ctx, req.IP, req.Action)
if !verificationResult {
resp.CaptchaID, resp.CaptchaImg, err = cs.GenerateCaptcha(ctx)
resp.Verify = true
}
@ -72,13 +69,10 @@ func (cs *CaptchaService) UserRegisterVerifyCaptcha(
// ActionRecordVerifyCaptcha
// Verify that you need to enter a CAPTCHA, and that the CAPTCHA is correct
func (cs *CaptchaService) ActionRecordVerifyCaptcha(
ctx context.Context, actionType string, ip string, id string, VerifyValue string,
ctx context.Context, actionType string, unit string, id string, VerifyValue string,
) bool {
num, cahceErr := cs.captchaRepo.GetActionType(ctx, ip, actionType)
if cahceErr != nil {
return true
}
if num >= 3 {
verificationResult := cs.ValidationStrategy(ctx, unit, actionType)
if !verificationResult {
if id == "" || VerifyValue == "" {
return false
}
@ -91,22 +85,22 @@ func (cs *CaptchaService) ActionRecordVerifyCaptcha(
return true
}
func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, ip string) (int, error) {
func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) (int, error) {
var err error
num, cahceErr := cs.captchaRepo.GetActionType(ctx, ip, actionType)
info, cahceErr := cs.captchaRepo.GetActionType(ctx, unit, actionType)
if cahceErr != nil {
log.Error(err)
}
num++
err = cs.captchaRepo.SetActionType(ctx, ip, actionType, num)
info.Num++
err = cs.captchaRepo.SetActionType(ctx, unit, actionType, "", info.Num)
if err != nil {
return 0, err
}
return num, nil
return info.Num, nil
}
func (cs *CaptchaService) ActionRecordDel(ctx context.Context, actionType string, ip string) {
err := cs.captchaRepo.DelActionType(ctx, ip, actionType)
func (cs *CaptchaService) ActionRecordDel(ctx context.Context, actionType string, unit string) {
err := cs.captchaRepo.DelActionType(ctx, unit, actionType)
if err != nil {
log.Error(err)
}

View File

@ -0,0 +1,180 @@
package action
import (
"context"
"time"
"github.com/answerdev/answer/internal/entity"
"github.com/davecgh/go-spew/spew"
)
// ValidationStrategy
// true pass
// false need captcha
func (cs *CaptchaService) ValidationStrategy(ctx context.Context, unit, actionType string) bool {
info, err := cs.captchaRepo.GetActionType(ctx, unit, actionType)
spew.Dump("[ValidationStrategy=验证策略]", unit, actionType, info, err)
if err != nil {
//No record, no processing
//
}
switch actionType {
case entity.CaptchaActionEmail:
return cs.CaptchaActionEmail(ctx, unit, info)
case entity.CaptchaActionPassword:
return cs.CaptchaActionPassword(ctx, unit, info)
case entity.CaptchaActionEditUserinfo:
return cs.CaptchaActionEditUserinfo(ctx, unit, info)
case entity.CaptchaActionQuestion:
return cs.CaptchaActionQuestion(ctx, unit, info)
case entity.CaptchaActionAnswer:
return cs.CaptchaActionAnswer(ctx, unit, info)
case entity.CaptchaActionComment:
return cs.CaptchaActionComment(ctx, unit, info)
case entity.CaptchaActionEdit:
return cs.CaptchaActionEdit(ctx, unit, info)
case entity.CaptchaActionInvitationAnswer:
return cs.CaptchaActionInvitationAnswer(ctx, unit, info)
case entity.CaptchaActionSearch:
return cs.CaptchaActionSearch(ctx, unit, info)
case entity.CaptchaActionReport:
return cs.CaptchaActionReport(ctx, unit, info)
case entity.CaptchaActionDelete:
return cs.CaptchaActionDelete(ctx, unit, info)
case entity.CaptchaActionVote:
return cs.CaptchaActionVote(ctx, unit, info)
}
//actionType not found
return false
}
func (cs *CaptchaService) CaptchaActionEmail(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
// You need a verification code every time
spew.Dump("[CaptchaActionEmail]", actioninfo)
return false
}
func (cs *CaptchaService) CaptchaActionPassword(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionPassword]", actioninfo)
setNum := 3
setTime := int64(60 * 30) //seconds
now := time.Now().Unix()
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
if now-actioninfo.LastTime > setTime {
cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionPassword, "", 0)
}
return true
}
func (cs *CaptchaService) CaptchaActionEditUserinfo(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionEditUserinfo]", actioninfo)
setNum := 3
setTime := int64(60 * 30) //seconds
now := time.Now().Unix()
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
if now-actioninfo.LastTime > setTime {
cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionEditUserinfo, "", 0)
}
return true
}
func (cs *CaptchaService) CaptchaActionQuestion(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionQuestion]", actioninfo)
setNum := 3
setTime := int64(5) //seconds
now := time.Now().Unix()
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionAnswer(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionAnswer]", actioninfo)
setNum := 10
setTime := int64(5) //seconds
now := time.Now().Unix()
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionComment(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionComment]", actioninfo)
setNum := 30
setTime := int64(1) //seconds
now := time.Now().Unix()
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionEdit(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionEdit]", actioninfo)
setNum := 10
if actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionInvitationAnswer(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionInvitationAnswer]", actioninfo)
setNum := 30
if actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
now := time.Now().Unix()
setNum := 20
setTime := int64(60) //seconds
spew.Dump("[CaptchaActionSearch]", unit, actioninfo, now-int64(actioninfo.LastTime))
if now-int64(actioninfo.LastTime) <= setTime && actioninfo.Num >= setNum {
return false
}
if now-actioninfo.LastTime > setTime {
cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionSearch, "", 0)
}
return true
}
func (cs *CaptchaService) CaptchaActionReport(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
setNum := 30
setTime := int64(1) //seconds
now := time.Now().Unix()
spew.Dump("[CaptchaActionReport]", actioninfo, now-int64(actioninfo.LastTime))
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionDelete(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionDelete]", actioninfo)
setNum := 5
setTime := int64(5) //seconds
now := time.Now().Unix()
if now-actioninfo.LastTime <= setTime || actioninfo.Num >= setNum {
return false
}
return true
}
func (cs *CaptchaService) CaptchaActionVote(ctx context.Context, unit string, actioninfo *entity.ActionRecordInfo) bool {
spew.Dump("[CaptchaActionVote]", actioninfo)
setNum := 40
if actioninfo.Num >= setNum {
return false
}
return true
}