Skip to content

Commit

Permalink
docs: update the README.md
Browse files Browse the repository at this point in the history
fix:don't allow move the folder into itself #4 (saltbo#26)

* fix:don't allow move the folder into itself #4

* fix: action building failed

* refactor: splitting logic as FileMove and FolderMove

Co-authored-by: lu.longshan <luls0728@zsmarter.com>

chore: update the front code to resolve #4

fix: resolve the issue #5

feat: support s3 and storage saltbo#10

chore: update the front code to resolve saltbo#11

feat: support search to resolve the issue saltbo#13

chore: update the assets to fix create folder

test: add some ut for the disk
  • Loading branch information
saltbo authored and XiangYu0777 committed Sep 15, 2020
1 parent 2898dac commit b804fd6
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 47 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ jobs:
- name: Run Unit tests.
run: make test
- name: Upload Coverage report to CodeCov
uses: codecov/codecov-action@v1.0.0
uses: codecov/codecov-action@v1
with:
token: ${{secrets.CODECOV_TOKEN}}
# token: ${{secrets.CODECOV_TOKEN}}
file: .coverprofile
build:
name: Build
Expand Down
13 changes: 11 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
FROM moreu:latest
FROM debian:10

RUN echo \
deb http://mirrors.aliyun.com/debian buster main \
deb http://mirrors.aliyun.com/debian buster-updates main \
deb http://mirrors.aliyun.com/debian-security buster/updates main \
> /etc/apt/sources.list

RUN apt-get update \
&& apt-get install -y ca-certificates telnet procps curl

ENV APP_HOME /zpan
WORKDIR $APP_HOME

RUN curl -sSf https://dl.saltbo.cn/install.sh | sh -s zpan

