Force relogin after webui data changes
- Add a force_relogin flag to user_pref - Return 404 for main.php requests when the user must reauthenticate - Clear the relogin flag after successful client login - Mark users for relogin after webui card import, accessory changes, and profile updates Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"honoka-chan/internal/middleware"
|
"honoka-chan/internal/middleware"
|
||||||
|
usermodel "honoka-chan/internal/model/user"
|
||||||
"honoka-chan/internal/router"
|
"honoka-chan/internal/router"
|
||||||
loginschema "honoka-chan/internal/schema/login"
|
loginschema "honoka-chan/internal/schema/login"
|
||||||
"honoka-chan/internal/session"
|
"honoka-chan/internal/session"
|
||||||
@@ -68,6 +69,10 @@ func login(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := usermodel.ClearUserForceRelogin(ss.UserEng, userID); ss.CheckErr(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ss.Respond(loginschema.LoginResp{
|
ss.Respond(loginschema.LoginResp{
|
||||||
ResponseData: loginschema.LoginData{
|
ResponseData: loginschema.LoginData{
|
||||||
AuthorizeToken: authorizeToken,
|
AuthorizeToken: authorizeToken,
|
||||||
|
|||||||
@@ -23,6 +23,17 @@ type accessoryInventoryItem struct {
|
|||||||
WornCount int `json:"worn_count"`
|
WornCount int `json:"worn_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func markAccessoryUserForceRelogin(ctx *gin.Context) bool {
|
||||||
|
if err := usermodel.MarkUserForceRelogin(db.UserEng, ctx.GetInt("userid")); err != nil {
|
||||||
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
|
Code: 1,
|
||||||
|
Message: "操作成功,但登录状态刷新失败!",
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func accessoryPage(ctx *gin.Context) {
|
func accessoryPage(ctx *gin.Context) {
|
||||||
ctx.HTML(http.StatusOK, "admin/accessory.html", gin.H{
|
ctx.HTML(http.StatusOK, "admin/accessory.html", gin.H{
|
||||||
"menu": 3,
|
"menu": 3,
|
||||||
@@ -121,6 +132,10 @@ func addAccessory(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !markAccessoryUserForceRelogin(ctx) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, webuischema.Msg{
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
Message: "添加成功,请重新进入游戏查看!",
|
Message: "添加成功,请重新进入游戏查看!",
|
||||||
@@ -322,6 +337,10 @@ func deleteAccessory(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !markAccessoryUserForceRelogin(ctx) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, webuischema.Msg{
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
Message: "删除成功,请重新登录游戏生效!",
|
Message: "删除成功,请重新登录游戏生效!",
|
||||||
|
|||||||
@@ -147,6 +147,14 @@ func updateProfile(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := usermodel.MarkUserForceRelogin(db.UserEng, ctx.GetInt("userid")); err != nil {
|
||||||
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
|
Code: 1,
|
||||||
|
Message: "保存成功,但登录状态刷新失败!",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, webuischema.Msg{
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
Message: "保存成功!",
|
Message: "保存成功!",
|
||||||
@@ -195,6 +203,14 @@ func resetProfile(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := usermodel.MarkUserForceRelogin(db.UserEng, ctx.GetInt("userid")); err != nil {
|
||||||
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
|
Code: 1,
|
||||||
|
Message: "重置成功,但登录状态刷新失败!",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, webuischema.Msg{
|
ctx.JSON(http.StatusOK, webuischema.Msg{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
Message: "已恢复默认值!",
|
Message: "已恢复默认值!",
|
||||||
|
|||||||
@@ -111,6 +111,11 @@ func upload(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := usermodel.MarkUserForceRelogin(db.UserEng, ctx.GetInt("userid")); err != nil {
|
||||||
|
ctx.JSON(http.StatusOK, ErrMsg{Error: 1, Msg: "卡片添加成功,但登录状态刷新失败!"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, ErrMsg{Error: 0, Msg: "导入成功,请重新打开游戏!"})
|
ctx.JSON(http.StatusOK, ErrMsg{Error: 0, Msg: "导入成功,请重新打开游戏!"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,16 +11,6 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckErr(ctx *gin.Context, err error) bool {
|
|
||||||
if err != nil {
|
|
||||||
ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
|
|
||||||
"code": 20001,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return err != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Common(ctx *gin.Context) {
|
func Common(ctx *gin.Context) {
|
||||||
reqData := ""
|
reqData := ""
|
||||||
if form, err := ctx.MultipartForm(); err == nil {
|
if form, err := ctx.MultipartForm(); err == nil {
|
||||||
@@ -39,9 +29,17 @@ func Common(ctx *gin.Context) {
|
|||||||
ss := session.Attach(ctx)
|
ss := session.Attach(ctx)
|
||||||
ctx.Set("session", ss)
|
ctx.Set("session", ss)
|
||||||
|
|
||||||
|
if ctx.Request.URL.Path != "/login/authkey" && ctx.Request.URL.Path != "/login/login" {
|
||||||
|
if ss.UserPref.ForceRelogin {
|
||||||
|
ctx.AbortWithStatus(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
authorize := ctx.GetHeader("Authorize")
|
authorize := ctx.GetHeader("Authorize")
|
||||||
params, err := url.ParseQuery(authorize)
|
params, err := url.ParseQuery(authorize)
|
||||||
if CheckErr(ctx, err) {
|
if err != nil {
|
||||||
|
ctx.AbortWithStatus(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CurrentUserPrefProfileVersion = 2
|
const CurrentUserPrefProfileVersion = 2
|
||||||
@@ -40,6 +42,7 @@ type UserPref struct {
|
|||||||
OverMaxEnergy int `xorm:"over_max_energy"`
|
OverMaxEnergy int `xorm:"over_max_energy"`
|
||||||
BirthMonth int `xorm:"birth_month"`
|
BirthMonth int `xorm:"birth_month"`
|
||||||
BirthDay int `xorm:"birth_day"`
|
BirthDay int `xorm:"birth_day"`
|
||||||
|
ForceRelogin bool `xorm:"force_relogin"`
|
||||||
ProfileVersion int `xorm:"profile_version"`
|
ProfileVersion int `xorm:"profile_version"`
|
||||||
UpdateTime int64 `xorm:"update_time"`
|
UpdateTime int64 `xorm:"update_time"`
|
||||||
}
|
}
|
||||||
@@ -154,10 +157,27 @@ func UserPrefProfileColumns() []string {
|
|||||||
"over_max_energy",
|
"over_max_energy",
|
||||||
"birth_month",
|
"birth_month",
|
||||||
"birth_day",
|
"birth_day",
|
||||||
|
"force_relogin",
|
||||||
"profile_version",
|
"profile_version",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MarkUserForceRelogin(exec xorm.Interface, userID int) error {
|
||||||
|
_, err := exec.Table(new(UserPref)).
|
||||||
|
Where("user_id = ?", userID).
|
||||||
|
Cols("force_relogin").
|
||||||
|
Update(&UserPref{ForceRelogin: true})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClearUserForceRelogin(exec xorm.Interface, userID int) error {
|
||||||
|
_, err := exec.Table(new(UserPref)).
|
||||||
|
Where("user_id = ?", userID).
|
||||||
|
Cols("force_relogin").
|
||||||
|
Update(&UserPref{ForceRelogin: false})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (UserPref) TableName() string {
|
func (UserPref) TableName() string {
|
||||||
return "user_pref"
|
return "user_pref"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user