Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions internal/db/sharing.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ func UpdateSharing(s *model.SharingDB) error {
return errors.WithStack(db.Save(s).Error)
}

func UpdateSharingId(oldId, newId string) error {
// Check if new ID already exists
if err := db.Where("id = ?", newId).First(&model.SharingDB{}).Error; err == nil {
return errors.New("sharing id already exists")
}
return errors.WithStack(db.Model(&model.SharingDB{}).Where("id = ?", oldId).Update("id", newId).Error)
}

func DeleteSharingById(id string) error {
s := model.SharingDB{ID: id}
return errors.WithStack(db.Where(s).Delete(&s).Error)
Expand Down
2 changes: 1 addition & 1 deletion internal/model/sharing.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package model
import "time"

type SharingDB struct {
ID string `json:"id" gorm:"type:char(12);primaryKey"`
ID string `json:"id" gorm:"type:varchar(64);primaryKey"`
FilesRaw string `json:"-" gorm:"type:text"`
Expires *time.Time `json:"expires"`
Pwd string `json:"pwd"`
Expand Down
9 changes: 9 additions & 0 deletions internal/model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type User struct {
// 12: can read archives
// 13: can decompress archives
// 14: can share
// 15: can customize share id
Permission int32 `json:"permission"`
OtpSecret string `json:"-"`
SsoID string `json:"sso_id"` // unique by sso platform
Expand Down Expand Up @@ -219,6 +220,14 @@ func (u *User) CanShare() bool {
return CanShare(u.Permission)
}

func CanCustomizeShareID(permission int32) bool {
return (permission>>15)&1 == 1
}

func (u *User) CanCustomizeShareID() bool {
return CanCustomizeShareID(u.Permission)
}

func (u *User) JoinPath(reqPath string) (string, error) {
return utils.JoinBasePath(u.BasePath, reqPath)
}
Expand Down
9 changes: 9 additions & 0 deletions internal/op/sharing.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ func UpdateSharing(sharing *model.Sharing, skipMarshal ...bool) (err error) {
return db.UpdateSharing(sharing.SharingDB)
}

func UpdateSharingId(sharing *model.Sharing, newId string) error {
sharingCache.Del(sharing.ID)
if err := db.UpdateSharingId(sharing.ID, newId); err != nil {
return err
}
sharing.ID = newId
return nil
}

func DeleteSharing(sid string) error {
sharingCache.Del(sid)
return db.DeleteSharingById(sid)
Expand Down
36 changes: 35 additions & 1 deletion server/handles/sharing.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package handles
import (
"fmt"
stdpath "path"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -416,6 +417,19 @@ type UpdateSharingReq struct {
CreatorName string `json:"creator"`
Accessed int `json:"accessed"`
ID string `json:"id"`
NewID string `json:"new_id"`
}

var validSharingID = regexp.MustCompile(`^[\w\p{Han}\-]+$`)

func validateSharingID(id string) error {
if len([]rune(id)) > 64 {
return errors.New("share id must be at most 64 characters")
}
if !validSharingID.MatchString(id) {
return errors.New("share id can only contain letters, numbers, underscores, hyphens, and CJK characters")
}
return nil
}

func UpdateSharing(c *gin.Context) {
Expand Down Expand Up @@ -471,6 +485,20 @@ func UpdateSharing(c *gin.Context) {
s.Readme = req.Readme
s.Remark = req.Remark
s.Creator = user
if req.NewID != "" && req.NewID != req.ID {
if !reqUser.CanCustomizeShareID() {
common.ErrorStrResp(c, "permission denied", 403)
return
}
if err = validateSharingID(req.NewID); err != nil {
common.ErrorResp(c, err, 400)
return
}
if err = op.UpdateSharingId(s, req.NewID); err != nil {
common.ErrorResp(c, err, 500)
return
}
}
if err = op.UpdateSharing(s); err != nil {
common.ErrorResp(c, err, 500)
} else {
Expand All @@ -493,6 +521,12 @@ func CreateSharing(c *gin.Context) {
common.ErrorStrResp(c, "must add at least 1 object", 400)
return
}
if req.ID != "" {
if err = validateSharingID(req.ID); err != nil {
common.ErrorResp(c, err, 400)
return
}
}
var user *model.User
reqUser := c.Request.Context().Value(conf.UserKey).(*model.User)
if reqUser.IsAdmin() && req.CreatorName != "" {
Expand All @@ -503,7 +537,7 @@ func CreateSharing(c *gin.Context) {
}
} else {
user = reqUser
if !user.CanShare() || (!user.IsAdmin() && req.ID != "") {
if !user.CanShare() || (!user.CanCustomizeShareID() && req.ID != "") {
common.ErrorStrResp(c, "permission denied", 403)
return
}
Expand Down
Loading