feat(privilege): add privileges API

This commit is contained in:
LinkinStars 2023-04-17 18:04:28 +08:00
parent 910484013c
commit 8800b376d5
22 changed files with 284 additions and 190 deletions

View File

@ -7919,10 +7919,6 @@ const docTemplate = `{
"custom_header": {
"type": "string",
"maxLength": 65536
},
"custom_sidebar": {
"type": "string",
"maxLength": 65536
}
}
},
@ -7944,10 +7940,6 @@ const docTemplate = `{
"custom_header": {
"type": "string",
"maxLength": 65536
},
"custom_sidebar": {
"type": "string",
"maxLength": 65536
}
}
},
@ -8049,18 +8041,10 @@ const docTemplate = `{
"schema.SiteInterfaceReq": {
"type": "object",
"required": [
"default_avatar",
"language",
"time_zone"
],
"properties": {
"default_avatar": {
"type": "string",
"enum": [
"system",
"gravatar"
]
},
"language": {
"type": "string",
"maxLength": 128
@ -8074,18 +8058,10 @@ const docTemplate = `{
"schema.SiteInterfaceResp": {
"type": "object",
"required": [
"default_avatar",
"language",
"time_zone"
],
"properties": {
"default_avatar": {
"type": "string",
"enum": [
"system",
"gravatar"
]
},
"language": {
"type": "string",
"maxLength": 128

View File

@ -7907,10 +7907,6 @@
"custom_header": {
"type": "string",
"maxLength": 65536
},
"custom_sidebar": {
"type": "string",
"maxLength": 65536
}
}
},
@ -7932,10 +7928,6 @@
"custom_header": {
"type": "string",
"maxLength": 65536
},
"custom_sidebar": {
"type": "string",
"maxLength": 65536
}
}
},
@ -8037,18 +8029,10 @@
"schema.SiteInterfaceReq": {
"type": "object",
"required": [
"default_avatar",
"language",
"time_zone"
],
"properties": {
"default_avatar": {
"type": "string",
"enum": [
"system",
"gravatar"
]
},
"language": {
"type": "string",
"maxLength": 128
@ -8062,18 +8046,10 @@
"schema.SiteInterfaceResp": {
"type": "object",
"required": [
"default_avatar",
"language",
"time_zone"
],
"properties": {
"default_avatar": {
"type": "string",
"enum": [
"system",
"gravatar"
]
},
"language": {
"type": "string",
"maxLength": 128

View File

@ -1463,9 +1463,6 @@ definitions:
custom_header:
maxLength: 65536
type: string
custom_sidebar:
maxLength: 65536
type: string
type: object
schema.SiteCustomCssHTMLResp:
properties:
@ -1481,9 +1478,6 @@ definitions:
custom_header:
maxLength: 65536
type: string
custom_sidebar:
maxLength: 65536
type: string
type: object
schema.SiteGeneralReq:
properties:
@ -1554,11 +1548,6 @@ definitions:
type: object
schema.SiteInterfaceReq:
properties:
default_avatar:
enum:
- system
- gravatar
type: string
language:
maxLength: 128
type: string
@ -1566,17 +1555,11 @@ definitions:
maxLength: 128
type: string
required:
- default_avatar
- language
- time_zone
type: object
schema.SiteInterfaceResp:
properties:
default_avatar:
enum:
- system
- gravatar
type: string
language:
maxLength: 128
type: string
@ -1584,7 +1567,6 @@ definitions:
maxLength: 128
type: string
required:
- default_avatar
- language
- time_zone
type: object

View File

@ -40,6 +40,60 @@ backend:
other: Have the full power to access the site.
moderator:
other: Has access to all posts except admin settings.
privilege:
level_1:
description:
other: Level 1 (less reputation required for startup community)
level_2:
description:
other: Level 2 (low reputation required for startup community)
level_3:
description:
other: Level 3 (high reputation required for mature community)
rank_question_add_label:
other: Ask question
rank_answer_add_label:
other: Write answer
rank_comment_add_label:
other: Write comment
rank_answer_accept_label:
other: Accept answer
rank_report_add_label:
other: Flag
rank_comment_vote_up_label:
other: Upvote comment
rank_link_url_limit_label:
other: Post more than 2 links at a time
rank_question_vote_up_label:
other: Upvote question
rank_answer_vote_up_label:
other: Upvote answer
rank_question_vote_down_label:
other: Downvote question
rank_answer_vote_down_label:
other: Downvote answer
rank_tag_add_label:
other: Create new tag
rank_tag_edit_label:
other: Edit tag description (need to review)
rank_question_edit_label:
other: Edit other's question (need to review)
rank_answer_edit_label:
other: Edit other's answer (need to review)
rank_question_edit_without_review_label:
other: Edit other's question without review
rank_answer_edit_without_review_label:
other: Edit other's answer without review
rank_question_audit_label:
other: Review question edits
rank_answer_audit_label:
other: Review answer edits
rank_tag_audit_label:
other: Review tag edits
rank_tag_edit_without_review_label:
other: Edit tag description without review
rank_tag_synonym_label:
other: Manage tag synonyms
email:
other: Email
password:

View File

@ -37,6 +37,60 @@ backend:
other: 拥有管理网站的全部权限。
moderator:
other: 拥有访问除管理员设置以外的所有权限。
privilege:
level_1:
description:
other: 等级1创业社区所需的声望最低
level_2:
description:
other: 等级2创业社区所需的声望较低
level_3:
description:
other: 等级3成熟社区所需的声望较高
rank_question_add_label:
other: 提问
rank_answer_add_label:
other: 回答问题
rank_comment_add_label:
other: 发表评论
rank_answer_accept_label:
other: 接受答案
rank_report_add_label:
other: 举报
rank_comment_vote_up_label:
other: 评论点赞
rank_link_url_limit_label:
other: 一次发布超过两个链接
rank_question_vote_up_label:
other: 问题点赞
rank_answer_vote_up_label:
other: 答案点赞
rank_question_vote_down_label:
other: 问题点踩
rank_answer_vote_down_label:
other: 答案点踩
rank_tag_add_label:
other: 创建新标签
rank_tag_edit_label:
other: 编辑标签描述(需要审核)
rank_question_edit_label:
other: 编辑他人提问(需要审核)
rank_answer_edit_label:
other: 编辑他人回答(需要审核)
rank_question_edit_without_review_label:
other: 编辑他人提问(无需审核)
rank_answer_edit_without_review_label:
other: 编辑他人回答(无需审核)
rank_question_audit_label:
other: 审核问题编辑
rank_answer_audit_label:
other: 审核答案编辑
rank_tag_audit_label:
other: 审核标签编辑
rank_tag_edit_without_review_label:
other: 编辑标签描述(无需审核)
rank_tag_synonym_label:
other: 管理标签同义词
email:
other: 邮箱
password:

View File

@ -1,9 +1,11 @@
package constant
import "github.com/answerdev/answer/internal/base/reason"
type Privilege struct {
Key string `json:"key"`
Label string `json:"label"`
Value int `json:"value"`
Key string `json:"-"`
}
const (
@ -41,80 +43,29 @@ const (
RankTagUseReservedTagKey = "rank.tag.use_reserved_tag"
)
//| Permission | Level 1 | Level 2 | Level 3 | Custom Level |
//| -------------------------------------- | ------------------------------------------------ | --------------------------------------------- | --------------------------------------------- | ------------ |
//| Description | less reputation required for private team, group | low reputation required for startup community | high reputation required for mature community | |
//| Ask question | 1 | 1 | 1 | |
//| Write answer | 1 | 1 | 1 | |
//| Write comment | 1 | 1 | 1 | |
//| Accept answer | 1 | 1 | 1 | |
//| Flag | 1 | 1 | 1 | |
//| Upvote comment | 1 | 1 | 1 | |
//| Post more than 2 links at a time | 1 | 10 | 10 | |
//| Upvote question | 1 | 1 | 15 | |
//| Upvote answer | 1 | 1 | 15 | |
//| Downvote question | 125 | 125 | 125 | |
//| Downvote answer | 125 | 125 | 125 | |
//| Create new tag | 1 | 750 | 1500 | |
//| Edit tag description (need to review) | 1 | 50 | 100 | |
//| Edit other's question (need to review) | 1 | 100 | 200 | |
//| Edit other's answer (need to review) | 1 | 100 | 200 | |
//| Edit other's question without review | 1 | 1000 | 2000 | |
//| Edit other's answer without review | 1 | 1000 | 2000 | |
//| Revew question edits | 1 | 1000 | 2000 | |
//| Review answer edits | 1 | 1000 | 2000 | |
//| Review tag edits | 1 | 2500 | 5000 | |
//| Edit tag description without review | 1 | 10000 | 20000 | |
//| Manage tag synonyms | 1 | 10000 | 20000 | |
const (
RankQuestionAddLabel = "Ask question"
RankAnswerAddLabel = "Write answer"
RankCommentAddLabel = "Write comment"
RankAnswerAcceptLabel = "Accept answer"
RankReportAddLabel = "Flag"
RankCommentVoteUpLabel = "Upvote comment"
RankLinkUrlLimitLabel = "Post more than 2 links at a time"
RankQuestionVoteUpLabel = "Upvote question"
RankAnswerVoteUpLabel = "Upvote answer"
RankQuestionVoteDownLabel = "Downvote question"
RankAnswerVoteDownLabel = "Downvote answer"
RankTagAddLabel = "Create new tag"
RankTagEditLabel = "Edit tag description (need to review)"
RankQuestionEditLabel = "Edit other's question (need to review)"
RankAnswerEditLabel = "Edit other's answer (need to review)"
RankQuestionEditWithoutReviewLabel = "Edit other's question without review"
RankAnswerEditWithoutReviewLabel = "Edit other's answer without review"
RankQuestionAuditLabel = "Review question edits"
RankAnswerAuditLabel = "Review answer edits"
RankTagAuditLabel = "Review tag edits"
RankTagEditWithoutReviewLabel = "Edit tag description without review"
RankTagSynonymLabel = "Manage tag synonyms"
)
var (
RankAllPrivileges = []*Privilege{
{Label: RankQuestionAddLabel, Key: RankQuestionAddKey},
{Label: RankAnswerAddLabel, Key: RankAnswerAddKey},
{Label: RankCommentAddLabel, Key: RankCommentAddKey},
{Label: RankAnswerAcceptLabel, Key: RankAnswerAcceptKey},
{Label: RankReportAddLabel, Key: RankReportAddKey},
{Label: RankCommentVoteUpLabel, Key: RankCommentVoteUpKey},
{Label: RankLinkUrlLimitLabel, Key: RankLinkUrlLimitKey},
{Label: RankQuestionVoteUpLabel, Key: RankQuestionVoteUpKey},
{Label: RankAnswerVoteUpLabel, Key: RankAnswerVoteUpKey},
{Label: RankQuestionVoteDownLabel, Key: RankQuestionVoteDownKey},
{Label: RankAnswerVoteDownLabel, Key: RankAnswerVoteDownKey},
{Label: RankTagAddLabel, Key: RankTagAddKey},
{Label: RankTagEditLabel, Key: RankTagEditKey},
{Label: RankQuestionEditLabel, Key: RankQuestionEditKey},
{Label: RankAnswerEditLabel, Key: RankAnswerEditKey},
{Label: RankQuestionEditWithoutReviewLabel, Key: RankQuestionEditWithoutReviewKey},
{Label: RankAnswerEditWithoutReviewLabel, Key: RankAnswerEditWithoutReviewKey},
{Label: RankQuestionAuditLabel, Key: RankQuestionAuditKey},
{Label: RankAnswerAuditLabel, Key: RankAnswerAuditKey},
{Label: RankTagAuditLabel, Key: RankTagAuditKey},
{Label: RankTagEditWithoutReviewLabel, Key: RankTagEditWithoutReviewKey},
{Label: RankTagSynonymLabel, Key: RankTagSynonymKey},
{Label: reason.RankQuestionAddLabel, Key: RankQuestionAddKey},
{Label: reason.RankAnswerAddLabel, Key: RankAnswerAddKey},
{Label: reason.RankCommentAddLabel, Key: RankCommentAddKey},
{Label: reason.RankAnswerAcceptLabel, Key: RankAnswerAcceptKey},
{Label: reason.RankReportAddLabel, Key: RankReportAddKey},
{Label: reason.RankCommentVoteUpLabel, Key: RankCommentVoteUpKey},
{Label: reason.RankLinkUrlLimitLabel, Key: RankLinkUrlLimitKey},
{Label: reason.RankQuestionVoteUpLabel, Key: RankQuestionVoteUpKey},
{Label: reason.RankAnswerVoteUpLabel, Key: RankAnswerVoteUpKey},
{Label: reason.RankQuestionVoteDownLabel, Key: RankQuestionVoteDownKey},
{Label: reason.RankAnswerVoteDownLabel, Key: RankAnswerVoteDownKey},
{Label: reason.RankTagAddLabel, Key: RankTagAddKey},
{Label: reason.RankTagEditLabel, Key: RankTagEditKey},
{Label: reason.RankQuestionEditLabel, Key: RankQuestionEditKey},
{Label: reason.RankAnswerEditLabel, Key: RankAnswerEditKey},
{Label: reason.RankQuestionEditWithoutReviewLabel, Key: RankQuestionEditWithoutReviewKey},
{Label: reason.RankAnswerEditWithoutReviewLabel, Key: RankAnswerEditWithoutReviewKey},
{Label: reason.RankQuestionAuditLabel, Key: RankQuestionAuditKey},
{Label: reason.RankAnswerAuditLabel, Key: RankAnswerAuditKey},
{Label: reason.RankTagAuditLabel, Key: RankTagAuditKey},
{Label: reason.RankTagEditWithoutReviewLabel, Key: RankTagEditWithoutReviewKey},
{Label: reason.RankTagSynonymLabel, Key: RankTagSynonymKey},
}
)

View File

@ -0,0 +1,30 @@
package reason
const (
PrivilegeLevel1Desc = "privilege.level_1.description"
PrivilegeLevel2Desc = "privilege.level_2.description"
PrivilegeLevel3Desc = "privilege.level_3.description"
RankQuestionAddLabel = "privilege.rank_question_add_label"
RankAnswerAddLabel = "privilege.rank_answer_add_label"
RankCommentAddLabel = "privilege.rank_comment_add_label"
RankAnswerAcceptLabel = "privilege.rank_answer_accept_label"
RankReportAddLabel = "privilege.rank_report_add_label"
RankCommentVoteUpLabel = "privilege.rank_comment_vote_up_label"
RankLinkUrlLimitLabel = "privilege.rank_link_url_limit_label"
RankQuestionVoteUpLabel = "privilege.rank_question_vote_up_label"
RankAnswerVoteUpLabel = "privilege.rank_answer_vote_up_label"
RankQuestionVoteDownLabel = "privilege.rank_question_vote_down_label"
RankAnswerVoteDownLabel = "privilege.rank_answer_vote_down_label"
RankTagAddLabel = "privilege.rank_tag_add_label"
RankTagEditLabel = "privilege.rank_tag_edit_label"
RankQuestionEditLabel = "privilege.rank_question_edit_label"
RankAnswerEditLabel = "privilege.rank_answer_edit_label"
RankQuestionEditWithoutReviewLabel = "privilege.rank_question_edit_without_review_label"
RankAnswerEditWithoutReviewLabel = "privilege.rank_answer_edit_without_review_label"
RankQuestionAuditLabel = "privilege.rank_question_audit_label"
RankAnswerAuditLabel = "privilege.rank_answer_audit_label"
RankTagAuditLabel = "privilege.rank_tag_audit_label"
RankTagEditWithoutReviewLabel = "privilege.rank_tag_edit_without_review_label"
RankTagSynonymLabel = "privilege.rank_tag_synonym_label"
)

View File

@ -68,6 +68,7 @@ func NewHTTPServer(debug bool,
// plugin routes
pluginAPIRouter.RegisterUnAuthConnectorRouter(mustUnAuthV1)
pluginAPIRouter.RegisterAuthUserConnectorRouter(authV1)
pluginAPIRouter.RegisterAuthAdminConnectorRouter(adminauthV1)
_ = plugin.CallAgent(func(agent plugin.Agent) error {
agent.RegisterUnAuthRouter(unAuthV1)

View File

@ -137,7 +137,7 @@ func (uc *UserCenterController) UserCenterLoginCallback(ctx *gin.Context) {
return
}
if len(resp.ErrMsg) > 0 {
ctx.String(http.StatusOK, resp.ErrMsg)
ctx.Redirect(http.StatusFound, "/50x?msg="+resp.ErrMsg)
return
}
userCenter.AfterLogin(userInfo.ExternalID, resp.AccessToken)
@ -172,7 +172,7 @@ func (uc *UserCenterController) UserCenterSignUpCallback(ctx *gin.Context) {
return
}
if len(resp.ErrMsg) > 0 {
ctx.String(http.StatusOK, resp.ErrMsg)
ctx.Redirect(http.StatusFound, "/50x?msg="+resp.ErrMsg)
return
}
userCenter.AfterLogin(userInfo.ExternalID, resp.AccessToken)

View File

@ -32,7 +32,7 @@ func NewUserAdminController(userService *user_admin.UserAdminService) *UserAdmin
// @Success 200 {object} handler.RespBody
// @Router /answer/admin/api/user/status [put]
func (uc *UserAdminController) UpdateUserStatus(ctx *gin.Context) {
if plugin.UserCenterEnabled() {
if u, ok := plugin.GetUserCenter(); ok && u.Description().UserStatusAgentEnabled {
handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil)
return
}

View File

@ -6,4 +6,5 @@ type UserCacheInfo struct {
UserStatus int `json:"user_status"`
EmailStatus int `json:"email_status"`
RoleID int `json:"role_id"`
ExternalID string `json:"external_id"`
}

View File

@ -7,6 +7,7 @@ import (
"github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/tidwall/gjson"
"xorm.io/xorm"
)
@ -22,10 +23,47 @@ func addLoginLimitations(x *xorm.Engine) error {
content := &schema.SiteLoginReq{}
_ = json.Unmarshal([]byte(loginSiteInfo.Content), content)
content.AllowEmailRegistrations = true
content.AllowEmailDomains = make([]string, 0)
_, err = x.ID(loginSiteInfo.ID).Cols("content").Update(loginSiteInfo)
if err != nil {
return fmt.Errorf("update site info failed: %w", err)
}
}
interfaceSiteInfo := &entity.SiteInfo{
Type: constant.SiteTypeInterface,
}
exist, err = x.Get(interfaceSiteInfo)
if err != nil {
return fmt.Errorf("get config failed: %w", err)
}
siteUsers := &schema.SiteUsersReq{
AllowUpdateDisplayName: true,
AllowUpdateUsername: true,
AllowUpdateAvatar: true,
AllowUpdateBio: true,
AllowUpdateWebsite: true,
AllowUpdateLocation: true,
}
if exist {
siteUsers.DefaultAvatar = gjson.Get(interfaceSiteInfo.Content, "default_avatar").String()
}
data, _ := json.Marshal(siteUsers)
exist, err = x.Get(&entity.SiteInfo{Type: constant.SiteTypeUsers})
if err != nil {
return fmt.Errorf("get config failed: %w", err)
}
if !exist {
usersSiteInfo := &entity.SiteInfo{
Type: constant.SiteTypeUsers,
Content: string(data),
Status: 1,
}
_, err = x.InsertOne(usersSiteInfo)
if err != nil {
return fmt.Errorf("insert site info failed: %w", err)
}
}
return nil
}

View File

@ -206,7 +206,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
// user
r.PUT("/user/password", middleware.BanAPIWhenUserCenterEnabled, a.userController.UserModifyPassWord)
r.PUT("/user/info", middleware.BanAPIWhenUserCenterEnabled, a.userController.UserUpdateInfo)
r.PUT("/user/info", a.userController.UserUpdateInfo)
r.PUT("/user/interface", a.userController.UserUpdateInterface)
r.POST("/user/notice/set", a.userController.UserNoticeSet)

View File

@ -45,7 +45,6 @@ func (r *SiteGeneralReq) FormatSiteUrl() {
type SiteInterfaceReq struct {
Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"`
TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"`
DefaultAvatar string `validate:"required,oneof=system gravatar" form:"default_avatar" json:"default_avatar"`
}
// SiteBrandingReq site branding request
@ -275,6 +274,7 @@ type GetPrivilegesConfigResp struct {
// PrivilegeOption privilege option
type PrivilegeOption struct {
Level PrivilegeLevel `json:"level"`
LevelDesc string `json:"level_desc"`
Privileges []*constant.Privilege `json:"privileges"`
}
@ -312,21 +312,27 @@ var (
)
func init() {
for _, option := range []PrivilegeLevel{PrivilegeLevel1, PrivilegeLevel2, PrivilegeLevel3} {
op := &PrivilegeOption{
Level: option,
}
DefaultPrivilegeOptions = append(DefaultPrivilegeOptions, &PrivilegeOption{
Level: PrivilegeLevel1,
LevelDesc: reason.PrivilegeLevel1Desc,
}, &PrivilegeOption{
Level: PrivilegeLevel2,
LevelDesc: reason.PrivilegeLevel2Desc,
}, &PrivilegeOption{
Level: PrivilegeLevel3,
LevelDesc: reason.PrivilegeLevel3Desc,
})
for _, option := range DefaultPrivilegeOptions {
for _, privilege := range constant.RankAllPrivileges {
if len(privilegeOptionsLevelMapping[privilege.Key]) == 0 {
fmt.Println("privilege key not found: ", privilege.Key)
continue
}
op.Privileges = append(op.Privileges, &constant.Privilege{
option.Privileges = append(option.Privileges, &constant.Privilege{
Label: privilege.Label,
Value: privilegeOptionsLevelMapping[privilege.Key][option-1],
Value: privilegeOptionsLevelMapping[privilege.Key][option.Level-1],
Key: privilege.Key,
})
}
DefaultPrivilegeOptions = append(DefaultPrivilegeOptions, op)
}
}

View File

@ -68,7 +68,7 @@ type UserCenterUserSettingsResp struct {
}
type UserCenterAdminFunctionAgentResp struct {
RoleAgentEnabled bool `json:"role_agent_enabled"`
UserStatusAgentEnabled bool `json:"user_status_agent_enabled"`
}
type UserSettingAgent struct {

View File

@ -5,6 +5,7 @@ import (
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/pkg/token"
"github.com/answerdev/answer/plugin"
"github.com/segmentfault/pacman/log"
)
@ -52,6 +53,14 @@ func (as *AuthService) GetUserCacheInfo(ctx context.Context, accessToken string)
return nil, err
}
}
// try to get user status from user center
uc, ok := plugin.GetUserCenter()
if ok && len(userCacheInfo.ExternalID) > 0 {
if userStatus := uc.UserStatus(userCacheInfo.ExternalID); userStatus != plugin.UserStatusAvailable {
userCacheInfo.UserStatus = int(userStatus)
}
}
return userCacheInfo, nil
}

View File

@ -6,6 +6,7 @@ import (
"fmt"
"github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/entity"
@ -35,7 +36,7 @@ func NewSiteInfoService(
tagCommonService *tagcommon.TagCommonService,
configRepo config.ConfigRepo,
) *SiteInfoService {
resp, err := siteInfoCommonService.GetSiteInterface(context.Background())
resp, err := siteInfoCommonService.GetSiteUsers(context.Background())
if err != nil {
log.Error(err)
} else {
@ -131,29 +132,18 @@ func (s *SiteInfoService) SaveSiteGeneral(ctx context.Context, req schema.SiteGe
}
func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.SiteInterfaceReq) (err error) {
var (
siteType = "interface"
content []byte
)
// check language
if !translator.CheckLanguageIsValid(req.Language) {
err = errors.BadRequest(reason.LangNotFound)
return
}
content, _ = json.Marshal(req)
content, _ := json.Marshal(req)
data := entity.SiteInfo{
Type: siteType,
Type: constant.SiteTypeInterface,
Content: string(content),
}
err = s.siteInfoRepo.SaveByType(ctx, siteType, &data)
if err == nil {
constant.DefaultAvatar = req.DefaultAvatar
}
return
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeInterface, &data)
}
// SaveSiteBranding save site branding information
@ -235,7 +225,11 @@ func (s *SiteInfoService) SaveSiteUsers(ctx context.Context, req *schema.SiteUse
Content: string(content),
Status: 1,
}
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeUsers, data)
err = s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeUsers, data)
if err == nil {
constant.DefaultAvatar = req.DefaultAvatar
}
return err
}
// GetSMTPConfig get smtp config
@ -329,8 +323,8 @@ func (s *SiteInfoService) GetPrivilegesConfig(ctx context.Context) (resp *schema
return nil, err
}
resp = &schema.GetPrivilegesConfigResp{
Options: schema.DefaultPrivilegeOptions,
SelectedLevel: schema.PrivilegeLevel2,
Options: s.translatePrivilegeOptions(ctx),
SelectedLevel: schema.PrivilegeLevel3,
}
if privilege != nil && privilege.Level > 0 {
resp.SelectedLevel = privilege.Level
@ -338,6 +332,25 @@ func (s *SiteInfoService) GetPrivilegesConfig(ctx context.Context) (resp *schema
return resp, nil
}
func (s *SiteInfoService) translatePrivilegeOptions(ctx context.Context) (options []*schema.PrivilegeOption) {
la := handler.GetLangByCtx(ctx)
for _, option := range schema.DefaultPrivilegeOptions {
op := &schema.PrivilegeOption{
Level: option.Level,
LevelDesc: translator.Tr(la, option.LevelDesc),
}
for _, privilege := range option.Privileges {
op.Privileges = append(op.Privileges, &constant.Privilege{
Key: privilege.Key,
Label: translator.Tr(la, privilege.Label),
Value: privilege.Value,
})
}
options = append(options, op)
}
return
}
func (s *SiteInfoService) UpdatePrivilegesConfig(ctx context.Context, req *schema.UpdatePrivilegesConfigReq) (err error) {
var chooseOption *schema.PrivilegeOption
for _, option := range schema.DefaultPrivilegeOptions {

View File

@ -150,7 +150,7 @@ func (us *UserCommon) MakeUsername(ctx context.Context, displayName string) (use
return username + suffix, nil
}
func (us *UserCommon) CacheLoginUserInfo(ctx context.Context, userID string, userStatus, emailStatus int) (
func (us *UserCommon) CacheLoginUserInfo(ctx context.Context, userID string, userStatus, emailStatus int, externalID string) (
accessToken string, userCacheInfo *entity.UserCacheInfo, err error) {
roleID, err := us.userRoleService.GetUserRole(ctx, userID)
if err != nil {
@ -162,6 +162,7 @@ func (us *UserCommon) CacheLoginUserInfo(ctx context.Context, userID string, use
EmailStatus: emailStatus,
UserStatus: userStatus,
RoleID: roleID,
ExternalID: externalID,
}
accessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo)

View File

@ -78,7 +78,7 @@ func (us *UserCenterLoginService) ExternalLogin(
log.Errorf("update user last login date failed: %v", err)
}
accessToken, _, err := us.userCommonService.CacheLoginUserInfo(
ctx, oldUserInfo.ID, oldUserInfo.MailStatus, oldUserInfo.Status)
ctx, oldUserInfo.ID, oldUserInfo.MailStatus, oldUserInfo.Status, oldExternalLoginUserInfo.ExternalID)
return &schema.UserExternalLoginResp{AccessToken: accessToken}, err
}
}
@ -97,7 +97,7 @@ func (us *UserCenterLoginService) ExternalLogin(
us.activeUser(ctx, oldUserInfo)
accessToken, _, err := us.userCommonService.CacheLoginUserInfo(
ctx, oldUserInfo.ID, oldUserInfo.MailStatus, oldUserInfo.Status)
ctx, oldUserInfo.ID, oldUserInfo.MailStatus, oldUserInfo.Status, oldExternalLoginUserInfo.ExternalID)
return &schema.UserExternalLoginResp{AccessToken: accessToken}, err
}
@ -203,7 +203,7 @@ func (us *UserCenterLoginService) UserCenterAdminFunctionAgent(ctx context.Conte
return
}
desc := userCenter.Description()
resp.RoleAgentEnabled = desc.RoleAgentEnabled
resp.UserStatusAgentEnabled = desc.UserStatusAgentEnabled
return resp, nil
}

View File

@ -83,7 +83,7 @@ func (us *UserExternalLoginService) ExternalLogin(
log.Error(err)
}
accessToken, _, err := us.userCommonService.CacheLoginUserInfo(
ctx, oldUserInfo.ID, newMailStatus, oldUserInfo.Status)
ctx, oldUserInfo.ID, newMailStatus, oldUserInfo.Status, oldExternalLoginUserInfo.ExternalID)
return &schema.UserExternalLoginResp{AccessToken: accessToken}, err
}
}
@ -122,7 +122,7 @@ func (us *UserExternalLoginService) ExternalLogin(
}
accessToken, _, err := us.userCommonService.CacheLoginUserInfo(
ctx, oldUserInfo.ID, newMailStatus, oldUserInfo.Status)
ctx, oldUserInfo.ID, newMailStatus, oldUserInfo.Status, oldExternalLoginUserInfo.ExternalID)
return &schema.UserExternalLoginResp{AccessToken: accessToken}, err
}
@ -251,7 +251,7 @@ func (us *UserExternalLoginService) ExternalLoginBindingUserSendEmail(
return nil, err
}
resp.AccessToken, _, err = us.userCommonService.CacheLoginUserInfo(
ctx, userInfo.ID, userInfo.MailStatus, userInfo.Status)
ctx, userInfo.ID, userInfo.MailStatus, userInfo.Status, externalLoginInfo.ExternalID)
if err != nil {
log.Error(err)
}

View File

@ -499,7 +499,7 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri
}
accessToken, userCacheInfo, err := us.userCommonService.CacheLoginUserInfo(
ctx, userInfo.ID, userInfo.MailStatus, userInfo.Status)
ctx, userInfo.ID, userInfo.MailStatus, userInfo.Status, "")
if err != nil {
return nil, err
}

View File

@ -12,6 +12,8 @@ type UserCenter interface {
SignUpCallback(ctx *GinContext) (userInfo *UserCenterBasicUserInfo, err error)
// UserInfo returns the user information
UserInfo(externalID string) (userInfo *UserCenterBasicUserInfo, err error)
// UserStatus returns the latest user status
UserStatus(externalID string) (userStatus UserStatus)
// UserList returns the user list information
UserList(externalIDs []string) (userInfo []*UserCenterBasicUserInfo, err error)
// UserSettings returns the user settings
@ -29,7 +31,7 @@ type UserCenterDesc struct {
LoginRedirectURL string `json:"login_redirect_url"`
SignUpRedirectURL string `json:"sign_up_redirect_url"`
RankAgentEnabled bool `json:"rank_agent_enabled"`
RoleAgentEnabled bool `json:"role_agent_enabled"`
UserStatusAgentEnabled bool `json:"user_status_agent_enabled"`
MustAuthEmailEnabled bool `json:"must_auth_email_enabled"`
}