Fix git lfs path (#3016)
* add suffix .git * Remove Content-Type on GET methods * Add migrations to force creation before any further potential migration
This commit is contained in:
parent
c80d147fa9
commit
4035ab05fa
5 changed files with 58 additions and 21 deletions
|
@ -23,13 +23,13 @@ func TestAPILFSLocksNotStarted(t *testing.T) {
|
||||||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||||
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
||||||
|
|
||||||
req := NewRequestf(t, "GET", "/%s/%s/info/lfs/locks", user.Name, repo.Name)
|
req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
req = NewRequestf(t, "POST", "/%s/%s/info/lfs/locks", user.Name, repo.Name)
|
req = NewRequestf(t, "POST", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
req = NewRequestf(t, "GET", "/%s/%s/info/lfs/locks/verify", user.Name, repo.Name)
|
req = NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks/verify", user.Name, repo.Name)
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
req = NewRequestf(t, "GET", "/%s/%s/info/lfs/locks/10/unlock", user.Name, repo.Name)
|
req = NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks/10/unlock", user.Name, repo.Name)
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +39,8 @@ func TestAPILFSLocksNotLogin(t *testing.T) {
|
||||||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||||
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
||||||
|
|
||||||
req := NewRequestf(t, "GET", "/%s/%s/info/lfs/locks", user.Name, repo.Name)
|
req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
|
||||||
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
||||||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
|
||||||
resp := MakeRequest(t, req, http.StatusForbidden)
|
resp := MakeRequest(t, req, http.StatusForbidden)
|
||||||
var lfsLockError api.LFSLockError
|
var lfsLockError api.LFSLockError
|
||||||
DecodeJSON(t, resp, &lfsLockError)
|
DecodeJSON(t, resp, &lfsLockError)
|
||||||
|
@ -102,7 +101,7 @@ func TestAPILFSLocksLogged(t *testing.T) {
|
||||||
//create locks
|
//create locks
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
session := loginUser(t, test.user.Name)
|
session := loginUser(t, test.user.Name)
|
||||||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/info/lfs/locks", test.repo.FullName()), map[string]string{"path": test.path})
|
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks", test.repo.FullName()), map[string]string{"path": test.path})
|
||||||
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
||||||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
||||||
session.MakeRequest(t, req, test.httpResult)
|
session.MakeRequest(t, req, test.httpResult)
|
||||||
|
@ -116,9 +115,8 @@ func TestAPILFSLocksLogged(t *testing.T) {
|
||||||
//check creation
|
//check creation
|
||||||
for _, test := range resultsTests {
|
for _, test := range resultsTests {
|
||||||
session := loginUser(t, test.user.Name)
|
session := loginUser(t, test.user.Name)
|
||||||
req := NewRequestf(t, "GET", "/%s/info/lfs/locks", test.repo.FullName())
|
req := NewRequestf(t, "GET", "/%s.git/info/lfs/locks", test.repo.FullName())
|
||||||
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
||||||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
var lfsLocks api.LFSLockList
|
var lfsLocks api.LFSLockList
|
||||||
DecodeJSON(t, resp, &lfsLocks)
|
DecodeJSON(t, resp, &lfsLocks)
|
||||||
|
@ -128,7 +126,7 @@ func TestAPILFSLocksLogged(t *testing.T) {
|
||||||
assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 1*time.Second)
|
assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 1*time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/info/lfs/locks/verify", test.repo.FullName()), map[string]string{})
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks/verify", test.repo.FullName()), map[string]string{})
|
||||||
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
||||||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
@ -152,7 +150,7 @@ func TestAPILFSLocksLogged(t *testing.T) {
|
||||||
//remove all locks
|
//remove all locks
|
||||||
for _, test := range deleteTests {
|
for _, test := range deleteTests {
|
||||||
session := loginUser(t, test.user.Name)
|
session := loginUser(t, test.user.Name)
|
||||||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/info/lfs/locks/%s/unlock", test.repo.FullName(), test.lockID), map[string]string{})
|
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks/%s/unlock", test.repo.FullName(), test.lockID), map[string]string{})
|
||||||
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
||||||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
@ -165,9 +163,8 @@ func TestAPILFSLocksLogged(t *testing.T) {
|
||||||
// check that we don't have any lock
|
// check that we don't have any lock
|
||||||
for _, test := range resultsTests {
|
for _, test := range resultsTests {
|
||||||
session := loginUser(t, test.user.Name)
|
session := loginUser(t, test.user.Name)
|
||||||
req := NewRequestf(t, "GET", "/%s/info/lfs/locks", test.repo.FullName())
|
req := NewRequestf(t, "GET", "/%s.git/info/lfs/locks", test.repo.FullName())
|
||||||
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
req.Header.Set("Accept", "application/vnd.git-lfs+json")
|
||||||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json")
|
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
var lfsLocks api.LFSLockList
|
var lfsLocks api.LFSLockList
|
||||||
DecodeJSON(t, resp, &lfsLocks)
|
DecodeJSON(t, resp, &lfsLocks)
|
||||||
|
|
|
@ -110,7 +110,7 @@ var migrations = []Migration{
|
||||||
NewMigration("add commit status table", addCommitStatus),
|
NewMigration("add commit status table", addCommitStatus),
|
||||||
// v30 -> 31
|
// v30 -> 31
|
||||||
NewMigration("add primary key to external login user", addExternalLoginUserPK),
|
NewMigration("add primary key to external login user", addExternalLoginUserPK),
|
||||||
// 31 -> 32
|
// v31 -> 32
|
||||||
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
|
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
|
||||||
// v32 -> v33
|
// v32 -> v33
|
||||||
NewMigration("add units for team", addUnitsToRepoTeam),
|
NewMigration("add units for team", addUnitsToRepoTeam),
|
||||||
|
@ -146,6 +146,8 @@ var migrations = []Migration{
|
||||||
NewMigration("add deleted branches", addDeletedBranch),
|
NewMigration("add deleted branches", addDeletedBranch),
|
||||||
// v48 -> v49
|
// v48 -> v49
|
||||||
NewMigration("add repo indexer status", addRepoIndexerStatus),
|
NewMigration("add repo indexer status", addRepoIndexerStatus),
|
||||||
|
// v49 -> v50
|
||||||
|
NewMigration("add lfs lock table", addLFSLock),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate database to current version
|
// Migrate database to current version
|
||||||
|
|
31
models/migrations/v49.go
Normal file
31
models/migrations/v49.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2017 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 (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func addLFSLock(x *xorm.Engine) error {
|
||||||
|
// LFSLock see models/lfs_lock.go
|
||||||
|
type LFSLock struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
RepoID int64 `xorm:"INDEX NOT NULL"`
|
||||||
|
Owner *models.User `xorm:"-"`
|
||||||
|
OwnerID int64 `xorm:"INDEX NOT NULL"`
|
||||||
|
Path string `xorm:"TEXT"`
|
||||||
|
Created time.Time `xorm:"created"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.Sync2(new(LFSLock)); err != nil {
|
||||||
|
return fmt.Errorf("Sync2: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ package lfs
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
@ -16,13 +17,19 @@ import (
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkRequest(req macaron.Request) int {
|
func checkRequest(req macaron.Request, post bool) int {
|
||||||
if !setting.LFS.StartServer {
|
if !setting.LFS.StartServer {
|
||||||
return 404
|
return 404
|
||||||
}
|
}
|
||||||
if !MetaMatcher(req) || req.Header.Get("Content-Type") != metaMediaType {
|
if !MetaMatcher(req) {
|
||||||
return 400
|
return 400
|
||||||
}
|
}
|
||||||
|
if post {
|
||||||
|
mediaParts := strings.Split(req.Header.Get("Content-Type"), ";")
|
||||||
|
if mediaParts[0] != metaMediaType {
|
||||||
|
return 400
|
||||||
|
}
|
||||||
|
}
|
||||||
return 200
|
return 200
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +59,7 @@ func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) {
|
||||||
|
|
||||||
// GetListLockHandler list locks
|
// GetListLockHandler list locks
|
||||||
func GetListLockHandler(ctx *context.Context) {
|
func GetListLockHandler(ctx *context.Context) {
|
||||||
status := checkRequest(ctx.Req)
|
status := checkRequest(ctx.Req, false)
|
||||||
if status != 200 {
|
if status != 200 {
|
||||||
writeStatus(ctx, status)
|
writeStatus(ctx, status)
|
||||||
return
|
return
|
||||||
|
@ -113,7 +120,7 @@ func GetListLockHandler(ctx *context.Context) {
|
||||||
|
|
||||||
// PostLockHandler create lock
|
// PostLockHandler create lock
|
||||||
func PostLockHandler(ctx *context.Context) {
|
func PostLockHandler(ctx *context.Context) {
|
||||||
status := checkRequest(ctx.Req)
|
status := checkRequest(ctx.Req, true)
|
||||||
if status != 200 {
|
if status != 200 {
|
||||||
writeStatus(ctx, status)
|
writeStatus(ctx, status)
|
||||||
return
|
return
|
||||||
|
@ -157,7 +164,7 @@ func PostLockHandler(ctx *context.Context) {
|
||||||
|
|
||||||
// VerifyLockHandler list locks for verification
|
// VerifyLockHandler list locks for verification
|
||||||
func VerifyLockHandler(ctx *context.Context) {
|
func VerifyLockHandler(ctx *context.Context) {
|
||||||
status := checkRequest(ctx.Req)
|
status := checkRequest(ctx.Req, true)
|
||||||
if status != 200 {
|
if status != 200 {
|
||||||
writeStatus(ctx, status)
|
writeStatus(ctx, status)
|
||||||
return
|
return
|
||||||
|
@ -204,7 +211,7 @@ func VerifyLockHandler(ctx *context.Context) {
|
||||||
|
|
||||||
// UnLockHandler delete locks
|
// UnLockHandler delete locks
|
||||||
func UnLockHandler(ctx *context.Context) {
|
func UnLockHandler(ctx *context.Context) {
|
||||||
status := checkRequest(ctx.Req)
|
status := checkRequest(ctx.Req, true)
|
||||||
if status != 200 {
|
if status != 200 {
|
||||||
writeStatus(ctx, status)
|
writeStatus(ctx, status)
|
||||||
return
|
return
|
||||||
|
|
|
@ -679,7 +679,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes(), context.LoadRepoUnits())
|
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes(), context.LoadRepoUnits())
|
||||||
|
|
||||||
m.Group("/:reponame", func() {
|
m.Group("/:reponame", func() {
|
||||||
m.Group("/info/lfs", func() {
|
m.Group("\\.git/info/lfs", func() {
|
||||||
m.Post("/objects/batch", lfs.BatchHandler)
|
m.Post("/objects/batch", lfs.BatchHandler)
|
||||||
m.Get("/objects/:oid/:filename", lfs.ObjectOidHandler)
|
m.Get("/objects/:oid/:filename", lfs.ObjectOidHandler)
|
||||||
m.Any("/objects/:oid", lfs.ObjectOidHandler)
|
m.Any("/objects/:oid", lfs.ObjectOidHandler)
|
||||||
|
|
Reference in a new issue