feat(role): add role permission

This commit is contained in:
LinkinStar 2022-12-02 11:21:24 +08:00
parent affd376f57
commit 210c5c6a8e
14 changed files with 212 additions and 151 deletions

View File

@ -31,6 +31,7 @@ import (
"github.com/answerdev/answer/internal/repo/reason"
"github.com/answerdev/answer/internal/repo/report"
"github.com/answerdev/answer/internal/repo/revision"
"github.com/answerdev/answer/internal/repo/role"
"github.com/answerdev/answer/internal/repo/search_common"
"github.com/answerdev/answer/internal/repo/site_info"
"github.com/answerdev/answer/internal/repo/tag"
@ -61,6 +62,7 @@ import (
"github.com/answerdev/answer/internal/service/report_backyard"
"github.com/answerdev/answer/internal/service/report_handle_backyard"
"github.com/answerdev/answer/internal/service/revision_common"
role2 "github.com/answerdev/answer/internal/service/role"
"github.com/answerdev/answer/internal/service/search_parser"
"github.com/answerdev/answer/internal/service/service_config"
"github.com/answerdev/answer/internal/service/siteinfo"
@ -128,7 +130,13 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService)
voteRepo := activity_common.NewVoteRepo(dataData, activityRepo)
commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo)
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, configRepo)
userRoleRelRepo := role.NewUserRoleRelRepo(dataData)
roleRepo := role.NewRoleRepo(dataData)
roleService := role2.NewRoleService(roleRepo)
userRoleRelService := role2.NewUserRoleRelService(userRoleRelRepo, roleService)
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService)
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configRepo)
commentController := controller.NewCommentController(commentService, rankService)
reportRepo := report.NewReportRepo(dataData, uniqueIDRepo)
reportService := report2.NewReportService(reportRepo, objService)
@ -171,7 +179,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
reportBackyardService := report_backyard.NewReportBackyardService(reportRepo, userCommon, commonRepo, answerRepo, questionRepo, commentCommonRepo, reportHandle, configRepo)
controller_backyardReportController := controller_backyard.NewReportController(reportBackyardService)
userBackyardRepo := user.NewUserBackyardRepo(dataData, authRepo)
userBackyardService := user_backyard.NewUserBackyardService(userBackyardRepo)
userBackyardService := user_backyard.NewUserBackyardService(userBackyardRepo, userRoleRelService)
userBackyardController := controller_backyard.NewUserBackyardController(userBackyardService)
reasonRepo := reason.NewReasonRepo(configRepo)
reasonService := reason2.NewReasonService(reasonRepo)
@ -191,7 +199,8 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo)
activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService)
activityController := controller.NewActivityController(activityCommon, activityService)
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_backyardReportController, userBackyardController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController)
roleController := controller_backyard.NewRoleController(roleService)
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_backyardReportController, userBackyardController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController, roleController)
swaggerRouter := router.NewSwaggerRouter(swaggerConf)
uiRouter := router.NewUIRouter()
authUserMiddleware := middleware.NewAuthUserMiddleware(authService)

View File

@ -58,3 +58,14 @@ func (ur *userRoleRelRepo) GetUserRoleRelList(ctx context.Context, userIDs []str
}
return
}
// GetUserRoleRel get user role
func (ur *userRoleRelRepo) GetUserRoleRel(ctx context.Context, userID string) (
rolePowerRel *entity.RolePowerRel, exist bool, err error) {
rolePowerRel = &entity.RolePowerRel{}
exist, err = ur.data.DB.Where("user_id", userID).Get(rolePowerRel)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
return
}

View File

