feat(auth): 用户账户 - 完善个人资料与登录日志 (#752)
Co-authored-by: wuligao <1247662379@qq.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
func RegisterAuthRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
registerChannelOrderRoutes(r, svc)
|
||||
registerNotificationRoutes(r, svc)
|
||||
registerAuthProfileRoutes(r, svc)
|
||||
r.GET("/auth/settings", func(c *gin.Context) {
|
||||
settings, err := svc.PublicAuthSettings()
|
||||
if err != nil {
|
||||
@@ -41,6 +42,7 @@ func RegisterAuthRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
if !available || !enforceRateLimit(c, "register:"+c.ClientIP(), policy.Request.RegisterPerHour, time.Hour) {
|
||||
return
|
||||
}
|
||||
req.LoginContext = loginRequestContext(c)
|
||||
result, err := svc.Register(req)
|
||||
if err != nil {
|
||||
failService(c, err)
|
||||
@@ -113,7 +115,7 @@ func RegisterAuthRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
}
|
||||
ok(c, gin.H{"reset": true})
|
||||
})
|
||||
r.POST("/auth/login", func(c *gin.Context) {
|
||||
r.POST("/auth/login", rejectedLoginAudit(svc, "password"), func(c *gin.Context) {
|
||||
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 64<<10)
|
||||
var req service.LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -132,6 +134,8 @@ func RegisterAuthRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
if !enforceRateLimit(c, "login:"+c.ClientIP()+":"+subject, policy.Request.LoginAccountPerTenMinutes, 10*time.Minute) {
|
||||
return
|
||||
}
|
||||
req.LoginContext = loginRequestContext(c)
|
||||
c.Set("login_audit_handled", true)
|
||||
result, err := svc.Login(req)
|
||||
if err != nil {
|
||||
failService(c, err)
|
||||
@@ -152,9 +156,12 @@ func RegisterAuthRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
}
|
||||
c.Redirect(http.StatusFound, target)
|
||||
})
|
||||
r.GET("/auth/linuxdo/callback", linuxDOCallbackHandler(svc))
|
||||
r.GET("/auth/linuxdo/callback", rejectedLoginAudit(svc, "linuxdo"), linuxDOCallbackHandler(svc))
|
||||
r.POST("/auth/logout", func(c *gin.Context) {
|
||||
_ = svc.Logout(sessionCookie(c))
|
||||
if err := svc.Logout(sessionCookie(c), loginRequestContext(c)); err != nil {
|
||||
failService(c, err)
|
||||
return
|
||||
}
|
||||
clearSessionCookie(c)
|
||||
ok(c, gin.H{"ok": true})
|
||||
})
|
||||
@@ -207,7 +214,7 @@ func RegisterAuthRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
|
||||
// 兼容已在 Linux.do OAuth 应用中登记的传统回调地址,处理逻辑与 /api/auth/linuxdo/callback 完全一致。
|
||||
func RegisterOAuthCallbackRoutes(r gin.IRoutes, svc *service.Service) {
|
||||
r.GET("/oauth/linuxdo/callback", linuxDOCallbackHandler(svc))
|
||||
r.GET("/oauth/linuxdo/callback", rejectedLoginAudit(svc, "linuxdo"), linuxDOCallbackHandler(svc))
|
||||
}
|
||||
|
||||
func linuxDOCallbackHandler(svc *service.Service) gin.HandlerFunc {
|
||||
@@ -215,12 +222,27 @@ func linuxDOCallbackHandler(svc *service.Service) gin.HandlerFunc {
|
||||
if !enforceRateLimit(c, "linuxdo-callback:"+c.ClientIP(), 30, 10*time.Minute) {
|
||||
return
|
||||
}
|
||||
result, err := svc.CompleteLinuxDOLogin(c.Query("state"), c.Query("code"))
|
||||
reauthentication, stateErr := svc.LinuxDOReauthenticationState(c.Query("state"))
|
||||
if stateErr != nil {
|
||||
if err := svc.RecordRejectedLogin("linuxdo", loginRequestContext(c), 400); err != nil {
|
||||
log.Printf("OAuth rejected login audit write failed: error=%v", err)
|
||||
}
|
||||
c.Redirect(http.StatusFound, "/login?oauth_error="+url.QueryEscape("无法读取身份验证状态,请重试"))
|
||||
return
|
||||
}
|
||||
c.Set("login_audit_handled", true)
|
||||
result, err := svc.CompleteLinuxDOLogin(c.Query("state"), c.Query("code"), sessionCookie(c), loginRequestContext(c))
|
||||
if err != nil {
|
||||
if reauthentication {
|
||||
c.Redirect(http.StatusFound, "/settings?section=profile&reauth=error")
|
||||
return
|
||||
}
|
||||
c.Redirect(http.StatusFound, "/login?oauth_error="+url.QueryEscape(err.Error()))
|
||||
return
|
||||
}
|
||||
setSessionCookie(c, result.Session.Session, result.Session.MaxAgeSecs)
|
||||
if !result.Reauthenticated {
|
||||
setSessionCookie(c, result.Session.Session, result.Session.MaxAgeSecs)
|
||||
}
|
||||
c.Redirect(http.StatusFound, result.Next)
|
||||
}
|
||||
}
|
||||
@@ -230,6 +252,7 @@ func RegisterAdminRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
registerAdminChannelRoutes(r, svc)
|
||||
registerAdminSettingRoutes(r, svc)
|
||||
registerAdminAPILogRoutes(r, svc)
|
||||
registerAdminLoginLogRoutes(r, svc)
|
||||
}
|
||||
|
||||
func RegisterSystemProxyRoutes(r *gin.RouterGroup, svc *service.Service) {
|
||||
|
||||
Reference in New Issue
Block a user