feat(permission): add user permission API

This commit is contained in:
LinkinStars 2023-05-25 15:56:58 +08:00
parent bd079a0040
commit 3428b5fbc3
9 changed files with 338 additions and 4 deletions

View File

@ -211,7 +211,8 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
pluginConfigRepo := plugin_config.NewPluginConfigRepo(dataData) pluginConfigRepo := plugin_config.NewPluginConfigRepo(dataData)
pluginCommonService := plugin_common.NewPluginCommonService(pluginConfigRepo, configRepo) pluginCommonService := plugin_common.NewPluginCommonService(pluginConfigRepo, configRepo)
pluginController := controller_admin.NewPluginController(pluginCommonService) pluginController := controller_admin.NewPluginController(pluginCommonService)
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_adminReportController, userAdminController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController) permissionController := controller.NewPermissionController(rankService)
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_adminReportController, userAdminController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController, permissionController)
swaggerRouter := router.NewSwaggerRouter(swaggerConf) swaggerRouter := router.NewSwaggerRouter(swaggerConf)
uiRouter := router.NewUIRouter(siteinfoController, siteInfoCommonService) uiRouter := router.NewUIRouter(siteinfoController, siteInfoCommonService)
authUserMiddleware := middleware.NewAuthUserMiddleware(authService, siteInfoCommonService) authUserMiddleware := middleware.NewAuthUserMiddleware(authService, siteInfoCommonService)

View File

