From 4035ab05fa2d2c8ec95d346fea91cab8211dab17 Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Wed, 29 Nov 2017 00:35:23 +0100 Subject: [PATCH] Fix git lfs path (#3016) * add suffix .git * Remove Content-Type on GET methods * Add migrations to force creation before any further potential migration --- integrations/api_repo_lfs_locks_test.go | 23 ++++++++---------- models/migrations/migrations.go | 4 +++- models/migrations/v49.go | 31 +++++++++++++++++++++++++ modules/lfs/locks.go | 19 ++++++++++----- routers/routes/routes.go | 2 +- 5 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 models/migrations/v49.go diff --git a/integrations/api_repo_lfs_locks_test.go b/integrations/api_repo_lfs_locks_test.go index 9fd796b6c..11b017e87 100644 --- a/integrations/api_repo_lfs_locks_test.go +++ b/integrations/api_repo_lfs_locks_test.go @@ -23,13 +23,13 @@ func TestAPILFSLocksNotStarted(t *testing.T) { user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) 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) - 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) - 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) - 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) } @@ -39,9 +39,8 @@ func TestAPILFSLocksNotLogin(t *testing.T) { user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) 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("Content-Type", "application/vnd.git-lfs+json") resp := MakeRequest(t, req, http.StatusForbidden) var lfsLockError api.LFSLockError DecodeJSON(t, resp, &lfsLockError) @@ -102,7 +101,7 @@ func TestAPILFSLocksLogged(t *testing.T) { //create locks for _, test := range tests { 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("Content-Type", "application/vnd.git-lfs+json") session.MakeRequest(t, req, test.httpResult) @@ -116,9 +115,8 @@ func TestAPILFSLocksLogged(t *testing.T) { //check creation for _, test := range resultsTests { 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("Content-Type", "application/vnd.git-lfs+json") resp := session.MakeRequest(t, req, http.StatusOK) var lfsLocks api.LFSLockList DecodeJSON(t, resp, &lfsLocks) @@ -128,7 +126,7 @@ func TestAPILFSLocksLogged(t *testing.T) { 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("Content-Type", "application/vnd.git-lfs+json") resp = session.MakeRequest(t, req, http.StatusOK) @@ -152,7 +150,7 @@ func TestAPILFSLocksLogged(t *testing.T) { //remove all locks for _, test := range deleteTests { 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("Content-Type", "application/vnd.git-lfs+json") resp := session.MakeRequest(t, req, http.StatusOK) @@ -165,9 +163,8 @@ func TestAPILFSLocksLogged(t *testing.T) { // check that we don't have any lock for _, test := range resultsTests { 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("Content-Type", "application/vnd.git-lfs+json") resp := session.MakeRequest(t, req, http.StatusOK) var lfsLocks api.LFSLockList DecodeJSON(t, resp, &lfsLocks) diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index ba27568fd..bccf6e692 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -110,7 +110,7 @@ var migrations = []Migration{ NewMigration("add commit status table", addCommitStatus), // v30 -> 31 NewMigration("add primary key to external login user", addExternalLoginUserPK), - // 31 -> 32 + // v31 -> 32 NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn), // v32 -> v33 NewMigration("add units for team", addUnitsToRepoTeam), @@ -146,6 +146,8 @@ var migrations = []Migration{ NewMigration("add deleted branches", addDeletedBranch), // v48 -> v49 NewMigration("add repo indexer status", addRepoIndexerStatus), + // v49 -> v50 + NewMigration("add lfs lock table", addLFSLock), } // Migrate database to current version diff --git a/models/migrations/v49.go b/models/migrations/v49.go new file mode 100644 index 000000000..ab57d27de --- /dev/null +++ b/models/migrations/v49.go @@ -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 +} diff --git a/modules/lfs/locks.go b/modules/lfs/locks.go index 38d290e13..2e776c26a 100644 --- a/modules/lfs/locks.go +++ b/modules/lfs/locks.go @@ -7,6 +7,7 @@ package lfs import ( "encoding/json" "strconv" + "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -16,13 +17,19 @@ import ( "gopkg.in/macaron.v1" ) -func checkRequest(req macaron.Request) int { +func checkRequest(req macaron.Request, post bool) int { if !setting.LFS.StartServer { return 404 } - if !MetaMatcher(req) || req.Header.Get("Content-Type") != metaMediaType { + if !MetaMatcher(req) { return 400 } + if post { + mediaParts := strings.Split(req.Header.Get("Content-Type"), ";") + if mediaParts[0] != metaMediaType { + return 400 + } + } return 200 } @@ -52,7 +59,7 @@ func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) { // GetListLockHandler list locks func GetListLockHandler(ctx *context.Context) { - status := checkRequest(ctx.Req) + status := checkRequest(ctx.Req, false) if status != 200 { writeStatus(ctx, status) return @@ -113,7 +120,7 @@ func GetListLockHandler(ctx *context.Context) { // PostLockHandler create lock func PostLockHandler(ctx *context.Context) { - status := checkRequest(ctx.Req) + status := checkRequest(ctx.Req, true) if status != 200 { writeStatus(ctx, status) return @@ -157,7 +164,7 @@ func PostLockHandler(ctx *context.Context) { // VerifyLockHandler list locks for verification func VerifyLockHandler(ctx *context.Context) { - status := checkRequest(ctx.Req) + status := checkRequest(ctx.Req, true) if status != 200 { writeStatus(ctx, status) return @@ -204,7 +211,7 @@ func VerifyLockHandler(ctx *context.Context) { // UnLockHandler delete locks func UnLockHandler(ctx *context.Context) { - status := checkRequest(ctx.Req) + status := checkRequest(ctx.Req, true) if status != 200 { writeStatus(ctx, status) return diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 2945c3147..56d4b5393 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -679,7 +679,7 @@ func RegisterRoutes(m *macaron.Macaron) { }, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes(), context.LoadRepoUnits()) m.Group("/:reponame", func() { - m.Group("/info/lfs", func() { + m.Group("\\.git/info/lfs", func() { m.Post("/objects/batch", lfs.BatchHandler) m.Get("/objects/:oid/:filename", lfs.ObjectOidHandler) m.Any("/objects/:oid", lfs.ObjectOidHandler)