Feat: hash id decode and verification

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

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

@ -1,6 +1,7 @@
package model
import (
"github.com/HFO4/cloudreve/pkg/hashid"
"github.com/HFO4/cloudreve/pkg/util"
"github.com/jinzhu/gorm"
"time"
@ -29,3 +30,18 @@ func (share *Share) Create() (uint, error) {
}
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)
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
import "github.com/HFO4/cloudreve/pkg/conf"
import (
"errors"
"github.com/HFO4/cloudreve/pkg/conf"
)
import "github.com/speps/go-hashids"
// ID类型
@ -9,6 +12,10 @@ const (
UserID // 用户
)
var (
ErrTypeNotMatch = errors.New("ID类型不匹配")
)
// HashEncode 对给定数据计算HashID
func HashEncode(v []int) (string, error) {
hd := hashids.NewData()
@ -26,8 +33,32 @@ func HashEncode(v []int) (string, error) {
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
func HashID(id uint, t int) string {
v, _ := HashEncode([]int{int(id), t})
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))
}
}
// 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.Use(middleware.AuthRequired())

@ -19,10 +19,14 @@ type ShareCreateService struct {
Score int `json:"score" binding:"gte=0"`
}
// ShareGetService 获取分享服务
type ShareGetService struct {
Password string `form:"password" binding:"max=255"`
}
// Create 创建新分享
func (service *ShareCreateService) Create(c *gin.Context) serializer.Response {
userCtx, _ := c.Get("user")
user := userCtx.(*model.User)
user := currentUser(c)
// 是否拥有权限
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