You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudreve/service/admin/share.go

162 lines
4.0 KiB

package admin
import (
"context"
"strconv"
"strings"
"github.com/cloudreve/Cloudreve/v4/application/dependency"
"github.com/cloudreve/Cloudreve/v4/ent"
"github.com/cloudreve/Cloudreve/v4/inventory"
"github.com/cloudreve/Cloudreve/v4/pkg/cluster/routes"
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
"github.com/cloudreve/Cloudreve/v4/pkg/serializer"
"github.com/gin-gonic/gin"
"github.com/samber/lo"
)
const (
shareUserIDCondition = "share_user_id"
shareFileIDCondition = "share_file_id"
shareIDCondition = "share_id"
)
func (s *AdminListService) Shares(c *gin.Context) (*ListShareResponse, error) {
dep := dependency.FromContext(c)
shareClient := dep.ShareClient()
hasher := dep.HashIDEncoder()
var (
err error
userID int
fileID int
shareIDs []int
)
if s.Conditions[shareUserIDCondition] != "" {
userID, err = strconv.Atoi(s.Conditions[shareUserIDCondition])
if err != nil {
return nil, serializer.NewError(serializer.CodeParamErr, "Invalid share user ID", err)
}
}
if s.Conditions[shareFileIDCondition] != "" {
fileID, err = strconv.Atoi(s.Conditions[shareFileIDCondition])
if err != nil {
return nil, serializer.NewError(serializer.CodeParamErr, "Invalid share file ID", err)
}
}
if s.Conditions[shareIDCondition] != "" {
shareIdStrs := strings.Split(s.Conditions[shareIDCondition], ",")
for _, shareIdStr := range shareIdStrs {
shareID, err := strconv.Atoi(shareIdStr)
if err != nil {
return nil, serializer.NewError(serializer.CodeParamErr, "Invalid share ID", err)
}
shareIDs = append(shareIDs, shareID)
}
}
ctx := context.WithValue(c, inventory.LoadShareFile{}, true)
ctx = context.WithValue(ctx, inventory.LoadShareUser{}, true)
res, err := shareClient.List(ctx, &inventory.ListShareArgs{
PaginationArgs: &inventory.PaginationArgs{
Page: s.Page - 1,
PageSize: s.PageSize,
OrderBy: s.OrderBy,
Order: inventory.OrderDirection(s.OrderDirection),
},
UserID: userID,
FileID: fileID,
ShareIDs: shareIDs,
})
if err != nil {
return nil, serializer.NewError(serializer.CodeDBError, "Failed to list shares", err)
}
siteUrl := dep.SettingProvider().SiteURL(c)
return &ListShareResponse{
Pagination: res.PaginationResults,
Shares: lo.Map(res.Shares, func(share *ent.Share, _ int) GetShareResponse {
var (
uid string
shareLink string
)
if share.Edges.User != nil {
uid = hashid.EncodeUserID(hasher, share.Edges.User.ID)
}
shareLink = routes.MasterShareUrl(siteUrl, hashid.EncodeShareID(hasher, share.ID), share.Password).String()
return GetShareResponse{
Share: share,
UserHashID: uid,
ShareLink: shareLink,
}
}),
}, nil
}
type (
SingleShareService struct {
ShareID int `uri:"id" binding:"required"`
}
SingleShareParamCtx struct{}
)
func (s *SingleShareService) Get(c *gin.Context) (*GetShareResponse, error) {
dep := dependency.FromContext(c)
shareClient := dep.ShareClient()
hasher := dep.HashIDEncoder()
ctx := context.WithValue(c, inventory.LoadShareFile{}, true)
ctx = context.WithValue(ctx, inventory.LoadShareUser{}, true)
share, err := shareClient.GetByID(ctx, s.ShareID)
if err != nil {
return nil, serializer.NewError(serializer.CodeDBError, "Failed to get share", err)
}
var (
uid string
shareLink string
)
if share.Edges.User != nil {
uid = hashid.EncodeUserID(hasher, share.Edges.User.ID)
}
siteUrl := dep.SettingProvider().SiteURL(c)
shareLink = routes.MasterShareUrl(siteUrl, hashid.EncodeShareID(hasher, share.ID), share.Password).String()
return &GetShareResponse{
Share: share,
UserHashID: uid,
ShareLink: shareLink,
}, nil
}
type (
BatchShareService struct {
ShareIDs []int `json:"ids" binding:"required"`
}
BatchShareParamCtx struct{}
)
func (s *BatchShareService) Delete(c *gin.Context) error {
dep := dependency.FromContext(c)
shareClient := dep.ShareClient()
if err := shareClient.DeleteBatch(c, s.ShareIDs); err != nil {
return serializer.NewError(serializer.CodeDBError, "Failed to delete shares", err)
}
return nil
}