@ -368,8 +368,7 @@ type ActionRecordResp struct {
}
type UserBasicInfo struct {
ID string `json:"-"` // user_id
IsAdmin bool `json:"-"`
ID string `json:"-"` // user_id
Username string `json:"username" ` // name
Rank int `json:"rank" ` // rank
DisplayName string `json:"display_name"` // display_name

View File

@ -0,0 +1,36 @@
package permission
import (
"context"
"github.com/answerdev/answer/internal/schema"
)
// GetAnswerPermission get answer permission
func GetAnswerPermission(ctx context.Context, userID string, creatorUserID string, canEdit, canDelete bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if len(userID) > 0 {
actions = append(actions, &schema.PermissionMemberAction{
Action: "report",
Name: "Flag",
Type: "reason",
})
}
if canEdit || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
if canDelete || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "delete",
Name: "Delete",
Type: "confirm",
})
}
return actions
}

View File

@ -34,103 +34,3 @@ func GetCommentPermission(ctx context.Context, userID string, creatorUserID stri
}
return actions
}
// GetTagPermission get tag permission
func GetTagPermission(ctx context.Context, canEdit, canDelete bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if canEdit {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
if canDelete {
actions = append(actions, &schema.PermissionMemberAction{
Action: "delete",
Name: "Delete",
Type: "reason",
})
}
return actions
}
// GetAnswerPermission get answer permission
func GetAnswerPermission(ctx context.Context, userID string, creatorUserID string, canEdit, canDelete bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if len(userID) > 0 {
actions = append(actions, &schema.PermissionMemberAction{
Action: "report",
Name: "Flag",
Type: "reason",
})
}
if canEdit || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
if canDelete || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "delete",
Name: "Delete",
Type: "confirm",
})
}
return actions
}
// GetQuestionPermission get question permission
func GetQuestionPermission(ctx context.Context, userID string, creatorUserID string, canEdit, canDelete, canClose bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if len(userID) > 0 {
actions = append(actions, &schema.PermissionMemberAction{
Action: "report",
Name: "Flag",
Type: "reason",
})
}
if canEdit || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
if canClose {
actions = append(actions, &schema.PermissionMemberAction{
Action: "close",
Name: "Close",
Type: "confirm",
})
}
if canDelete || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "delete",
Name: "Delete",
Type: "confirm",
})
}
return actions
}
// GetTagSynonymPermission get tag synonym permission
func GetTagSynonymPermission(ctx context.Context, canEdit bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if canEdit {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
return actions
}

View File

@ -0,0 +1,42 @@
package permission
import (
"context"
"github.com/answerdev/answer/internal/schema"
)
// GetQuestionPermission get question permission
func GetQuestionPermission(ctx context.Context, userID string, creatorUserID string, canEdit, canDelete, canClose bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if len(userID) > 0 {
actions = append(actions, &schema.PermissionMemberAction{
Action: "report",
Name: "Flag",
Type: "reason",
})
}
if canEdit || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
if canClose {
actions = append(actions, &schema.PermissionMemberAction{
Action: "close",
Name: "Close",
Type: "confirm",
})
}
if canDelete || userID == creatorUserID {
actions = append(actions, &schema.PermissionMemberAction{
Action: "delete",
Name: "Delete",
Type: "confirm",
})
}
return actions
}

View File

@ -0,0 +1,43 @@
package permission
import (
"context"
"github.com/answerdev/answer/internal/schema"
)
// GetTagPermission get tag permission
func GetTagPermission(ctx context.Context, canEdit, canDelete bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if canEdit {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
if canDelete {
actions = append(actions, &schema.PermissionMemberAction{
Action: "delete",
Name: "Delete",
Type: "reason",
})
}
return actions
}
// GetTagSynonymPermission get tag synonym permission
func GetTagSynonymPermission(ctx context.Context, canEdit bool) (
actions []*schema.PermissionMemberAction) {
actions = make([]*schema.PermissionMemberAction, 0)
if canEdit {
actions = append(actions, &schema.PermissionMemberAction{
Action: "edit",
Name: "Edit",
Type: "edit",
})
}
return actions
}

View File

@ -23,7 +23,6 @@ import (
"github.com/answerdev/answer/internal/service/report_backyard"
"github.com/answerdev/answer/internal/service/report_handle_backyard"
"github.com/answerdev/answer/internal/service/revision_common"
"github.com/answerdev/answer/internal/service/search_parser"
"github.com/answerdev/answer/internal/service/role"
"github.com/answerdev/answer/internal/service/search_parser"
"github.com/answerdev/answer/internal/service/siteinfo"

View File

@ -2,6 +2,7 @@ package rank
import (
"context"
"strings"
"github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/base/pager"
@ -11,6 +12,7 @@ import (
"github.com/answerdev/answer/internal/service/activity_type"
"github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/object_info"
"github.com/answerdev/answer/internal/service/role"
usercommon "github.com/answerdev/answer/internal/service/user_common"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
@ -60,6 +62,8 @@ type RankService struct {
configRepo config.ConfigRepo
userRankRepo UserRankRepo
objectInfoService *object_info.ObjService
roleService *role.UserRoleRelService
rolePowerService *role.RolePowerRelService
}
// NewRankService new rank service
@ -67,12 +71,16 @@ func NewRankService(
userCommon *usercommon.UserCommon,
userRankRepo UserRankRepo,
objectInfoService *object_info.ObjService,
roleService *role.UserRoleRelService,
rolePowerService *role.RolePowerRelService,
configRepo config.ConfigRepo) *RankService {
return &RankService{
userCommon: userCommon,
configRepo: configRepo,
userRankRepo: userRankRepo,
objectInfoService: objectInfoService,
roleService: roleService,
rolePowerService: rolePowerService,
}
}
@ -91,8 +99,10 @@ func (rs *RankService) CheckOperationPermission(ctx context.Context, userID stri
if !exist {
return false, nil
}
// administrator have all permissions
if userInfo.IsAdmin {
powerMapping := rs.getUserPowerMapping(ctx, userID)
// TODO: remove
act := strings.TrimPrefix(action, "rank.")
if powerMapping[act] {
return true, nil
}
@ -141,8 +151,12 @@ func (rs *RankService) CheckOperationPermissions(ctx context.Context, userID str
}
}
powerMapping := rs.getUserPowerMapping(ctx, userID)
for idx, action := range actions {
if userInfo.IsAdmin || objectOwner {
// TODO: remove
act := strings.TrimPrefix(action, "rank.")
if powerMapping[act] || objectOwner {
can[idx] = true
continue
}
@ -204,6 +218,26 @@ func (rs *RankService) CheckVotePermission(ctx context.Context, userID, objectID
return meetRank, nil
}
// getUserPowerMapping get user power mapping
func (rs *RankService) getUserPowerMapping(ctx context.Context, userID string) (powerMapping map[string]bool) {
powerMapping = make(map[string]bool, 0)
userRole, err := rs.roleService.GetUserRole(ctx, userID)
if err != nil {
log.Error(err)
return powerMapping
}
powers, err := rs.rolePowerService.GetRolePowerList(ctx, userRole)
if err != nil {
log.Error(err)
return powerMapping
}
for _, power := range powers {
powerMapping[power] = true
}
return powerMapping
}
// CheckRankPermission verify that the user meets the prestige criteria
func (rs *RankService) checkUserRank(ctx context.Context, userID string, userRank int, action string) (
can bool, err error) {

View File

@ -10,38 +10,3 @@ import (
type PowerRepo interface {
GetPowerList(ctx context.Context, power *entity.Power) (powers []*entity.Power, err error)
}
//// PowerService user service
//type PowerService struct {
// powerRepo PowerRepo
// rolePowerRelService *RolePowerRelService
//}
//
//// NewPowerService new power service
//func NewPowerService(powerRepo PowerRepo, rolePowerRelService *RolePowerRelService) *PowerService {
// return &PowerService{
// powerRepo: powerRepo,
// }
//}
//
//// GetRolePowerList get role power list
//func (ps *PowerService) GetRolePowerList(ctx context.Context, roleID string) (powers []string, err error) {
// power := &entity.Power{}
// powerList, err := ps.powerRepo.GetPowerList(ctx, power)
// if err != nil {
// return
// }
//}
//
//// GetPowerList get list all
//func (ps *PowerService) GetPowerList(ctx context.Context, req *schema.GetPowerListReq) (resp *[]schema.GetPowerResp, err error) {
// power := &entity.Power{}
// powers, err := ps.powerRepo.GetPowerList(ctx, power)
// if err != nil {
// return
// }
//
// resp = &[]schema.GetPowerResp{}
// _ = copier.Copy(resp, powers)
// return
//}

View File

@ -11,13 +11,16 @@ type RolePowerRelRepo interface {
// RolePowerRelService user service
type RolePowerRelService struct {
rolePowerRelRepo RolePowerRelRepo
rolePowerRelRepo RolePowerRelRepo
userRoleRelService *UserRoleRelService
}
// NewRolePowerRelService new role power rel service
func NewRolePowerRelService(rolePowerRelRepo RolePowerRelRepo) *RolePowerRelService {
func NewRolePowerRelService(rolePowerRelRepo RolePowerRelRepo,
userRoleRelService *UserRoleRelService) *RolePowerRelService {
return &RolePowerRelService{
rolePowerRelRepo: rolePowerRelRepo,
rolePowerRelRepo: rolePowerRelRepo,
userRoleRelService: userRoleRelService,
}
}
@ -25,3 +28,12 @@ func NewRolePowerRelService(rolePowerRelRepo RolePowerRelRepo) *RolePowerRelServ
func (rs *RolePowerRelService) GetRolePowerList(ctx context.Context, roleID int) (powers []string, err error) {
return rs.rolePowerRelRepo.GetRolePowerTypeList(ctx, roleID)
}
// GetUserPowerList get list all
func (rs *RolePowerRelService) GetUserPowerList(ctx context.Context, userID string) (powers []string, err error) {
roleID, err := rs.userRoleRelService.GetUserRole(ctx, userID)
if err != nil {
return nil, err
}
return rs.rolePowerRelRepo.GetRolePowerTypeList(ctx, roleID)
}

View File

@ -10,6 +10,7 @@ import (
type UserRoleRelRepo interface {
SaveUserRoleRel(ctx context.Context, userID string, roleID int) (err error)
GetUserRoleRelList(ctx context.Context, userIDs []string) (userRoleRelList []*entity.UserRoleRel, err error)
GetUserRoleRel(ctx context.Context, userID string) (rolePowerRel *entity.RolePowerRel, exist bool, err error)
}
// UserRoleRelService user service
@ -79,3 +80,16 @@ func (us *UserRoleRelService) GetUserRoleRelMapping(ctx context.Context, userIDs
}
return userRoleRelMapping, nil
}
// GetUserRole get user role
func (us *UserRoleRelService) GetUserRole(ctx context.Context, userID string) (roleID int, err error) {
rolePowerRel, exist, err := us.userRoleRelRepo.GetUserRoleRel(ctx, userID)
if err != nil {
return 0, err
}
if exist {
// set default role
return 1, nil
}
return rolePowerRel.RoleID, nil
}

View File

@ -5,7 +5,6 @@ import (
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/role"
)
type UserRepo interface {
@ -28,8 +27,7 @@ type UserRepo interface {
// UserCommon user service
type UserCommon struct {
userRepo UserRepo
roleService *role.RoleService
userRepo UserRepo
}
func NewUserCommon(userRepo UserRepo) *UserCommon {
@ -82,7 +80,6 @@ func (us *UserCommon) BatchUserBasicInfoByID(ctx context.Context, IDs []string)
func (us *UserCommon) FormatUserBasicInfo(ctx context.Context, userInfo *entity.User) *schema.UserBasicInfo {
userBasicInfo := &schema.UserBasicInfo{}
userBasicInfo.ID = userInfo.ID
userBasicInfo.IsAdmin = userInfo.IsAdmin
userBasicInfo.Username = userInfo.Username
userBasicInfo.Rank = userInfo.Rank
userBasicInfo.DisplayName = userInfo.DisplayName