Skip to content

Commit 1de9ef6

Browse files
committed
Merge remote-tracking branch 'github/feat/1.1.1/user-center' into beta.2/1.1.0
# Conflicts: # go.mod # i18n/en_US.yaml # internal/base/reason/reason.go
2 parents d61e0da + d641bdf commit 1de9ef6

28 files changed

+864
-60
lines changed

cmd/wire_gen.go

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.sum

Lines changed: 49 additions & 3 deletions
Large diffs are not rendered by default.

i18n/en_US.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ backend:
1212
other: Unauthorized.
1313
database_error:
1414
other: Data server error.
15+
forbidden_error:
16+
other: Forbidden.
1517
action:
1618
report:
1719
other: Flag
@@ -552,7 +554,7 @@ ui:
552554
tip_answer: >-
553555
Use comments to reply to other users or notify them of changes. If you are
554556
adding new information, edit your post instead of commenting.
555-
tip_vote: It adds something useful to the post
557+
tip_vote: It adds something useful to the post
556558
edit_answer:
557559
title: Edit Answer
558560
default_reason: Edit answer
@@ -835,8 +837,8 @@ ui:
835837
closed_in: Closed in
836838
show_exist: Show existing question.
837839
useful: Useful
838-
question_useful: It is useful and clear
839-
question_un_useful: It is unclear or not useful
840+
question_useful: It is useful and clear
841+
question_un_useful: It is unclear or not useful
840842
answer_useful: It is useful
841843
answer_un_useful: It is not useful
842844
answers:

i18n/zh_CN.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ ui:
691691
label: 确认新密码
692692
settings:
693693
page_title: 设置
694+
goto_modify: 前往修改
694695
nav:
695696
profile: 我的资料
696697
notification: 通知
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package middleware
2+
3+
import (
4+
"github.com/answerdev/answer/internal/base/handler"
5+
"github.com/answerdev/answer/internal/base/reason"
6+
"github.com/answerdev/answer/plugin"
7+
"github.com/gin-gonic/gin"
8+
"github.com/segmentfault/pacman/errors"
9+
)
10+
11+
// BanAPIWhenUserCenterEnabled ban api when user center enabled
12+
func BanAPIWhenUserCenterEnabled(ctx *gin.Context) {
13+
if plugin.UserCenterEnabled() {
14+
handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil)
15+
ctx.Abort()
16+
return
17+
}
18+
ctx.Next()
19+
}

internal/base/reason/reason.go

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const (
1111
UnauthorizedError = "base.unauthorized_error"
1212
// DatabaseError database error
1313
DatabaseError = "base.database_error"
14+
// ForbiddenError forbidden error
15+
ForbiddenError = "base.forbidden_error"
1416
)
1517

