Add: GetIntSetting helper
This commit is contained in:
parent
fffcf1aa1b
commit
a75be3a927
11 changed files with 59 additions and 110 deletions
|
@ -106,6 +106,7 @@ solid #e9e9e9;"bgcolor="#fff"><tbody><tr style="font-family: 'Helvetica Neue',He
|
|||
{Name: "doc_preview_timeout", Value: `60`, Type: "timeout"},
|
||||
{Name: "upload_credential_timeout", Value: `1800`, Type: "timeout"},
|
||||
{Name: "upload_session_timeout", Value: `86400`, Type: "timeout"},
|
||||
{Name: "slave_api_timeout", Value: `60`, Type: "timeout"},
|
||||
{Name: "allowdVisitorDownload", Value: `false`, Type: "share"},
|
||||
{Name: "login_captcha", Value: `0`, Type: "login"},
|
||||
{Name: "qq_login", Value: `0`, Type: "login"},
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"github.com/HFO4/cloudreve/pkg/cache"
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Setting 系统设置模型
|
||||
|
@ -72,3 +73,13 @@ func GetSiteURL() *url.URL {
|
|||
}
|
||||
return base
|
||||
}
|
||||
|
||||
// GetIntSetting 获取整形设置值,如果转换失败则返回默认值defaultVal
|
||||
// TODO 测试
|
||||
func GetIntSetting(key string, defaultVal int) int {
|
||||
res, err := strconv.Atoi(GetSettingByName(key))
|
||||
if err != nil {
|
||||
return defaultVal
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/HFO4/cloudreve/pkg/util"
|
||||
"github.com/juju/ratelimit"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/* ============
|
||||
|
@ -107,16 +106,8 @@ func (fs *FileSystem) Preview(ctx context.Context, path string) (*response.Conte
|
|||
}
|
||||
|
||||
// 否则重定向到签名的预览URL
|
||||
ttl, err := strconv.ParseInt(model.GetSettingByName("preview_timeout"), 10, 64)
|
||||
if err != nil {
|
||||
return nil,
|
||||
serializer.NewError(
|
||||
serializer.CodeInternalSetting,
|
||||
"无法获取预览地址有效期设定",
|
||||
err,
|
||||
)
|
||||
}
|
||||
previewURL, err := fs.signURL(ctx, &fs.FileTarget[0], ttl, false)
|
||||
ttl := model.GetIntSetting("preview_timeout", 60)
|
||||
previewURL, err := fs.signURL(ctx, &fs.FileTarget[0], int64(ttl), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -222,20 +213,11 @@ func (fs *FileSystem) GetDownloadURL(ctx context.Context, path string, timeout s
|
|||
fileTarget := &fs.FileTarget[0]
|
||||
|
||||
// 生成下載地址
|
||||
ttl, err := strconv.ParseInt(model.GetSettingByName(timeout), 10, 64)
|
||||
if err != nil {
|
||||
return "",
|
||||
serializer.NewError(
|
||||
serializer.CodeInternalSetting,
|
||||
"无法获取下载地址有效期",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
ttl := model.GetIntSetting(timeout, 60)
|
||||
source, err := fs.signURL(
|
||||
ctx,
|
||||
fileTarget,
|
||||
ttl,
|
||||
int64(ttl),
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
@ -548,28 +548,6 @@ func TestFileSystem_Preview(t *testing.T) {
|
|||
asserts.NoError(resp.Content.Close())
|
||||
}
|
||||
|
||||
// 需要重定向,无法解析有效期设置
|
||||
{
|
||||
fs := FileSystem{
|
||||
User: &model.User{},
|
||||
}
|
||||
fs.FileTarget = []model.File{
|
||||
{
|
||||
SourceName: "tests/file1.txt",
|
||||
PolicyID: 1,
|
||||
Policy: model.Policy{
|
||||
Model: gorm.Model{ID: 1},
|
||||
Type: "remote",
|
||||
},
|
||||
},
|
||||
}
|
||||
asserts.NoError(cache.Set("setting_preview_timeout", "test", 0))
|
||||
resp, err := fs.Preview(ctx, "/1.txt")
|
||||
asserts.Error(err)
|
||||
asserts.Nil(resp)
|
||||
asserts.Equal(serializer.CodeInternalSetting, err.(serializer.AppError).Code)
|
||||
}
|
||||
|
||||
// 需要重定向,成功
|
||||
{
|
||||
fs := FileSystem{
|
||||
|
|
|
@ -3,6 +3,7 @@ package filesystem
|
|||
import (
|
||||
"context"
|
||||
"github.com/HFO4/cloudreve/models"
|
||||
"github.com/HFO4/cloudreve/pkg/auth"
|
||||
"github.com/HFO4/cloudreve/pkg/conf"
|
||||
"github.com/HFO4/cloudreve/pkg/filesystem/local"
|
||||
"github.com/HFO4/cloudreve/pkg/filesystem/remote"
|
||||
|
@ -152,8 +153,9 @@ func (fs *FileSystem) dispatchHandler() error {
|
|||
return nil
|
||||
case "remote":
|
||||
fs.Handler = remote.Handler{
|
||||
Policy: currentPolicy,
|
||||
Client: request.HTTPClient{},
|
||||
Policy: currentPolicy,
|
||||
Client: request.HTTPClient{},
|
||||
AuthInstance: auth.HMACAuth{[]byte(currentPolicy.SecretKey)},
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
|
|
|
@ -22,8 +22,9 @@ import (
|
|||
|
||||
// Handler 远程存储策略适配器
|
||||
type Handler struct {
|
||||
Client request.Client
|
||||
Policy *model.Policy
|
||||
Client request.Client
|
||||
Policy *model.Policy
|
||||
AuthInstance auth.Auth
|
||||
}
|
||||
|
||||
// getAPI 获取接口请求地址
|
||||
|
@ -55,7 +56,6 @@ func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string,
|
|||
|
||||
// Delete 删除一个或多个文件,
|
||||
// 返回未删除的文件,及遇到的最后一个错误
|
||||
// TODO 测试
|
||||
func (handler Handler) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
// 封装接口请求正文
|
||||
reqBody := serializer.RemoteDeleteRequest{
|
||||
|
@ -68,12 +68,12 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er
|
|||
|
||||
// 发送删除请求
|
||||
bodyReader := strings.NewReader(string(reqBodyEncoded))
|
||||
authInstance := auth.HMACAuth{SecretKey: []byte(handler.Policy.SecretKey)}
|
||||
signTTL := model.GetIntSetting("slave_api_timeout", 60)
|
||||
resp, err := handler.Client.Request(
|
||||
"POST",
|
||||
handler.getAPI("delete"),
|
||||
bodyReader,
|
||||
request.WithCredential(authInstance, 60),
|
||||
request.WithCredential(handler.AuthInstance, int64(signTTL)),
|
||||
).GetResponse(200)
|
||||
if err != nil {
|
||||
return files, err
|
||||
|
@ -105,7 +105,6 @@ func (handler Handler) Thumb(ctx context.Context, path string) (*response.Conten
|
|||
}
|
||||
|
||||
// Source 获取外链URL
|
||||
// TODO 测试
|
||||
func (handler Handler) Source(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
|
@ -138,9 +137,8 @@ func (handler Handler) Source(
|
|||
|
||||
// 签名下载地址
|
||||
sourcePath := base64.RawURLEncoding.EncodeToString([]byte(file.SourceName))
|
||||
authInstance := auth.HMACAuth{SecretKey: []byte(handler.Policy.SecretKey)}
|
||||
signedURI, err = auth.SignURI(
|
||||
authInstance,
|
||||
handler.AuthInstance,
|
||||
fmt.Sprintf("%s/%d/%s/%s", controller, speed, sourcePath, file.Name),
|
||||
expires,
|
||||
)
|
||||
|
@ -180,8 +178,7 @@ func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serial
|
|||
uploadRequest.Header = map[string][]string{
|
||||
"X-Policy": {policyEncoded},
|
||||
}
|
||||
remoteAuth := auth.HMACAuth{SecretKey: []byte(handler.Policy.SecretKey)}
|
||||
auth.SignRequest(remoteAuth, uploadRequest, time.Now().Unix()+TTL)
|
||||
auth.SignRequest(handler.AuthInstance, uploadRequest, time.Now().Unix()+TTL)
|
||||
|
||||
if credential, ok := uploadRequest.Header["Authorization"]; ok && len(credential) == 1 {
|
||||
return serializer.UploadCredential{
|
||||
|
|
|
@ -30,6 +30,7 @@ func TestHandler_Token(t *testing.T) {
|
|||
FileType: []string{"txt"},
|
||||
},
|
||||
},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
ctx := context.Background()
|
||||
auth.General = auth.HMACAuth{SecretKey: []byte("test")}
|
||||
|
@ -56,7 +57,9 @@ func TestHandler_Source(t *testing.T) {
|
|||
|
||||
// 无法获取上下文
|
||||
{
|
||||
handler := Handler{}
|
||||
handler := Handler{
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
ctx := context.Background()
|
||||
res, err := handler.Source(ctx, "", url.URL{}, 0, true, 0)
|
||||
asserts.Error(err)
|
||||
|
@ -66,7 +69,8 @@ func TestHandler_Source(t *testing.T) {
|
|||
// 成功
|
||||
{
|
||||
handler := Handler{
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
file := model.File{
|
||||
SourceName: "1.txt",
|
||||
|
@ -80,7 +84,8 @@ func TestHandler_Source(t *testing.T) {
|
|||
// 成功 预览
|
||||
{
|
||||
handler := Handler{
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
file := model.File{
|
||||
SourceName: "1.txt",
|
||||
|
@ -108,8 +113,10 @@ func TestHandler_Delete(t *testing.T) {
|
|||
SecretKey: "test",
|
||||
Server: "http://test.com",
|
||||
},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
ctx := context.Background()
|
||||
cache.Set("setting_slave_api_timeout", "60", 0)
|
||||
|
||||
// 成功
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/HFO4/cloudreve/pkg/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/* ================
|
||||
|
@ -142,32 +141,14 @@ func (fs *FileSystem) CancelUpload(ctx context.Context, path string, file FileHe
|
|||
// GetUploadToken 生成新的上传凭证
|
||||
func (fs *FileSystem) GetUploadToken(ctx context.Context, path string, size uint64) (*serializer.UploadCredential, error) {
|
||||
// 获取相关有效期设置
|
||||
ttls := model.GetSettingByNames([]string{"upload_credential_timeout", "upload_session_timeout"})
|
||||
credentialTTL := model.GetIntSetting("upload_credential_timeout", 3600)
|
||||
callBackSessionTTL := model.GetIntSetting("upload_session_timeout", 86400)
|
||||
|
||||
var (
|
||||
err error
|
||||
credentialTTL int64 = 3600
|
||||
callBackSessionTTL int64 = 86400
|
||||
)
|
||||
// 获取上传凭证的有效期
|
||||
if ttlStr, ok := ttls["upload_credential_timeout"]; ok {
|
||||
credentialTTL, err = strconv.ParseInt(ttlStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, serializer.NewError(serializer.CodeInternalSetting, "上传凭证有效期设置无效", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取回调会话的有效期
|
||||
if ttlStr, ok := ttls["upload_session_timeout"]; ok {
|
||||
callBackSessionTTL, err = strconv.ParseInt(ttlStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, serializer.NewError(serializer.CodeInternalSetting, "上传会话有效期设置无效", err)
|
||||
}
|
||||
}
|
||||
var err error
|
||||
|
||||
// 获取上传凭证
|
||||
callbackKey := util.RandStringRunes(32)
|
||||
credential, err := fs.Handler.Token(ctx, credentialTTL, callbackKey)
|
||||
credential, err := fs.Handler.Token(ctx, int64(credentialTTL), callbackKey)
|
||||
if err != nil {
|
||||
return nil, serializer.NewError(serializer.CodeEncryptError, "无法获取上传凭证", err)
|
||||
}
|
||||
|
@ -180,7 +161,7 @@ func (fs *FileSystem) GetUploadToken(ctx context.Context, path string, size uint
|
|||
PolicyID: fs.User.GetPolicyID(),
|
||||
VirtualPath: path,
|
||||
},
|
||||
int(callBackSessionTTL),
|
||||
callBackSessionTTL,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -199,26 +199,4 @@ func TestFileSystem_GetUploadToken(t *testing.T) {
|
|||
testHandller.AssertExpectations(t)
|
||||
asserts.Error(err)
|
||||
}
|
||||
|
||||
// 上传有效期错误
|
||||
{
|
||||
cache.SetSettings(map[string]string{
|
||||
"upload_credential_timeout": "?10",
|
||||
"upload_session_timeout": "10",
|
||||
}, "setting_")
|
||||
|
||||
_, err := fs.GetUploadToken(ctx, "/", 10)
|
||||
asserts.Error(err)
|
||||
}
|
||||
|
||||
// 上传会话有效期错误
|
||||
{
|
||||
cache.SetSettings(map[string]string{
|
||||
"upload_credential_timeout": "10",
|
||||
"upload_session_timeout": "?10",
|
||||
}, "setting_")
|
||||
|
||||
_, err := fs.GetUploadToken(ctx, "/", 10)
|
||||
asserts.Error(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,6 +221,8 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request, fs *file
|
|||
|
||||
// OK
|
||||
func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
reqPath, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
|
||||
if err != nil {
|
||||
return status, err
|
||||
|
@ -249,6 +251,8 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request, fs *
|
|||
|
||||
// OK
|
||||
func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
reqPath, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
|
||||
if err != nil {
|
||||
return status, err
|
||||
|
@ -353,6 +357,8 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request, fs *filesyst
|
|||
|
||||
// OK
|
||||
func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
reqPath, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
|
||||
if err != nil {
|
||||
return status, err
|
||||
|
@ -376,6 +382,8 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request, fs *filesy
|
|||
|
||||
// OK
|
||||
func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
hdr := r.Header.Get("Destination")
|
||||
if hdr == "" {
|
||||
return http.StatusBadRequest, errInvalidDestination
|
||||
|
@ -460,6 +468,8 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request, fs *fil
|
|||
|
||||
// OK
|
||||
func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (retStatus int, retErr error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
duration, err := parseTimeout(r.Header.Get("Timeout"))
|
||||
if err != nil {
|
||||
return http.StatusBadRequest, err
|
||||
|
@ -555,6 +565,8 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request, fs *filesys
|
|||
|
||||
// OK
|
||||
func (h *Handler) handleUnlock(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#HEADER_Lock-Token says that the
|
||||
// Lock-Token value is a Coded-URL. We strip its angle brackets.
|
||||
t := r.Header.Get("Lock-Token")
|
||||
|
@ -579,6 +591,8 @@ func (h *Handler) handleUnlock(w http.ResponseWriter, r *http.Request, fs *files
|
|||
|
||||
// OK
|
||||
func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
reqPath, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
|
||||
if err != nil {
|
||||
return status, err
|
||||
|
@ -646,6 +660,8 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request, fs *fil
|
|||
}
|
||||
|
||||
func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
|
||||
defer fs.Recycle()
|
||||
|
||||
reqPath, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
|
||||
if err != nil {
|
||||
return status, err
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/HFO4/cloudreve/pkg/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -62,10 +61,7 @@ func (service *ItemService) Archive(ctx context.Context, c *gin.Context) seriali
|
|||
return serializer.Err(serializer.CodeNotSet, "无法解析站点URL", err)
|
||||
}
|
||||
zipID := util.RandStringRunes(16)
|
||||
ttl, err := strconv.Atoi(model.GetSettingByName("archive_timeout"))
|
||||
if err != nil {
|
||||
ttl = 30
|
||||
}
|
||||
ttl := model.GetIntSetting("archive_timeout", 30)
|
||||
signedURI, err := auth.SignURI(
|
||||
auth.General,
|
||||
fmt.Sprintf("/api/v3/file/archive/%s/archive.zip", zipID),
|
||||
|
|
Loading…
Add table
Reference in a new issue