@ -3009,6 +3009,102 @@ const docTemplate = `{
} }
} }
}, },
"/answer/api/v1/permission": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "check user permission",
"produces": [
"application/json"
],
"tags": [
"Permission"
],
"summary": "check user permission",
"parameters": [
{
"type": "string",
"description": "access-token",
"name": "Authorization",
"in": "header",
"required": true
},
{
"enum": [
"question.add",
"question.edit",
"question.edit_without_review",
"question.delete",
"question.close",
"question.reopen",
"question.vote_up",
"question.vote_down",
"question.pin",
"question.unpin",
"question.hide",
"question.show",
"answer.add",
"answer.edit",
"answer.edit_without_review",
"answer.delete",
"answer.accept",
"answer.vote_up",
"answer.vote_down",
"answer.invite_someone_to_answer",
"comment.add",
"comment.edit",
"comment.delete",
"comment.vote_up",
"comment.vote_down",
"report.add",
"tag.add",
"tag.edit",
"tag.edit_slug_name",
"tag.edit_without_review",
"tag.delete",
"tag.synonym",
"link.url_limit",
"vote.detail",
"answer.audit",
"question.audit",
"tag.audit",
"tag.use_reserved_tag"
],
"type": "string",
"description": "permission key",
"name": "action",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.RespBody"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
}
}
}
]
}
}
}
}
},
"/answer/api/v1/personal/answer/page": { "/answer/api/v1/personal/answer/page": {
"get": { "get": {
"security": [ "security": [

View File

@ -2997,6 +2997,102 @@
} }
} }
}, },
"/answer/api/v1/permission": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "check user permission",
"produces": [
"application/json"
],
"tags": [
"Permission"
],
"summary": "check user permission",
"parameters": [
{
"type": "string",
"description": "access-token",
"name": "Authorization",
"in": "header",
"required": true
},
{
"enum": [
"question.add",
"question.edit",
"question.edit_without_review",
"question.delete",
"question.close",
"question.reopen",
"question.vote_up",
"question.vote_down",
"question.pin",
"question.unpin",
"question.hide",
"question.show",
"answer.add",
"answer.edit",
"answer.edit_without_review",
"answer.delete",
"answer.accept",
"answer.vote_up",
"answer.vote_down",
"answer.invite_someone_to_answer",
"comment.add",
"comment.edit",
"comment.delete",
"comment.vote_up",
"comment.vote_down",
"report.add",
"tag.add",
"tag.edit",
"tag.edit_slug_name",
"tag.edit_without_review",
"tag.delete",
"tag.synonym",
"link.url_limit",
"vote.detail",
"answer.audit",
"question.audit",
"tag.audit",
"tag.use_reserved_tag"
],
"type": "string",
"description": "permission key",
"name": "action",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.RespBody"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
}
}
}
]
}
}
}
}
},
"/answer/api/v1/personal/answer/page": { "/answer/api/v1/personal/answer/page": {
"get": { "get": {
"security": [ "security": [

View File

@ -4086,6 +4086,78 @@ paths:
summary: DelRedDot summary: DelRedDot
tags: tags:
- Notification - Notification
/answer/api/v1/permission:
get:
description: check user permission
parameters:
- description: access-token
in: header
name: Authorization
required: true
type: string
- description: permission key
enum:
- question.add
- question.edit
- question.edit_without_review
- question.delete
- question.close
- question.reopen
- question.vote_up
- question.vote_down
- question.pin
- question.unpin
- question.hide
- question.show
- answer.add
- answer.edit
- answer.edit_without_review
- answer.delete
- answer.accept
- answer.vote_up
- answer.vote_down
- answer.invite_someone_to_answer
- comment.add
- comment.edit
- comment.delete
- comment.vote_up
- comment.vote_down
- report.add
- tag.add
- tag.edit
- tag.edit_slug_name
- tag.edit_without_review
- tag.delete
- tag.synonym
- link.url_limit
- vote.detail
- answer.audit
- question.audit
- tag.audit
- tag.use_reserved_tag
in: query
name: action
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/handler.RespBody'
- properties:
data:
additionalProperties:
type: boolean
type: object
type: object
security:
- ApiKeyAuth: []
summary: check user permission
tags:
- Permission
/answer/api/v1/personal/answer/page: /answer/api/v1/personal/answer/page:
get: get:
consumes: consumes:

View File

@ -26,4 +26,5 @@ var ProviderSetController = wire.NewSet(
NewTemplateController, NewTemplateController,
NewConnectorController, NewConnectorController,
NewUserCenterController, NewUserCenterController,
NewPermissionController,
) )

View File

@ -1 +0,0 @@
package controller

View File

@ -0,0 +1,47 @@
package controller
import (
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/rank"
"github.com/gin-gonic/gin"
)
type PermissionController struct {
rankService *rank.RankService
}
// NewPermissionController new language controller.
func NewPermissionController(rankService *rank.RankService) *PermissionController {
return &PermissionController{rankService: rankService}
}
// GetPermission check user permission
// @Summary check user permission
// @Description check user permission
// @Tags Permission
// @Security ApiKeyAuth
// @Param Authorization header string true "access-token"
// @Produce json
// @Param action query string true "permission key" Enums(question.add, question.edit, question.edit_without_review, question.delete, question.close, question.reopen, question.vote_up, question.vote_down, question.pin, question.unpin, question.hide, question.show, answer.add, answer.edit, answer.edit_without_review, answer.delete, answer.accept, answer.vote_up, answer.vote_down, answer.invite_someone_to_answer, comment.add, comment.edit, comment.delete, comment.vote_up, comment.vote_down, report.add, tag.add, tag.edit, tag.edit_slug_name, tag.edit_without_review, tag.delete, tag.synonym, link.url_limit, vote.detail, answer.audit, question.audit, tag.audit, tag.use_reserved_tag)
// @Success 200 {object} handler.RespBody{data=map[string]bool}
// @Router /answer/api/v1/permission [get]
func (u *PermissionController) GetPermission(ctx *gin.Context) {
req := &schema.GetPermissionReq{}
if handler.BindAndCheck(ctx, req) {
return
}
userID := middleware.GetLoginUserIDFromContext(ctx)
resp, err := u.rankService.CheckOperationPermissions(ctx, userID, req.Actions)
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
}
mapping := make(map[string]bool, len(resp))
for i, action := range req.Actions {
mapping[action] = resp[i]
}
handler.HandleResponse(ctx, err, mapping)
}

View File

@ -33,6 +33,7 @@ type AnswerAPIRouter struct {
activityController *controller.ActivityController activityController *controller.ActivityController
roleController *controller_admin.RoleController roleController *controller_admin.RoleController
pluginController *controller_admin.PluginController pluginController *controller_admin.PluginController
permissionController *controller.PermissionController
} }
func NewAnswerAPIRouter( func NewAnswerAPIRouter(
@ -61,6 +62,7 @@ func NewAnswerAPIRouter(
activityController *controller.ActivityController, activityController *controller.ActivityController,
roleController *controller_admin.RoleController, roleController *controller_admin.RoleController,
pluginController *controller_admin.PluginController, pluginController *controller_admin.PluginController,
permissionController *controller.PermissionController,
) *AnswerAPIRouter { ) *AnswerAPIRouter {
return &AnswerAPIRouter{ return &AnswerAPIRouter{
langController: langController, langController: langController,
@ -88,6 +90,7 @@ func NewAnswerAPIRouter(
activityController: activityController, activityController: activityController,
roleController: roleController, roleController: roleController,
pluginController: pluginController, pluginController: pluginController,
permissionController: permissionController,
} }
} }
@ -220,6 +223,9 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
// reason // reason
r.GET("/reasons", a.reasonController.Reasons) r.GET("/reasons", a.reasonController.Reasons)
// permission
r.GET("/permission", a.permissionController.GetPermission)
// notification // notification
r.GET("/notification/status", a.notificationController.GetRedDot) r.GET("/notification/status", a.notificationController.GetRedDot)
r.PUT("/notification/status", a.notificationController.ClearRedDot) r.PUT("/notification/status", a.notificationController.ClearRedDot)

View File

@ -1,7 +1,10 @@
package schema package schema
const PermissionMemberActionTypeEdit = "edit" import (
const PermissionMemberActionTypeReason = "reason" "strings"
"github.com/answerdev/answer/internal/base/validator"
)
// PermissionMemberAction permission member action // PermissionMemberAction permission member action
type PermissionMemberAction struct { type PermissionMemberAction struct {
@ -9,3 +12,16 @@ type PermissionMemberAction struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
} }
// GetPermissionReq get permission request
type GetPermissionReq struct {
Action string `form:"action"`
Actions []string `validate:"omitempty" form:"actions"`
}
func (r *GetPermissionReq) Check() (errField []*validator.FormErrorField, err error) {
if len(r.Action) > 0 {
r.Actions = strings.Split(r.Action, ",")
}
return nil, nil
}