mirror of https://github.com/cloudreve/Cloudreve
Feat: User/Me
parent
80f30465e9
commit
589c399488
|
@ -0,0 +1,38 @@
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"cloudreve/models"
|
||||||
|
"cloudreve/pkg/serializer"
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CurrentUser 获取登录用户
|
||||||
|
func CurrentUser() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
uid := session.Get("user_id")
|
||||||
|
if uid != nil {
|
||||||
|
user, err := model.GetUserByID(uid)
|
||||||
|
if err == nil {
|
||||||
|
c.Set("user", &user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthRequired 需要登录
|
||||||
|
func AuthRequired() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
if user, _ := c.Get("user"); user != nil {
|
||||||
|
if _, ok := user.(*model.User); ok {
|
||||||
|
c.Next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, serializer.CheckLogin())
|
||||||
|
c.Abort()
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,10 +6,13 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Store session存储
|
||||||
|
var Store memstore.Store
|
||||||
|
|
||||||
// Session 初始化session
|
// Session 初始化session
|
||||||
func Session(secret string) gin.HandlerFunc {
|
func Session(secret string) gin.HandlerFunc {
|
||||||
store := memstore.NewStore([]byte(secret))
|
Store = memstore.NewStore([]byte(secret))
|
||||||
//Also set Secure: true if using SSL, you should though
|
// Also set Secure: true if using SSL, you should though
|
||||||
store.Options(sessions.Options{HttpOnly: true, MaxAge: 7 * 86400, Path: "/"})
|
Store.Options(sessions.Options{HttpOnly: true, MaxAge: 7 * 86400, Path: "/"})
|
||||||
return sessions.Sessions("cloudreve-session", store)
|
return sessions.Sessions("cloudreve-session", Store)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSession(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
|
||||||
|
handler := Session("2333")
|
||||||
|
asserts.NotNil(handler)
|
||||||
|
asserts.NotNil(Store)
|
||||||
|
asserts.IsType(emptyFunc(), handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func emptyFunc() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cloudreve/pkg/serializer"
|
|
||||||
"cloudreve/pkg/util"
|
"cloudreve/pkg/util"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
@ -37,8 +36,14 @@ type User struct {
|
||||||
TwoFactor string `json:"-"`
|
TwoFactor string `json:"-"`
|
||||||
Delay int
|
Delay int
|
||||||
Avatar string
|
Avatar string
|
||||||
Options string `json:"-",gorm:"size:4096"`
|
Options string `json:"-",gorm:"size:4096"`
|
||||||
OptionsSerialized serializer.UserOption `gorm:"-"`
|
OptionsSerialized UserOption `gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserOption 用户个性化配置字段
|
||||||
|
type UserOption struct {
|
||||||
|
ProfileOn int `json:"profile_on"`
|
||||||
|
WebDAVKey string `json:"webdav_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserByID 用ID获取用户
|
// GetUserByID 用ID获取用户
|
||||||
|
@ -57,7 +62,7 @@ func GetUserByEmail(email string) (User, error) {
|
||||||
|
|
||||||
// NewUser 返回一个新的空 User
|
// NewUser 返回一个新的空 User
|
||||||
func NewUser() User {
|
func NewUser() User {
|
||||||
options := serializer.UserOption{
|
options := UserOption{
|
||||||
ProfileOn: 1,
|
ProfileOn: 1,
|
||||||
}
|
}
|
||||||
optionsValue, _ := json.Marshal(&options)
|
optionsValue, _ := json.Marshal(&options)
|
||||||
|
|
|
@ -1,7 +1,40 @@
|
||||||
package serializer
|
package serializer
|
||||||
|
|
||||||
// UserOption 用户个性化配置字段
|
import "cloudreve/models"
|
||||||
type UserOption struct {
|
|
||||||
ProfileOn int `json:"profile_on"`
|
// CheckLogin 检查登录
|
||||||
WebDAVKey string `json:"webdav_key"`
|
func CheckLogin() Response {
|
||||||
|
return Response{
|
||||||
|
Code: CodeCheckLogin,
|
||||||
|
Msg: "未登录",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User 用户序列化器
|
||||||
|
type User struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Email string `json:"user_name"`
|
||||||
|
Nickname string `json:"nickname"`
|
||||||
|
Status int `json:"status"`
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildUser 序列化用户
|
||||||
|
func BuildUser(user model.User) User {
|
||||||
|
return User{
|
||||||
|
ID: user.ID,
|
||||||
|
Email: user.Email,
|
||||||
|
Nickname: user.Nick,
|
||||||
|
Status: user.Status,
|
||||||
|
Avatar: user.Avatar,
|
||||||
|
CreatedAt: user.CreatedAt.Unix(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildUserResponse 序列化用户响应
|
||||||
|
func BuildUserResponse(user model.User) Response {
|
||||||
|
return Response{
|
||||||
|
Data: BuildUser(user),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cloudreve/models"
|
||||||
"cloudreve/pkg/serializer"
|
"cloudreve/pkg/serializer"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"gopkg.in/go-playground/validator.v8"
|
"gopkg.in/go-playground/validator.v8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,3 +49,13 @@ func ErrorResponse(err error) serializer.Response {
|
||||||
|
|
||||||
return serializer.ParamErr("参数错误", err)
|
return serializer.ParamErr("参数错误", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentUser 获取当前用户
|
||||||
|
func CurrentUser(c *gin.Context) *model.User {
|
||||||
|
if user, _ := c.Get("user"); user != nil {
|
||||||
|
if u, ok := user.(*model.User); ok {
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cloudreve/pkg/serializer"
|
||||||
"cloudreve/service/user"
|
"cloudreve/service/user"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
@ -16,3 +17,11 @@ func UserLogin(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserMe 获取当前登录的用户
|
||||||
|
func UserMe(c *gin.Context) {
|
||||||
|
user := CurrentUser(c)
|
||||||
|
res := serializer.BuildUserResponse(*user)
|
||||||
|
c.JSON(200, res)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// InitRouter 初始化路由
|
||||||
func InitRouter() *gin.Engine {
|
func InitRouter() *gin.Engine {
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
// 中间件
|
// 中间件
|
||||||
r.Use(middleware.Session(conf.SystemConfig.SessionSecret))
|
r.Use(middleware.Session(conf.SystemConfig.SessionSecret))
|
||||||
|
r.Use(middleware.CurrentUser())
|
||||||
|
|
||||||
// 顶层路由分组
|
// 顶层路由分组
|
||||||
v3 := r.Group("/Api/V3")
|
v3 := r.Group("/Api/V3")
|
||||||
|
@ -21,6 +23,19 @@ func InitRouter() *gin.Engine {
|
||||||
// 用户登录
|
// 用户登录
|
||||||
v3.POST("User/Session", controllers.UserLogin)
|
v3.POST("User/Session", controllers.UserLogin)
|
||||||
|
|
||||||
|
// 需要登录保护的
|
||||||
|
auth := v3.Group("")
|
||||||
|
auth.Use(middleware.AuthRequired())
|
||||||
|
{
|
||||||
|
// 用户类
|
||||||
|
user := auth.Group("User")
|
||||||
|
{
|
||||||
|
// 当前登录用户信息
|
||||||
|
user.GET("Me", controllers.UserMe)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,6 @@ func (service *UserLoginService) Login(c *gin.Context) serializer.Response {
|
||||||
"user_id": expectedUser.ID,
|
"user_id": expectedUser.ID,
|
||||||
})
|
})
|
||||||
|
|
||||||
return serializer.Response{
|
return serializer.BuildUserResponse(expectedUser)
|
||||||
Code: 0,
|
|
||||||
Data: &expectedUser,
|
|
||||||
Msg: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue