* fix upload attachments * add migration for new column uploader_id on table attachment * fix imports sequencetags/v1.9.0-rc1
| @@ -7,7 +7,6 @@ package models | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| "io" | "io" | ||||
| "mime/multipart" | |||||
| "os" | "os" | ||||
| "path" | "path" | ||||
| @@ -25,6 +24,7 @@ type Attachment struct { | |||||
| UUID string `xorm:"uuid UNIQUE"` | UUID string `xorm:"uuid UNIQUE"` | ||||
| IssueID int64 `xorm:"INDEX"` | IssueID int64 `xorm:"INDEX"` | ||||
| ReleaseID int64 `xorm:"INDEX"` | ReleaseID int64 `xorm:"INDEX"` | ||||
| UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added | |||||
| CommentID int64 | CommentID int64 | ||||
| Name string | Name string | ||||
| DownloadCount int64 `xorm:"DEFAULT 0"` | DownloadCount int64 `xorm:"DEFAULT 0"` | ||||
| @@ -72,11 +72,8 @@ func (a *Attachment) DownloadURL() string { | |||||
| } | } | ||||
| // NewAttachment creates a new attachment object. | // NewAttachment creates a new attachment object. | ||||
| func NewAttachment(name string, buf []byte, file multipart.File) (_ *Attachment, err error) { | |||||
| attach := &Attachment{ | |||||
| UUID: gouuid.NewV4().String(), | |||||
| Name: name, | |||||
| } | |||||
| func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) { | |||||
| attach.UUID = gouuid.NewV4().String() | |||||
| localPath := attach.LocalPath() | localPath := attach.LocalPath() | ||||
| if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { | if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { | ||||
| @@ -5,11 +5,40 @@ | |||||
| package models | package models | ||||
| import ( | import ( | ||||
| "os" | |||||
| "path/filepath" | |||||
| "testing" | "testing" | ||||
| "github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
| ) | ) | ||||
| func TestUploadAttachment(t *testing.T) { | |||||
| assert.NoError(t, PrepareTestDatabase()) | |||||
| user := AssertExistsAndLoadBean(t, &User{ID: 1}).(*User) | |||||
| var fPath = "./attachment_test.go" | |||||
| f, err := os.Open(fPath) | |||||
| assert.NoError(t, err) | |||||
| defer f.Close() | |||||
| var buf = make([]byte, 1024) | |||||
| n, err := f.Read(buf) | |||||
| assert.NoError(t, err) | |||||
| buf = buf[:n] | |||||
| attach, err := NewAttachment(&Attachment{ | |||||
| UploaderID: user.ID, | |||||
| Name: filepath.Base(fPath), | |||||
| }, buf, f) | |||||
| assert.NoError(t, err) | |||||
| attachment, err := GetAttachmentByUUID(attach.UUID) | |||||
| assert.NoError(t, err) | |||||
| assert.EqualValues(t, user.ID, attachment.UploaderID) | |||||
| assert.Equal(t, int64(0), attachment.DownloadCount) | |||||
| } | |||||
| func TestIncreaseDownloadCount(t *testing.T) { | func TestIncreaseDownloadCount(t *testing.T) { | ||||
| assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
| @@ -219,6 +219,8 @@ var migrations = []Migration{ | |||||
| NewMigration("update U2F counter type", changeU2FCounterType), | NewMigration("update U2F counter type", changeU2FCounterType), | ||||
| // v82 -> v83 | // v82 -> v83 | ||||
| NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable), | NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable), | ||||
| // v83 -> v84 | |||||
| NewMigration("add uploader id for table attachment", addUploaderIDForAttachment), | |||||
| } | } | ||||
| // Migrate database to current version | // Migrate database to current version | ||||
| @@ -0,0 +1,28 @@ | |||||
| // Copyright 2019 The Gitea Authors. All rights reserved. | |||||
| // Use of this source code is governed by a MIT-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package migrations | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/util" | |||||
| "github.com/go-xorm/xorm" | |||||
| ) | |||||
| func addUploaderIDForAttachment(x *xorm.Engine) error { | |||||
| type Attachment struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| UUID string `xorm:"uuid UNIQUE"` | |||||
| IssueID int64 `xorm:"INDEX"` | |||||
| ReleaseID int64 `xorm:"INDEX"` | |||||
| UploaderID int64 `xorm:"INDEX DEFAULT 0"` | |||||
| CommentID int64 | |||||
| Name string | |||||
| DownloadCount int64 `xorm:"DEFAULT 0"` | |||||
| Size int64 `xorm:"DEFAULT 0"` | |||||
| CreatedUnix util.TimeStamp `xorm:"created"` | |||||
| } | |||||
| return x.Sync2(new(Attachment)) | |||||
| } | |||||
| @@ -200,16 +200,16 @@ func CreateReleaseAttachment(ctx *context.APIContext) { | |||||
| } | } | ||||
| // Create a new attachment and save the file | // Create a new attachment and save the file | ||||
| attach, err := models.NewAttachment(filename, buf, file) | |||||
| attach, err := models.NewAttachment(&models.Attachment{ | |||||
| UploaderID: ctx.User.ID, | |||||
| Name: filename, | |||||
| ReleaseID: release.ID, | |||||
| }, buf, file) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Error(500, "NewAttachment", err) | ctx.Error(500, "NewAttachment", err) | ||||
| return | return | ||||
| } | } | ||||
| attach.ReleaseID = release.ID | |||||
| if err := models.UpdateAttachment(attach); err != nil { | |||||
| ctx.Error(500, "UpdateAttachment", err) | |||||
| return | |||||
| } | |||||
| ctx.JSON(201, attach.APIFormat()) | ctx.JSON(201, attach.APIFormat()) | ||||
| } | } | ||||
| @@ -60,7 +60,10 @@ func UploadAttachment(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| attach, err := models.NewAttachment(header.Filename, buf, file) | |||||
| attach, err := models.NewAttachment(&models.Attachment{ | |||||
| UploaderID: ctx.User.ID, | |||||
| Name: header.Filename, | |||||
| }, buf, file) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Error(500, fmt.Sprintf("NewAttachment: %v", err)) | ctx.Error(500, fmt.Sprintf("NewAttachment: %v", err)) | ||||
| return | return | ||||
| @@ -480,9 +480,12 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| return | return | ||||
| } | } | ||||
| }) | }) | ||||
| m.Post("/attachments", repo.UploadAttachment) | |||||
| }, ignSignIn) | }, ignSignIn) | ||||
| m.Group("", func() { | |||||
| m.Post("/attachments", repo.UploadAttachment) | |||||
| }, reqSignIn) | |||||
| m.Group("/:username", func() { | m.Group("/:username", func() { | ||||
| m.Get("/action/:action", user.Action) | m.Get("/action/:action", user.Action) | ||||
| }, reqSignIn) | }, reqSignIn) | ||||