Feat: hash id decode and verification

pull/247/head
HFO4 5 years ago
parent 880d224169
commit 94b13393a9

@ -197,8 +197,7 @@ func (policy *Policy) GetUploadURL() string {
var controller *url.URL var controller *url.URL
switch policy.Type { switch policy.Type {
case "local", "onedrive": case "local", "onedrive":
server = GetSiteURL() return "/api/v3/file/upload"
controller, _ = url.Parse("/api/v3/file/upload")
case "remote": case "remote":
controller, _ = url.Parse("/api/v3/slave/upload") controller, _ = url.Parse("/api/v3/slave/upload")
case "oss", "cos": case "oss", "cos":

@ -1,6 +1,7 @@
package model package model
import ( import (
"github.com/HFO4/cloudreve/pkg/hashid"
"github.com/HFO4/cloudreve/pkg/util" "github.com/HFO4/cloudreve/pkg/util"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"time" "time"
@ -29,3 +30,18 @@ func (share *Share) Create() (uint, error) {
} }
return share.ID, nil return share.ID, nil
} }
// GetShareByHashID 根据HashID查找分享
func GetShareByHashID(hashID string) *Share {
id, err := hashid.DecodeHashID(hashID, hashid.ShareID)
if err != nil {
return nil
}
var share Share
result := DB.First(&share, id)
if result.Error != nil {
return nil
}
return &share
}

@ -233,3 +233,17 @@ func (user *User) SetPassword(password string) error {
user.Password = salt + ":" + string(bs) user.Password = salt + ":" + string(bs)
return nil return nil
} }
// NewAnonymousUser 返回一个匿名用户
// TODO 测试
func NewAnonymousUser() *User {
user := User{}
user.Group, _ = GetGroupByID(3)
return &user
}
// IsAnonymous 返回是否为未登录用户
// TODO 测试
func (user *User) IsAnonymous() bool {
return user.ID == 0
}

@ -1,6 +1,9 @@
package hashid package hashid
import "github.com/HFO4/cloudreve/pkg/conf" import (
"errors"
"github.com/HFO4/cloudreve/pkg/conf"
)
import "github.com/speps/go-hashids" import "github.com/speps/go-hashids"
// ID类型 // ID类型
@ -9,6 +12,10 @@ const (
UserID // 用户 UserID // 用户
) )
var (
ErrTypeNotMatch = errors.New("ID类型不匹配")
)
// HashEncode 对给定数据计算HashID // HashEncode 对给定数据计算HashID
func HashEncode(v []int) (string, error) { func HashEncode(v []int) (string, error) {
hd := hashids.NewData() hd := hashids.NewData()
@ -26,8 +33,32 @@ func HashEncode(v []int) (string, error) {
return id, nil return id, nil
} }
// HashDecode 对给定数据计算原始数据
func HashDecode(raw string) ([]int, error) {
hd := hashids.NewData()
hd.Salt = conf.SystemConfig.HashIDSalt
h, err := hashids.NewWithData(hd)
if err != nil {
return []int{}, err
}
return h.DecodeWithError(raw)
}
// HashID 计算数据库内主键对应的HashID // HashID 计算数据库内主键对应的HashID
func HashID(id uint, t int) string { func HashID(id uint, t int) string {
v, _ := HashEncode([]int{int(id), t}) v, _ := HashEncode([]int{int(id), t})
return v return v
} }
// DecodeHashID 计算HashID对应的数据库ID
// TODO 测试
func DecodeHashID(id string, t int) (uint, error) {
v, _ := HashDecode(id)
if len(v) != 2 || v[1] != t {
return 0, ErrTypeNotMatch
}
return uint(v[0]), nil
}

@ -15,3 +15,14 @@ func CreateShare(c *gin.Context) {
c.JSON(200, ErrorResponse(err)) c.JSON(200, ErrorResponse(err))
} }
} }
// GetShare 查看分享
func GetShare(c *gin.Context) {
var service share.ShareGetService
if err := c.ShouldBindQuery(&service); err == nil {
res := service.Get(c)
c.JSON(200, res)
} else {
c.JSON(200, ErrorResponse(err))
}
}

@ -167,6 +167,13 @@ func InitMasterRouter() *gin.Engine {
) )
} }
// 分享相关
share := v3.Group("share")
{
// 获取分享
share.GET(":id", controllers.GetShare)
}
// 需要登录保护的 // 需要登录保护的
auth := v3.Group("") auth := v3.Group("")
auth.Use(middleware.AuthRequired()) auth.Use(middleware.AuthRequired())

@ -19,10 +19,14 @@ type ShareCreateService struct {
Score int `json:"score" binding:"gte=0"` Score int `json:"score" binding:"gte=0"`
} }
// ShareGetService 获取分享服务
type ShareGetService struct {
Password string `form:"password" binding:"max=255"`
}
// Create 创建新分享 // Create 创建新分享
func (service *ShareCreateService) Create(c *gin.Context) serializer.Response { func (service *ShareCreateService) Create(c *gin.Context) serializer.Response {
userCtx, _ := c.Get("user") user := currentUser(c)
user := userCtx.(*model.User)
// 是否拥有权限 // 是否拥有权限
if !user.Group.ShareEnabled { if !user.Group.ShareEnabled {
@ -80,3 +84,27 @@ func (service *ShareCreateService) Create(c *gin.Context) serializer.Response {
} }
} }
// Get 获取分享内容
func (service *ShareGetService) Get(c *gin.Context) serializer.Response {
user := currentUser(c)
share := model.GetShareByHashID(c.Param("id"))
if share == nil {
return serializer.Err(serializer.CodeNotFound, "分享不存在或已被取消", nil)
}
return serializer.Response{
Code: 0,
Data: user,
}
}
func currentUser(c *gin.Context) *model.User {
var user *model.User
if userCtx, ok := c.Get("user"); ok {
user = userCtx.(*model.User)
} else {
user = model.NewAnonymousUser()
}
return user
}

Loading…
Cancel
Save