1618
const (
@@ -25,7 +27,7 @@ const (
2527
AnswerNotFound = "error.answer.not_found"
2628
AnswerCannotDeleted = "error.answer.cannot_deleted"
2729
AnswerCannotUpdate = "error.answer.cannot_update"
28-
AnswerCannotAddByClosedQuestion = "error.answer.question_closed_cannot_add"
30+
AnswerCannotAddByClosedQuestion = "error.answer.question_closed_cannot_add"
2931
CommentEditWithoutPermission = "error.comment.edit_without_permission"
3032
DisallowVote = "error.object.disallow_vote"
3133
DisallowFollow = "error.object.disallow_follow"
@@ -46,29 +48,29 @@ const (
4648
TagNotContainSynonym = "error.tag.not_contain_synonym_tags"
4749
TagCannotUpdate = "error.tag.cannot_update"
4850
TagIsUsedCannotDelete = "error.tag.is_used_cannot_delete"
49-
TagAlreadyExist = "error.tag.already_exist"
50-
RankFailToMeetTheCondition = "error.rank.fail_to_meet_the_condition"
51+
TagAlreadyExist = "error.tag.already_exist"
52+
RankFailToMeetTheCondition = "error.rank.fail_to_meet_the_condition"
5153
VoteRankFailToMeetTheCondition = "error.rank.vote_fail_to_meet_the_condition"
52-
ThemeNotFound = "error.theme.not_found"
53-
LangNotFound = "error.lang.not_found"
54-
ReportHandleFailed = "error.report.handle_failed"
55-
ReportNotFound = "error.report.not_found"
56-
ReadConfigFailed = "error.config.read_config_failed"
57-
DatabaseConnectionFailed = "error.database.connection_failed"
58-
InstallCreateTableFailed = "error.database.create_table_failed"
59-
InstallConfigFailed = "error.install.create_config_failed"
60-
SiteInfoNotFound = "error.site_info.not_found"
61-
UploadFileSourceUnsupported = "error.upload.source_unsupported"
62-
UploadFileUnsupportedFileFormat = "error.upload.unsupported_file_format"
63-
RecommendTagNotExist = "error.tag.recommend_tag_not_found"
64-
RecommendTagEnter = "error.tag.recommend_tag_enter"
65-
RevisionReviewUnderway = "error.revision.review_underway"
66-
RevisionNoPermission = "error.revision.no_permission"
67-
UserCannotUpdateYourRole = "error.user.cannot_update_your_role"
68-
TagCannotSetSynonymAsItself = "error.tag.cannot_set_synonym_as_itself"
69-
NotAllowedRegistration = "error.user.not_allowed_registration"
70-
SMTPConfigFromNameCannotBeEmail = "error.smtp.config_from_name_cannot_be_email"
71-
AdminCannotUpdateTheirPassword = "error.admin.cannot_update_their_password"
72-
AdminCannotModifySelfStatus = "error.admin.cannot_modify_self_status"
54+
ThemeNotFound = "error.theme.not_found"
55+
LangNotFound = "error.lang.not_found"
56+
ReportHandleFailed = "error.report.handle_failed"
57+
ReportNotFound = "error.report.not_found"
58+
ReadConfigFailed = "error.config.read_config_failed"
59+
DatabaseConnectionFailed = "error.database.connection_failed"
60+
InstallCreateTableFailed = "error.database.create_table_failed"
61+
InstallConfigFailed = "error.install.create_config_failed"
62+
SiteInfoNotFound = "error.site_info.not_found"
63+
UploadFileSourceUnsupported = "error.upload.source_unsupported"
64+
UploadFileUnsupportedFileFormat = "error.upload.unsupported_file_format"
65+
RecommendTagNotExist = "error.tag.recommend_tag_not_found"
66+
RecommendTagEnter = "error.tag.recommend_tag_enter"
67+
RevisionReviewUnderway = "error.revision.review_underway"
68+
RevisionNoPermission = "error.revision.no_permission"
69+
UserCannotUpdateYourRole = "error.user.cannot_update_your_role"
70+
TagCannotSetSynonymAsItself = "error.tag.cannot_set_synonym_as_itself"
71+
NotAllowedRegistration = "error.user.not_allowed_registration"
72+
SMTPConfigFromNameCannotBeEmail = "error.smtp.config_from_name_cannot_be_email"
73+
AdminCannotUpdateTheirPassword = "error.admin.cannot_update_their_password"
74+
AdminCannotModifySelfStatus = "error.admin.cannot_modify_self_status"
7375
UserExternalLoginUnbindingForbidden = "error.user.external_login_unbinding_forbidden"
7476
)

internal/controller/controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ var ProviderSetController = wire.NewSet(
2525
NewActivityController,
2626
NewTemplateController,
2727
NewConnectorController,
28+
NewUserCenterController,
2829
)
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package controller
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
"github.com/answerdev/answer/internal/base/handler"
8+
"github.com/answerdev/answer/internal/base/middleware"
9+
"github.com/answerdev/answer/internal/schema"
10+
"github.com/answerdev/answer/internal/service/siteinfo_common"
11+
"github.com/answerdev/answer/internal/service/user_external_login"
12+
"github.com/answerdev/answer/plugin"
13+
"github.com/gin-gonic/gin"
14+
"github.com/segmentfault/pacman/log"
15+
)
16+
17+
const (
18+
UserCenterLoginRouter = "/user-center/login/redirect"
19+
UserCenterSignUpRedirectRouter = "/user-center/sign-up/redirect"
20+
)
21+
22+
// UserCenterController comment controller
23+
type UserCenterController struct {
24+
userCenterLoginService *user_external_login.UserCenterLoginService
25+
siteInfoService *siteinfo_common.SiteInfoCommonService
26+
}
27+
28+
// NewUserCenterController new controller
29+
func NewUserCenterController(
30+
userCenterLoginService *user_external_login.UserCenterLoginService,
31+
siteInfoService *siteinfo_common.SiteInfoCommonService,
32+
) *UserCenterController {
33+
return &UserCenterController{
34+
userCenterLoginService: userCenterLoginService,
35+
siteInfoService: siteInfoService,
36+
}
37+
}
38+
39+
// UserCenterAgent get user center agent info
40+
func (uc *UserCenterController) UserCenterAgent(ctx *gin.Context) {
41+
resp := &schema.UserCenterAgentResp{}
42+
resp.Enabled = plugin.UserCenterEnabled()
43+
if !resp.Enabled {
44+
handler.HandleResponse(ctx, nil, resp)
45+
return
46+
}
47+
siteGeneral, err := uc.siteInfoService.GetSiteGeneral(ctx)
48+
if err != nil {
49+
log.Errorf("get site info failed: %v", err)
50+
ctx.Redirect(http.StatusFound, "/50x")
51+
return
52+
}
53+
54+
resp.AgentInfo = &schema.AgentInfo{}
55+
resp.AgentInfo.LoginRedirectURL = fmt.Sprintf("%s%s%s", siteGeneral.SiteUrl,
56+
commonRouterPrefix, UserCenterLoginRouter)
57+
resp.AgentInfo.SignUpRedirectURL = fmt.Sprintf("%s%s%s", siteGeneral.SiteUrl,
58+
commonRouterPrefix, UserCenterSignUpRedirectRouter)
59+
60+
_ = plugin.CallUserCenter(func(uc plugin.UserCenter) error {
61+
info := uc.Description()
62+
resp.AgentInfo.Name = info.Name
63+
resp.AgentInfo.Icon = info.Icon
64+
resp.AgentInfo.Url = info.Url
65+
resp.AgentInfo.ControlCenterItems = make([]*schema.ControlCenter, 0)
66+
items := uc.ControlCenterItems()
67+
for _, item := range items {
68+
resp.AgentInfo.ControlCenterItems = append(resp.AgentInfo.ControlCenterItems, &schema.ControlCenter{
69+
Name: item.Name,
70+
Label: item.Label,
71+
Url: item.Url,
72+
})
73+
}
74+
return nil
75+
})
76+
77+
handler.HandleResponse(ctx, nil, resp)
78+
}
79+
80+
// UserCenterPersonalBranding get user center personal user info
81+
func (uc *UserCenterController) UserCenterPersonalBranding(ctx *gin.Context) {
82+
req := &schema.GetOtherUserInfoByUsernameReq{}
83+
if handler.BindAndCheck(ctx, req) {
84+
return
85+
}
86+
87+
resp, err := uc.userCenterLoginService.UserCenterPersonalBranding(ctx, req.Username)
88+
handler.HandleResponse(ctx, err, resp)
89+
}
90+
91+
func (uc *UserCenterController) UserCenterLoginRedirect(ctx *gin.Context) {
92+
var redirectURL string
93+
_ = plugin.CallUserCenter(func(uc plugin.UserCenter) error {
94+
info := uc.Description()
95+
redirectURL = info.LoginRedirectURL
96+
return nil
97+
})
98+
ctx.Redirect(http.StatusFound, redirectURL)
99+
}
100+
101+
func (uc *UserCenterController) UserCenterSignUpRedirect(ctx *gin.Context) {
102+
var redirectURL string
103+
_ = plugin.CallUserCenter(func(uc plugin.UserCenter) error {
104+
info := uc.Description()
105+
redirectURL = info.SignUpRedirectURL
106+
return nil
107+
})
108+
ctx.Redirect(http.StatusFound, redirectURL)
109+
}
110+
111+
func (uc *UserCenterController) UserCenterLoginCallback(ctx *gin.Context) {
112+
siteGeneral, err := uc.siteInfoService.GetSiteGeneral(ctx)
113+
if err != nil {
114+
log.Errorf("get site info failed: %v", err)
115+
ctx.Redirect(http.StatusFound, "/50x")
116+
return
117+
}
118+
119+
userCenter, ok := plugin.GetUserCenter()
120+
if !ok {
121+
ctx.Redirect(http.StatusFound, "/404")
122+
return
123+
}
124+
userInfo, err := userCenter.LoginCallback(ctx)
125+
if err != nil {
126+
log.Error(err)
127+
ctx.Redirect(http.StatusFound, "/50x")
128+
return
129+
}
130+
131+
resp, err := uc.userCenterLoginService.ExternalLogin(ctx, userCenter.Info().SlugName, userInfo)
132+
if err != nil {
133+
log.Errorf("external login failed: %v", err)
134+
ctx.Redirect(http.StatusFound, "/50x")
135+
return
136+
}
137+
ctx.Redirect(http.StatusFound, fmt.Sprintf("%s/users/oauth?access_token=%s",
138+
siteGeneral.SiteUrl, resp.AccessToken))
139+
}
140+
141+
func (uc *UserCenterController) UserCenterSignUpCallback(ctx *gin.Context) {
142+
siteGeneral, err := uc.siteInfoService.GetSiteGeneral(ctx)
143+
if err != nil {
144+
log.Errorf("get site info failed: %v", err)
145+
ctx.Redirect(http.StatusFound, "/50x")
146+
return
147+
}
148+
149+
userCenter, ok := plugin.GetUserCenter()
150+
if !ok {
151+
ctx.Redirect(http.StatusFound, "/404")
152+
return
153+
}
154+
userInfo, err := userCenter.SignUpCallback(ctx)
155+
if err != nil {
156+
log.Error(err)
157+
ctx.Redirect(http.StatusFound, "/50x")
158+
return
159+
}
160+
161+
resp, err := uc.userCenterLoginService.ExternalLogin(ctx, userCenter.Info().SlugName, userInfo)
162+
if err != nil {
163+
log.Errorf("external login failed: %v", err)
164+
ctx.Redirect(http.StatusFound, "/50x")
165+
return
166+
}
167+
ctx.Redirect(http.StatusFound, fmt.Sprintf("%s/users/oauth?access_token=%s",
168+
siteGeneral.SiteUrl, resp.AccessToken))
169+
}
170+
171+
// UserCenterUserSettings user center user settings
172+
func (uc *UserCenterController) UserCenterUserSettings(ctx *gin.Context) {
173+
userID := middleware.GetLoginUserIDFromContext(ctx)
174+
resp, err := uc.userCenterLoginService.UserCenterUserSettings(ctx, userID)
175+
handler.HandleResponse(ctx, err, resp)
176+
}

internal/controller/question_controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,9 @@ func (qc *QuestionController) AdminSearchAnswerList(ctx *gin.Context) {
668668
return
669669
}
670670
req.QuestionID = uid.DeShortID(req.QuestionID)
671+
if req.QuestionID == "0" {
672+
req.QuestionID = ""
673+
}
671674
userID := middleware.GetLoginUserIDFromContext(ctx)
672675
questionList, count, err := qc.questionService.AdminSearchAnswerList(ctx, req, userID)
673676
handler.HandleResponse(ctx, err, gin.H{

internal/controller_admin/user_backyard_controller.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ package controller_admin
33
import (
44
"github.com/answerdev/answer/internal/base/handler"
55
"github.com/answerdev/answer/internal/base/middleware"
6+
"github.com/answerdev/answer/internal/base/reason"
67
"github.com/answerdev/answer/internal/schema"
78
"github.com/answerdev/answer/internal/service/user_admin"
9+
"github.com/answerdev/answer/plugin"
810
"github.com/gin-gonic/gin"
11+
"github.com/segmentfault/pacman/errors"
912
)
1013

1114
// UserAdminController user controller
@@ -29,6 +32,10 @@ func NewUserAdminController(userService *user_admin.UserAdminService) *UserAdmin
2932
// @Success 200 {object} handler.RespBody
3033
// @Router /answer/admin/api/user/status [put]
3134
func (uc *UserAdminController) UpdateUserStatus(ctx *gin.Context) {
35+
if plugin.UserCenterEnabled() {
36+
handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil)
37+
return
38+
}
3239
req := &schema.UpdateUserStatusReq{}
3340
if handler.BindAndCheck(ctx, req) {
3441
return
@@ -73,6 +80,10 @@ func (uc *UserAdminController) UpdateUserRole(ctx *gin.Context) {
7380
// @Success 200 {object} handler.RespBody
7481
// @Router /answer/admin/api/user [post]
7582
func (uc *UserAdminController) AddUser(ctx *gin.Context) {
83+
if plugin.UserCenterEnabled() {
84+
handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil)
85+
return
86+
}
7687
req := &schema.AddUserReq{}
7788
if handler.BindAndCheck(ctx, req) {
7889
return
@@ -95,6 +106,10 @@ func (uc *UserAdminController) AddUser(ctx *gin.Context) {
95106
// @Success 200 {object} handler.RespBody
96107
// @Router /answer/admin/api/user/password [put]
97108
func (uc *UserAdminController) UpdateUserPassword(ctx *gin.Context) {
109+
if plugin.UserCenterEnabled() {
110+
handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil)
111+
return
112+
}
98113
req := &schema.UpdateUserPasswordReq{}
99114
if handler.BindAndCheck(ctx, req) {
100115
return

0 commit comments

Comments
 (0)