Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
hexbee
Cloudreve
提交
0edbbfc9
C
Cloudreve
项目概览
hexbee
/
Cloudreve
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Cloudreve
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0edbbfc9
编写于
1月 30, 2020
作者:
H
HFO4
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Feat: list files for shared folder
上级
a0c320b9
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
115 addition
and
26 deletion
+115
-26
middleware/share.go
middleware/share.go
+24
-12
pkg/filesystem/path.go
pkg/filesystem/path.go
+10
-1
pkg/serializer/setting.go
pkg/serializer/setting.go
+2
-0
pkg/serializer/user.go
pkg/serializer/user.go
+2
-0
routers/controllers/share.go
routers/controllers/share.go
+16
-5
routers/router.go
routers/router.go
+12
-1
service/share/visit.go
service/share/visit.go
+49
-7
未找到文件。
middleware/share.go
浏览文件 @
0edbbfc9
...
@@ -49,6 +49,30 @@ func ShareCanPreview() gin.HandlerFunc {
...
@@ -49,6 +49,30 @@ func ShareCanPreview() gin.HandlerFunc {
}
}
}
}
// CheckShareUnlocked 检查分享是否已解锁
func
CheckShareUnlocked
()
gin
.
HandlerFunc
{
return
func
(
c
*
gin
.
Context
)
{
if
shareCtx
,
ok
:=
c
.
Get
(
"share"
);
ok
{
share
:=
shareCtx
.
(
*
model
.
Share
)
// 分享是否已解锁
if
share
.
Password
!=
""
{
sessionKey
:=
fmt
.
Sprintf
(
"share_unlock_%d"
,
share
.
ID
)
unlocked
:=
util
.
GetSession
(
c
,
sessionKey
)
!=
nil
if
!
unlocked
{
c
.
JSON
(
200
,
serializer
.
Err
(
serializer
.
CodeNoPermissionErr
,
"无权访问此分享"
,
nil
))
c
.
Abort
()
return
}
}
c
.
Next
()
return
}
c
.
Abort
()
}
}
// BeforeShareDownload 分享被下载前的检查
// BeforeShareDownload 分享被下载前的检查
func
BeforeShareDownload
()
gin
.
HandlerFunc
{
func
BeforeShareDownload
()
gin
.
HandlerFunc
{
return
func
(
c
*
gin
.
Context
)
{
return
func
(
c
*
gin
.
Context
)
{
...
@@ -66,18 +90,6 @@ func BeforeShareDownload() gin.HandlerFunc {
...
@@ -66,18 +90,6 @@ func BeforeShareDownload() gin.HandlerFunc {
return
return
}
}
// 分享是否已解锁
if
share
.
Password
!=
""
{
sessionKey
:=
fmt
.
Sprintf
(
"share_unlock_%d"
,
share
.
ID
)
unlocked
:=
util
.
GetSession
(
c
,
sessionKey
)
!=
nil
if
!
unlocked
{
c
.
JSON
(
200
,
serializer
.
Err
(
serializer
.
CodeNoPermissionErr
,
"无权访问此分享"
,
nil
))
c
.
Abort
()
return
}
}
// 对积分、下载次数进行更新
// 对积分、下载次数进行更新
err
=
share
.
DownloadBy
(
user
,
c
)
err
=
share
.
DownloadBy
(
user
,
c
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
pkg/filesystem/path.go
浏览文件 @
0edbbfc9
...
@@ -20,13 +20,22 @@ func (fs *FileSystem) IsPathExist(path string) (bool, *model.Folder) {
...
@@ -20,13 +20,22 @@ func (fs *FileSystem) IsPathExist(path string) (bool, *model.Folder) {
}
}
// 递归步入目录
// 递归步入目录
// TODO:
装入树形缓存
// TODO:
测试新增
var
currentFolder
*
model
.
Folder
var
currentFolder
*
model
.
Folder
// 如果已设定目录对象,则从给定目录向下遍历
if
len
(
fs
.
DirTarget
)
>
0
{
currentFolder
=
&
fs
.
DirTarget
[
0
]
}
for
_
,
folderName
:=
range
pathList
{
for
_
,
folderName
:=
range
pathList
{
var
err
error
var
err
error
// 根目录
// 根目录
if
folderName
==
"/"
{
if
folderName
==
"/"
{
if
currentFolder
!=
nil
{
continue
}
currentFolder
,
err
=
fs
.
User
.
Root
()
currentFolder
,
err
=
fs
.
User
.
Root
()
if
err
!=
nil
{
if
err
!=
nil
{
return
false
,
nil
return
false
,
nil
...
...
pkg/serializer/setting.go
浏览文件 @
0edbbfc9
...
@@ -31,6 +31,8 @@ func BuildSiteConfig(settings map[string]string, user *model.User) Response {
...
@@ -31,6 +31,8 @@ func BuildSiteConfig(settings map[string]string, user *model.User) Response {
var
userRes
User
var
userRes
User
if
user
!=
nil
{
if
user
!=
nil
{
userRes
=
BuildUser
(
*
user
)
userRes
=
BuildUser
(
*
user
)
}
else
{
userRes
=
BuildUser
(
*
model
.
NewAnonymousUser
())
}
}
return
Response
{
return
Response
{
Data
:
SiteConfig
{
Data
:
SiteConfig
{
...
...
pkg/serializer/user.go
浏览文件 @
0edbbfc9
...
@@ -43,6 +43,7 @@ type group struct {
...
@@ -43,6 +43,7 @@ type group struct {
AllowTorrentDownload
bool
`json:"allowTorrentDownload"`
AllowTorrentDownload
bool
`json:"allowTorrentDownload"`
AllowArchiveDownload
bool
`json:"allowArchiveDownload"`
AllowArchiveDownload
bool
`json:"allowArchiveDownload"`
ShareFreeEnabled
bool
`json:"shareFree"`
ShareFreeEnabled
bool
`json:"shareFree"`
ShareDownload
bool
`json:"shareDownload"`
}
}
type
storage
struct
{
type
storage
struct
{
...
@@ -78,6 +79,7 @@ func BuildUser(user model.User) User {
...
@@ -78,6 +79,7 @@ func BuildUser(user model.User) User {
AllowTorrentDownload
:
aria2Option
[
2
],
AllowTorrentDownload
:
aria2Option
[
2
],
AllowArchiveDownload
:
user
.
Group
.
OptionsSerialized
.
ArchiveDownloadEnabled
,
AllowArchiveDownload
:
user
.
Group
.
OptionsSerialized
.
ArchiveDownloadEnabled
,
ShareFreeEnabled
:
user
.
Group
.
OptionsSerialized
.
ShareFreeEnabled
,
ShareFreeEnabled
:
user
.
Group
.
OptionsSerialized
.
ShareFreeEnabled
,
ShareDownload
:
user
.
Group
.
OptionsSerialized
.
ShareDownloadEnabled
,
},
},
}
}
}
}
...
...
routers/controllers/share.go
浏览文件 @
0edbbfc9
...
@@ -30,7 +30,7 @@ func GetShare(c *gin.Context) {
...
@@ -30,7 +30,7 @@ func GetShare(c *gin.Context) {
// GetShareDownload 创建分享下载会话
// GetShareDownload 创建分享下载会话
func
GetShareDownload
(
c
*
gin
.
Context
)
{
func
GetShareDownload
(
c
*
gin
.
Context
)
{
var
service
share
.
S
ingleFil
eService
var
service
share
.
S
har
eService
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
res
:=
service
.
CreateDownloadSession
(
c
)
res
:=
service
.
CreateDownloadSession
(
c
)
c
.
JSON
(
200
,
res
)
c
.
JSON
(
200
,
res
)
...
@@ -45,7 +45,7 @@ func PreviewShare(c *gin.Context) {
...
@@ -45,7 +45,7 @@ func PreviewShare(c *gin.Context) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
defer
cancel
()
var
service
share
.
S
ingleFil
eService
var
service
share
.
S
har
eService
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
res
:=
service
.
PreviewContent
(
ctx
,
c
,
false
)
res
:=
service
.
PreviewContent
(
ctx
,
c
,
false
)
// 是否需要重定向
// 是否需要重定向
...
@@ -68,7 +68,7 @@ func PreviewShareText(c *gin.Context) {
...
@@ -68,7 +68,7 @@ func PreviewShareText(c *gin.Context) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
defer
cancel
()
var
service
share
.
S
ingleFil
eService
var
service
share
.
S
har
eService
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
res
:=
service
.
PreviewContent
(
ctx
,
c
,
true
)
res
:=
service
.
PreviewContent
(
ctx
,
c
,
true
)
// 是否有错误发生
// 是否有错误发生
...
@@ -82,7 +82,7 @@ func PreviewShareText(c *gin.Context) {
...
@@ -82,7 +82,7 @@ func PreviewShareText(c *gin.Context) {
// GetShareDocPreview 创建分享Office文档预览地址
// GetShareDocPreview 创建分享Office文档预览地址
func
GetShareDocPreview
(
c
*
gin
.
Context
)
{
func
GetShareDocPreview
(
c
*
gin
.
Context
)
{
var
service
share
.
S
ingleFil
eService
var
service
share
.
S
har
eService
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
if
err
:=
c
.
ShouldBindQuery
(
&
service
);
err
==
nil
{
res
:=
service
.
CreateDocPreviewSession
(
c
)
res
:=
service
.
CreateDocPreviewSession
(
c
)
c
.
JSON
(
200
,
res
)
c
.
JSON
(
200
,
res
)
...
@@ -93,7 +93,7 @@ func GetShareDocPreview(c *gin.Context) {
...
@@ -93,7 +93,7 @@ func GetShareDocPreview(c *gin.Context) {
// SaveShare 转存他人分享
// SaveShare 转存他人分享
func
SaveShare
(
c
*
gin
.
Context
)
{
func
SaveShare
(
c
*
gin
.
Context
)
{
var
service
share
.
S
ingleFil
eService
var
service
share
.
S
har
eService
if
err
:=
c
.
ShouldBindJSON
(
&
service
);
err
==
nil
{
if
err
:=
c
.
ShouldBindJSON
(
&
service
);
err
==
nil
{
res
:=
service
.
SaveToMyFile
(
c
)
res
:=
service
.
SaveToMyFile
(
c
)
c
.
JSON
(
200
,
res
)
c
.
JSON
(
200
,
res
)
...
@@ -101,3 +101,14 @@ func SaveShare(c *gin.Context) {
...
@@ -101,3 +101,14 @@ func SaveShare(c *gin.Context) {
c
.
JSON
(
200
,
ErrorResponse
(
err
))
c
.
JSON
(
200
,
ErrorResponse
(
err
))
}
}
}
}
// ListSharedFolder 列出分享的目录下的对象
func
ListSharedFolder
(
c
*
gin
.
Context
)
{
var
service
share
.
ShareService
if
err
:=
c
.
ShouldBindUri
(
&
service
);
err
==
nil
{
res
:=
service
.
List
(
c
)
c
.
JSON
(
200
,
res
)
}
else
{
c
.
JSON
(
200
,
ErrorResponse
(
err
))
}
}
routers/router.go
浏览文件 @
0edbbfc9
...
@@ -174,25 +174,35 @@ func InitMasterRouter() *gin.Engine {
...
@@ -174,25 +174,35 @@ func InitMasterRouter() *gin.Engine {
share
.
GET
(
"info/:id"
,
controllers
.
GetShare
)
share
.
GET
(
"info/:id"
,
controllers
.
GetShare
)
// 创建文件下载会话
// 创建文件下载会话
share
.
POST
(
"download/:id"
,
share
.
POST
(
"download/:id"
,
middleware
.
CheckShareUnlocked
(),
middleware
.
BeforeShareDownload
(),
middleware
.
BeforeShareDownload
(),
controllers
.
GetShareDownload
,
controllers
.
GetShareDownload
,
)
)
// 预览分享文件
// 预览分享文件
share
.
GET
(
"preview/:id"
,
share
.
GET
(
"preview/:id"
,
middleware
.
CheckShareUnlocked
(),
middleware
.
ShareCanPreview
(),
middleware
.
ShareCanPreview
(),
middleware
.
BeforeShareDownload
(),
middleware
.
BeforeShareDownload
(),
controllers
.
PreviewShare
,
controllers
.
PreviewShare
,
)
)
// 取得Office文档预览地址
// 取得Office文档预览地址
share
.
GET
(
"doc/:id"
,
middleware
.
ShareCanPreview
(),
share
.
GET
(
"doc/:id"
,
middleware
.
CheckShareUnlocked
(),
middleware
.
ShareCanPreview
(),
middleware
.
BeforeShareDownload
(),
middleware
.
BeforeShareDownload
(),
controllers
.
GetShareDocPreview
,
controllers
.
GetShareDocPreview
,
)
)
// 获取文本文件内容
// 获取文本文件内容
share
.
GET
(
"content/:id"
,
share
.
GET
(
"content/:id"
,
middleware
.
CheckShareUnlocked
(),
middleware
.
BeforeShareDownload
(),
middleware
.
BeforeShareDownload
(),
controllers
.
PreviewShareText
,
controllers
.
PreviewShareText
,
)
)
// 分享目录列文件
share
.
GET
(
"list/:id/*path"
,
middleware
.
CheckShareUnlocked
(),
controllers
.
ListSharedFolder
,
)
}
}
// 需要登录保护的
// 需要登录保护的
...
@@ -272,6 +282,7 @@ func InitMasterRouter() *gin.Engine {
...
@@ -272,6 +282,7 @@ func InitMasterRouter() *gin.Engine {
// 转存他人分享
// 转存他人分享
share
.
POST
(
"save/:id"
,
share
.
POST
(
"save/:id"
,
middleware
.
ShareAvailable
(),
middleware
.
ShareAvailable
(),
middleware
.
CheckShareUnlocked
(),
middleware
.
BeforeShareDownload
(),
middleware
.
BeforeShareDownload
(),
controllers
.
SaveShare
,
controllers
.
SaveShare
,
)
)
...
...
service/share/visit.go
浏览文件 @
0edbbfc9
...
@@ -10,6 +10,7 @@ import (
...
@@ -10,6 +10,7 @@ import (
"github.com/HFO4/cloudreve/pkg/util"
"github.com/HFO4/cloudreve/pkg/util"
"github.com/HFO4/cloudreve/service/explorer"
"github.com/HFO4/cloudreve/service/explorer"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
"path"
)
)
// ShareGetService 获取分享服务
// ShareGetService 获取分享服务
...
@@ -17,9 +18,10 @@ type ShareGetService struct {
...
@@ -17,9 +18,10 @@ type ShareGetService struct {
Password
string
`form:"password" binding:"max=255"`
Password
string
`form:"password" binding:"max=255"`
}
}
// SingleFileService 对单文件进行操作的服务,path为可选文件完整路径
// ShareService 对分享进行操作的服务,
type
SingleFileService
struct
{
// path 为可选文件完整路径,在目录分享下有效
Path
string
`form:"path" binding:"max=65535"`
type
ShareService
struct
{
Path
string
`form:"path" uri:"path" binding:"max=65535"`
}
}
// Get 获取分享内容
// Get 获取分享内容
...
@@ -59,7 +61,7 @@ func (service *ShareGetService) Get(c *gin.Context) serializer.Response {
...
@@ -59,7 +61,7 @@ func (service *ShareGetService) Get(c *gin.Context) serializer.Response {
}
}
// CreateDownloadSession 创建下载会话
// CreateDownloadSession 创建下载会话
func
(
service
*
S
ingleFil
eService
)
CreateDownloadSession
(
c
*
gin
.
Context
)
serializer
.
Response
{
func
(
service
*
S
har
eService
)
CreateDownloadSession
(
c
*
gin
.
Context
)
serializer
.
Response
{
shareCtx
,
_
:=
c
.
Get
(
"share"
)
shareCtx
,
_
:=
c
.
Get
(
"share"
)
share
:=
shareCtx
.
(
*
model
.
Share
)
share
:=
shareCtx
.
(
*
model
.
Share
)
userCtx
,
_
:=
c
.
Get
(
"user"
)
userCtx
,
_
:=
c
.
Get
(
"user"
)
...
@@ -92,7 +94,7 @@ func (service *SingleFileService) CreateDownloadSession(c *gin.Context) serializ
...
@@ -92,7 +94,7 @@ func (service *SingleFileService) CreateDownloadSession(c *gin.Context) serializ
// PreviewContent 预览文件,需要登录会话, isText - 是否为文本文件,文本文件会
// PreviewContent 预览文件,需要登录会话, isText - 是否为文本文件,文本文件会
// 强制经由服务端中转
// 强制经由服务端中转
func
(
service
*
S
ingleFil
eService
)
PreviewContent
(
ctx
context
.
Context
,
c
*
gin
.
Context
,
isText
bool
)
serializer
.
Response
{
func
(
service
*
S
har
eService
)
PreviewContent
(
ctx
context
.
Context
,
c
*
gin
.
Context
,
isText
bool
)
serializer
.
Response
{
shareCtx
,
_
:=
c
.
Get
(
"share"
)
shareCtx
,
_
:=
c
.
Get
(
"share"
)
share
:=
shareCtx
.
(
*
model
.
Share
)
share
:=
shareCtx
.
(
*
model
.
Share
)
...
@@ -106,7 +108,7 @@ func (service *SingleFileService) PreviewContent(ctx context.Context, c *gin.Con
...
@@ -106,7 +108,7 @@ func (service *SingleFileService) PreviewContent(ctx context.Context, c *gin.Con
}
}
// CreateDocPreviewSession 创建Office预览会话,返回预览地址
// CreateDocPreviewSession 创建Office预览会话,返回预览地址
func
(
service
*
S
ingleFil
eService
)
CreateDocPreviewSession
(
c
*
gin
.
Context
)
serializer
.
Response
{
func
(
service
*
S
har
eService
)
CreateDocPreviewSession
(
c
*
gin
.
Context
)
serializer
.
Response
{
shareCtx
,
_
:=
c
.
Get
(
"share"
)
shareCtx
,
_
:=
c
.
Get
(
"share"
)
share
:=
shareCtx
.
(
*
model
.
Share
)
share
:=
shareCtx
.
(
*
model
.
Share
)
...
@@ -120,7 +122,7 @@ func (service *SingleFileService) CreateDocPreviewSession(c *gin.Context) serial
...
@@ -120,7 +122,7 @@ func (service *SingleFileService) CreateDocPreviewSession(c *gin.Context) serial
}
}
// SaveToMyFile 将此分享转存到自己的网盘
// SaveToMyFile 将此分享转存到自己的网盘
func
(
service
*
S
ingleFil
eService
)
SaveToMyFile
(
c
*
gin
.
Context
)
serializer
.
Response
{
func
(
service
*
S
har
eService
)
SaveToMyFile
(
c
*
gin
.
Context
)
serializer
.
Response
{
shareCtx
,
_
:=
c
.
Get
(
"share"
)
shareCtx
,
_
:=
c
.
Get
(
"share"
)
share
:=
shareCtx
.
(
*
model
.
Share
)
share
:=
shareCtx
.
(
*
model
.
Share
)
userCtx
,
_
:=
c
.
Get
(
"user"
)
userCtx
,
_
:=
c
.
Get
(
"user"
)
...
@@ -151,3 +153,43 @@ func (service *SingleFileService) SaveToMyFile(c *gin.Context) serializer.Respon
...
@@ -151,3 +153,43 @@ func (service *SingleFileService) SaveToMyFile(c *gin.Context) serializer.Respon
return
serializer
.
Response
{}
return
serializer
.
Response
{}
}
}
// List 列出分享的目录下的对象
func
(
service
*
ShareService
)
List
(
c
*
gin
.
Context
)
serializer
.
Response
{
shareCtx
,
_
:=
c
.
Get
(
"share"
)
share
:=
shareCtx
.
(
*
model
.
Share
)
if
!
share
.
IsDir
{
return
serializer
.
ParamErr
(
"此分享无法列目录"
,
nil
)
}
if
!
path
.
IsAbs
(
service
.
Path
)
{
return
serializer
.
ParamErr
(
"路径无效"
,
nil
)
}
// 创建文件系统
fs
,
err
:=
filesystem
.
NewFileSystem
(
share
.
GetCreator
())
if
err
!=
nil
{
return
serializer
.
Err
(
serializer
.
CodePolicyNotAllowed
,
err
.
Error
(),
err
)
}
defer
fs
.
Recycle
()
// 上下文
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
// 重设根目录
fs
.
SetTargetDir
(
&
[]
model
.
Folder
{
*
share
.
GetSource
()
.
(
*
model
.
Folder
)})
fs
.
DirTarget
[
0
]
.
Name
=
"/"
// 获取子项目
objects
,
err
:=
fs
.
List
(
ctx
,
service
.
Path
,
nil
)
if
err
!=
nil
{
return
serializer
.
Err
(
serializer
.
CodeCreateFolderFailed
,
err
.
Error
(),
err
)
}
return
serializer
.
Response
{
Code
:
0
,
Data
:
objects
,
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录