CMD ["zpan", "server"]
CMD ["zpan", "server"]
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@ English | [🇨🇳中文](https://saltbo.cn/zpan)
## QuickStart
### Linux
```bash
# 安装服务
# Install
curl -sSf https://dl.saltbo.cn/install.sh | sudo sh -s zpan

# 启动服务
# Start
systemctl start zpan

# 设置开机启动
# Status
systemctl status zpan

# Enable boot up
systemctl enable zpan
```

### Docker
```bash
docker run -p 80:8081 -v /opt/dockerv/zpan:/zpan -it saltbo/zpan:latest
docker run -p 80:8222 -v /opt/dockerv/zpan:/zpan -it saltbo/zpan:latest
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion assets/statik.go

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion disk/aws-s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ func (p *AwsS3) SignedPutURL(key, filetype string, public bool) (string, http.He
ContentType: aws.String(filetype),
}
req, _ := p.client.PutObjectRequest(input)
return req.PresignRequest(time.Minute * 5)
us, headers, err := req.PresignRequest(time.Minute * 5)
return us, headerRebuild(headers), err
}

func (p *AwsS3) SignedGetURL(key, filename string) (string, error) {
Expand Down Expand Up @@ -106,3 +107,13 @@ func (p *AwsS3) ObjectsDelete(objectKeys []string) error {
_, err := p.client.DeleteObjects(input)
return err
}

func headerRebuild(h http.Header) http.Header {
nh := make(http.Header)
for k, vs := range h {
for _, v := range vs {
nh.Add(k, v)
}
}
return nh
}
17 changes: 13 additions & 4 deletions disk/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ type Config struct {
type ProviderConstructor func(provider Config) (Provider, error)

var supportDrivers = map[string]string{
"cos": "cos.(.*).myqcloud.com",
"oss": `oss.(.*).aliyuncs.com`,
"kodo": "s3-(.*).qiniucs.com",
"s3": "s3.(.*).amazonaws.com",
"cos": "cos.(.*).myqcloud.com",
"oss": `oss.(.*).aliyuncs.com`,
"kodo": "s3-(.*).qiniucs.com",
"storage": "storage.googleapis.com",
}

func New(conf Config) (Provider, error) {
Expand All @@ -45,5 +47,12 @@ func New(conf Config) (Provider, error) {
return nil, err
}

return newAwsS3(conf, exp.FindString(conf.Endpoint))
var region string
if conf.Name == "storage" {
region = "auto"
} else if items := exp.FindStringSubmatch(conf.Endpoint); len(items) > 1 {
region = items[1]
}

return newAwsS3(conf, region)
}
94 changes: 94 additions & 0 deletions disk/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package disk

import (
"fmt"
"net/url"
"strings"
"testing"

"github.com/aws/aws-sdk-go/service/s3"
"github.com/stretchr/testify/assert"
)

// default config
var dc = Config{
Name: "s3",
Bucket: "test-bucket",
Endpoint: "s3.ap-northeast-1.amazonaws.com",
AccessKey: "test-ak",
AccessSecret: "test-sk",
}

var key = "1001/test.txt"

func checkSignedURLStr(t *testing.T, us, customHost string) *url.URL {
host := fmt.Sprintf("%s.%s", dc.Bucket, dc.Endpoint)
if customHost != "" {
host = strings.TrimPrefix(customHost, "http://")
}
u, err := url.Parse(us)
assert.NoError(t, err)
assert.Equal(t, "/"+key, u.Path)
assert.Equal(t, host, u.Host)
assert.Contains(t, u.RawQuery, dc.AccessKey)
assert.NotContains(t, u.RawQuery, dc.AccessSecret)
return u
}

func testSignedGetUrl(t *testing.T, conf Config) {
disk, err := New(conf)
assert.NoError(t, err)

us, headers, err := disk.SignedPutURL(key, "text/plain", false)
assert.NoError(t, err)
checkSignedURLStr(t, us, conf.CustomHost)

assert.Equal(t, s3.ObjectCannedACLAuthenticatedRead, headers.Get("x-amz-acl"))
assert.Equal(t, "text/plain", headers.Get("content-type"))
}

func TestSignedPutURL(t *testing.T) {
testSignedGetUrl(t, dc)
}

func TestSignedPutURLWithCustomHost(t *testing.T) {
conf := dc
conf.CustomHost = "http://dl.zpan.com"
testSignedGetUrl(t, conf)
}

func TestSignedGetURL(t *testing.T) {
disk, err := New(dc)
assert.NoError(t, err)

filename := "test2.txt"
us, err := disk.SignedGetURL(key, filename)
assert.NoError(t, err)
u := checkSignedURLStr(t, us, "")
assert.Equal(t, u.Query().Get("response-content-disposition"), fmt.Sprintf(`attachment;filename="%s"`, urlEncode(filename)))
}

func TestPublicURL(t *testing.T) {
disk, err := New(dc)
assert.NoError(t, err)

us := disk.PublicURL(key)
u, err := url.Parse(us)
assert.NoError(t, err)
assert.Equal(t, "/"+key, u.Path)
assert.Equal(t, fmt.Sprintf("%s.%s", dc.Bucket, dc.Endpoint), u.Host)
}

func TestNotSupportedProvider(t *testing.T) {
conf := dc
conf.Name = "test-provider"
_, err := New(conf)
assert.Error(t, err)
}

func TestNew4Storage(t *testing.T) {
conf := dc
conf.Name = "storage"
_, err := New(conf)
assert.NoError(t, err)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ require (
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.7.1
github.com/storyicon/grbac v0.0.0-20200224041032-a0461737df7e
github.com/stretchr/testify v1.6.1
)
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
Expand Down Expand Up @@ -231,6 +232,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
Expand Down Expand Up @@ -295,6 +297,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
Expand Down
30 changes: 15 additions & 15 deletions model/matter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ const (
)

type Matter struct {
Id int64 `json:"id"`
Uid int64 `json:"uid" gorm:"not null"`
Alias string `json:"alias" gorm:"not null"`
Name string `json:"name" gorm:"not null"`
Type string `json:"type" gorm:"not null"`
Size int64 `json:"size" gorm:"not null"`
DirType int8 `json:"dirtype" gorm:"column:dirtype;not null"`
Parent string `json:"parent" gorm:"not null"`
Object string `json:"object" gorm:"not null"`
ACL string `json:"acl" gorm:"not null"`
URL string `json:"url" gorm:"-"`
Uploaded time.Time `json:"uploaded" gorm:"not null"`
Created time.Time `json:"created" gorm:"column:created_at;not null"`
Updated time.Time `json:"updated" gorm:"column:updated_at;not null"`
Deleted *time.Time `json:"-" gorm:"column:deleted_at"`
Id int64 `json:"id"`
Uid int64 `json:"uid" gorm:"not null"`
Alias string `json:"alias" gorm:"not null"`
Name string `json:"name" gorm:"not null"`
Type string `json:"type" gorm:"not null"`
Size int64 `json:"size" gorm:"not null"`
DirType int8 `json:"dirtype" gorm:"column:dirtype;not null"`
Parent string `json:"parent" gorm:"not null"`
Object string `json:"object" gorm:"not null"`
ACL string `json:"acl" gorm:"not null"`
URL string `json:"url" gorm:"-"`
CreatedAt time.Time `json:"created" gorm:"not null"`
UpdatedAt time.Time `json:"updated" gorm:"not null"`
UploadedAt *time.Time `json:"uploaded"`
DeletedAt *time.Time `json:"-"`
}

func NewMatter(uid int64, name string) *Matter {
Expand Down
3 changes: 1 addition & 2 deletions rest/bind/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ type QueryFiles struct {
QueryPage
Dir string `form:"dir"`
Type string `form:"type"`
Search bool `form:"search"`
Keyword string `form:"keyword"`
Keyword string `form:"kw"`
}

type BodyFile struct {
Expand Down
3 changes: 0 additions & 3 deletions rest/bind/folder.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package bind

import (
"time"

"github.com/saltbo/zpan/model"
)

Expand All @@ -20,6 +18,5 @@ func (p *BodyFolder) ToMatter(uid int64) *model.Matter {
m := model.NewMatter(uid, p.Name)
m.Parent = p.Dir
m.DirType = model.DirTypeUser
m.Uploaded = time.Now()
return m
}
31 changes: 21 additions & 10 deletions rest/file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rest

import (
"errors"
"fmt"
"log"
"path/filepath"
Expand Down Expand Up @@ -52,10 +53,12 @@ func (rs *FileResource) findAll(c *gin.Context) {
}

sm := service.NewMatter(userIdGet(c))
if !p.Search {
sm.SetDir(p.Dir)
} else if p.Type != "" {
if p.Type != "" {
sm.SetType(p.Type)
} else if p.Keyword != "" {
sm.SetKeyword(p.Keyword)
} else {
sm.SetDir(p.Dir)
}
list, total, err := sm.Find(p.Offset, p.Limit)
if err != nil {
Expand Down Expand Up @@ -97,10 +100,6 @@ func (rs *FileResource) create(c *gin.Context) {
p.Name = name + suffix + ext
}

//publicRead := false
//if p.Dir == ".pics/" {
// publicRead = true
//}
matter := p.ToMatter(user.Id)
link, headers, err := rs.provider.SignedPutURL(matter.Object, p.Type, p.Public)
if err != nil {
Expand Down Expand Up @@ -206,12 +205,24 @@ func (rs *FileResource) move(c *gin.Context) {
ginutil.JSONBadRequest(c, err)
return
}

if err = service.FileMove(file, p.NewDir); err != nil {
ginutil.JSONServerError(c, err)
//issue #4
if strings.Contains(p.NewDir, file.Name) {
ginutil.JSONBadRequest(c, errors.New("can't move to itself"))
return
}

if file.IsDir() {
if err = service.FolderMove(file, p.NewDir); err != nil {
ginutil.JSONServerError(c, err)
return
}
} else {
if err = service.FileMove(file, p.NewDir); err != nil {
ginutil.JSONServerError(c, err)
return
}
}

ginutil.JSON(c)
}

Expand Down
2 changes: 1 addition & 1 deletion service/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func UserFileGet(uid int64, alias string) (*model.Matter, error) {
}

func FileUploaded(src *model.Matter) error {
return gormutil.DB().Model(src).Update("uploaded", time.Now()).Error
return gormutil.DB().Model(src).Update("uploaded_at", time.Now()).Error
}

func FileRename(src *model.Matter, name string) error {
Expand Down
15 changes: 15 additions & 0 deletions service/folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@ func FolderRename(src *model.Matter, name string) error {

return gormutil.DB().Transaction(fc)
}

func FolderMove(src *model.Matter, parent string) error {
var children []model.Matter
err := gormutil.DB().Where("parent like ?", "%"+src.Name+"%").Find(&children).Error
if err != nil {
return err
}
for _, v := range children {
err := gormutil.DB().Model(v).Update("parent", parent+src.Name+"/").Error
if err != nil {
return err
}
}
return gormutil.DB().Model(src).Update("parent", parent).Error
}
Loading

0 comments on commit b804fd6

Please sign in to comment.