Compare commits

..

10 Commits

Author SHA1 Message Date
Lunny Xiao
11f6ed4f83 fix api route (#7346) (#7347) 2019-07-03 03:15:55 -04:00
Antoine GIRARD
e94a84248d add .fa margin like .octicon (#7267) 2019-06-20 22:41:21 +08:00
John Olheiser
cf7a5b3d91 Changelog 1.8.3 (#7230)
* Changelog 1.8.3

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Suggestion

Co-Authored-By: zeripath <art27@cantab.net>
2019-06-17 18:08:50 +01:00
zeripath
5d1a8d23b0 Always set userID on LFS authentication (#7224)
* Always set userID on LFS authentication

Fix #5478
Fix #7219

* Deploy keys should only be able to read their repos
2019-06-17 18:36:42 +03:00
zeripath
dbd0a2e6dc Fix LFS Locks over SSH (#6999) (#7223)
* Fix LFS Locks over SSH
* Mark test as skipped
2019-06-17 14:54:49 +01:00
Lunny Xiao
7697a282d6 fix duplicated file on pull request conflicted files (#7211) (#7214) 2019-06-15 17:22:45 +01:00
zeripath
76e8eec3d9 Detect noreply email address as user (#7133) (#7195) 2019-06-13 12:16:50 -04:00
Lunny Xiao
10effb396a if milestone id is zero don't get it from database (#7174) 2019-06-10 23:29:07 +08:00
Lanre Adelowo
5e97b2d00e archived repos can be starred and watched (#7163) (#7168) 2019-06-10 09:20:34 -04:00
Lunny Xiao
873acd884d fix GCArgs load from ini (#7156) (#7157) 2019-06-08 10:41:44 -04:00
12 changed files with 266 additions and 148 deletions

View File

@@ -4,6 +4,16 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.8.3](https://github.com/go-gitea/gitea/releases/tag/v1.8.3) - 2019-06-17
* BUGFIXES
* Always set userID on LFS authentication (#7224) (Part of #6993)
* Fix LFS Locks over SSH (#6999) (#7223)
* Fix duplicated file on pull request conflicted files (#7211) (#7214)
* Detect noreply email address as user (#7133) (#7195)
* Don't get milestone from DB if ID is zero (#7169) (#7174)
* Allow archived repos to be (un)starred and (un)watched (#7163) (#7168)
* Fix GCArgs load from ini (#7156) (#7157)
## [1.8.2](https://github.com/go-gitea/gitea/releases/tag/v1.8.2) - 2019-05-29 ## [1.8.2](https://github.com/go-gitea/gitea/releases/tag/v1.8.2) - 2019-05-29
* BUGFIXES * BUGFIXES
* Fix possbile mysql invalid connnection error (#7051) (#7071) * Fix possbile mysql invalid connnection error (#7051) (#7071)

View File

@@ -219,8 +219,9 @@ func runServ(c *cli.Context) error {
var ( var (
keyID int64 keyID int64
user *models.User user *models.User
userID int64
) )
if requestedMode == models.AccessModeWrite || repo.IsPrivate || setting.Service.RequireSignInView {
keys := strings.Split(c.Args()[0], "-") keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 { if len(keys) != 2 {
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0]) fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
@@ -231,8 +232,8 @@ func runServ(c *cli.Context) error {
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err) fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
} }
keyID = key.ID keyID = key.ID
userID = key.OwnerID
// Check deploy key or user key.
if key.Type == models.KeyTypeDeploy { if key.Type == models.KeyTypeDeploy {
// Now we have to get the deploy key for this repo // Now we have to get the deploy key for this repo
deployKey, err := private.GetDeployKey(key.ID, repo.ID) deployKey, err := private.GetDeployKey(key.ID, repo.ID)
@@ -258,7 +259,9 @@ func runServ(c *cli.Context) error {
// so for now use the owner // so for now use the owner
os.Setenv(models.EnvPusherName, username) os.Setenv(models.EnvPusherName, username)
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", repo.OwnerID)) os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", repo.OwnerID))
} else { userID = repo.OwnerID
} else if requestedMode == models.AccessModeWrite || repo.IsPrivate || setting.Service.RequireSignInView {
// Check deploy key or user key.
user, err = private.GetUserByKeyID(key.ID) user, err = private.GetUserByKeyID(key.ID)
if err != nil { if err != nil {
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err) fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
@@ -286,7 +289,6 @@ func runServ(c *cli.Context) error {
os.Setenv(models.EnvPusherName, user.Name) os.Setenv(models.EnvPusherName, user.Name)
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID)) os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID))
} }
}
//LFS token authentication //LFS token authentication
if verb == lfsAuthenticateVerb { if verb == lfsAuthenticateVerb {
@@ -299,8 +301,8 @@ func runServ(c *cli.Context) error {
"exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(), "exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
"nbf": now.Unix(), "nbf": now.Unix(),
} }
if user != nil { if userID > 0 {
claims["user"] = user.ID claims["user"] = userID
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

View File

@@ -61,6 +61,10 @@ func testGit(t *testing.T, u *url.URL) {
little = commitAndPush(t, littleSize, dstPath) little = commitAndPush(t, littleSize, dstPath)
}) })
t.Run("Big", func(t *testing.T) { t.Run("Big", func(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
return
}
big = commitAndPush(t, bigSize, dstPath) big = commitAndPush(t, bigSize, dstPath)
}) })
}) })
@@ -77,9 +81,15 @@ func testGit(t *testing.T, u *url.URL) {
t.Run("Little", func(t *testing.T) { t.Run("Little", func(t *testing.T) {
littleLFS = commitAndPush(t, littleSize, dstPath) littleLFS = commitAndPush(t, littleSize, dstPath)
lockFileTest(t, littleLFS, dstPath)
}) })
t.Run("Big", func(t *testing.T) { t.Run("Big", func(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
return
}
bigLFS = commitAndPush(t, bigSize, dstPath) bigLFS = commitAndPush(t, bigSize, dstPath)
lockFileTest(t, bigLFS, dstPath)
}) })
}) })
t.Run("Locks", func(t *testing.T) { t.Run("Locks", func(t *testing.T) {
@@ -94,19 +104,21 @@ func testGit(t *testing.T, u *url.URL) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Body.Len()) assert.Equal(t, littleSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", big))
nilResp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, bigSize, nilResp.Length)
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", littleLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", littleLFS))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.NotEqual(t, littleSize, resp.Body.Len()) assert.NotEqual(t, littleSize, resp.Body.Len())
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", big))
nilResp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, bigSize, nilResp.Length)
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", bigLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", bigLFS))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.NotEqual(t, bigSize, resp.Body.Len()) assert.NotEqual(t, bigSize, resp.Body.Len())
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
}
}) })
t.Run("Media", func(t *testing.T) { t.Run("Media", func(t *testing.T) {
@@ -117,17 +129,19 @@ func testGit(t *testing.T, u *url.URL) {
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length) assert.Equal(t, littleSize, resp.Length)
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", big))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Length)
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", littleLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", littleLFS))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length) assert.Equal(t, littleSize, resp.Length)
if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", big))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Length)
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", bigLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", bigLFS))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Length) assert.Equal(t, bigSize, resp.Length)
}
}) })
}) })
@@ -160,6 +174,10 @@ func testGit(t *testing.T, u *url.URL) {
little = commitAndPush(t, littleSize, dstPath) little = commitAndPush(t, littleSize, dstPath)
}) })
t.Run("Big", func(t *testing.T) { t.Run("Big", func(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
return
}
big = commitAndPush(t, bigSize, dstPath) big = commitAndPush(t, bigSize, dstPath)
}) })
}) })
@@ -176,9 +194,16 @@ func testGit(t *testing.T, u *url.URL) {
t.Run("Little", func(t *testing.T) { t.Run("Little", func(t *testing.T) {
littleLFS = commitAndPush(t, littleSize, dstPath) littleLFS = commitAndPush(t, littleSize, dstPath)
lockFileTest(t, littleLFS, dstPath)
}) })
t.Run("Big", func(t *testing.T) { t.Run("Big", func(t *testing.T) {
if testing.Short() {
return
}
bigLFS = commitAndPush(t, bigSize, dstPath) bigLFS = commitAndPush(t, bigSize, dstPath)
lockFileTest(t, bigLFS, dstPath)
}) })
}) })
t.Run("Locks", func(t *testing.T) { t.Run("Locks", func(t *testing.T) {
@@ -193,20 +218,21 @@ func testGit(t *testing.T, u *url.URL) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Body.Len()) assert.Equal(t, littleSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", big))
resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", littleLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", littleLFS))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.NotEqual(t, littleSize, resp.Body.Len()) assert.NotEqual(t, littleSize, resp.Body.Len())
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", big))
resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", bigLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", bigLFS))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.NotEqual(t, bigSize, resp.Body.Len()) assert.NotEqual(t, bigSize, resp.Body.Len())
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier) assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
}
}) })
t.Run("Media", func(t *testing.T) { t.Run("Media", func(t *testing.T) {
session := loginUser(t, "user2") session := loginUser(t, "user2")
@@ -216,17 +242,19 @@ func testGit(t *testing.T, u *url.URL) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Body.Len()) assert.Equal(t, littleSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", big))
resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", littleLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", littleLFS))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Body.Len()) assert.Equal(t, littleSize, resp.Body.Len())
if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", big))
resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", bigLFS)) req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", bigLFS))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, bigSize, resp.Body.Len()) assert.Equal(t, bigSize, resp.Body.Len())
}
}) })
}) })
@@ -243,15 +271,17 @@ func ensureAnonymousClone(t *testing.T, u *url.URL) {
} }
func lockTest(t *testing.T, remote, repoPath string) { func lockTest(t *testing.T, remote, repoPath string) {
_, err := git.NewCommand("remote").AddArguments("set-url", "origin", remote).RunInDir(repoPath) //TODO add test ssh git-lfs-creds lockFileTest(t, "README.md", repoPath)
}
func lockFileTest(t *testing.T, filename, repoPath string) {
_, err := git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
assert.NoError(t, err)
_, err = git.NewCommand("lfs").AddArguments("lock", filename).RunInDir(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
_, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath) _, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
_, err = git.NewCommand("lfs").AddArguments("lock", "README.md").RunInDir(repoPath) _, err = git.NewCommand("lfs").AddArguments("unlock", filename).RunInDir(repoPath)
assert.NoError(t, err)
_, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
assert.NoError(t, err)
_, err = git.NewCommand("lfs").AddArguments("unlock", "README.md").RunInDir(repoPath)
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@@ -861,7 +861,17 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
line := scanner.Text() line := scanner.Text()
if strings.HasPrefix(line, prefix) { if strings.HasPrefix(line, prefix) {
pr.ConflictedFiles = append(pr.ConflictedFiles, strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])) var found bool
var filepath = strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])
for _, f := range pr.ConflictedFiles {
if f == filepath {
found = true
break
}
}
if !found {
pr.ConflictedFiles = append(pr.ConflictedFiles, filepath)
}
} }
// only list 10 conflicted files // only list 10 conflicted files
if len(pr.ConflictedFiles) >= 10 { if len(pr.ConflictedFiles) >= 10 {

View File

@@ -1346,6 +1346,19 @@ func GetUserByEmail(email string) (*User, error) {
return GetUserByID(emailAddress.UID) return GetUserByID(emailAddress.UID)
} }
// Finally, if email address is the protected email address:
if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) {
username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress))
user := &User{LowerName: username}
has, err := x.Get(user)
if err != nil {
return nil, err
}
if has {
return user, nil
}
}
return nil, ErrUserNotExist{0, email, 0} return nil, ErrUserNotExist{0, email, 0}
} }

View File

@@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
@@ -44,7 +45,7 @@ func checkIsValidRequest(ctx *context.Context, post bool) bool {
return true return true
} }
func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) { func handleLockListOut(ctx *context.Context, repo *models.Repository, lock *models.LFSLock, err error) {
if err != nil { if err != nil {
if models.IsErrLFSLockNotExist(err) { if models.IsErrLFSLockNotExist(err) {
ctx.JSON(200, api.LFSLockList{ ctx.JSON(200, api.LFSLockList{
@@ -57,7 +58,7 @@ func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) {
}) })
return return
} }
if ctx.Repo.Repository.ID != lock.RepoID { if repo.ID != lock.RepoID {
ctx.JSON(200, api.LFSLockList{ ctx.JSON(200, api.LFSLockList{
Locks: []*api.LFSLock{}, Locks: []*api.LFSLock{},
}) })
@@ -75,17 +76,21 @@ func GetListLockHandler(ctx *context.Context) {
} }
ctx.Resp.Header().Set("Content-Type", metaMediaType) ctx.Resp.Header().Set("Content-Type", metaMediaType)
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository, models.AccessModeRead) rv := unpack(ctx)
repository, err := models.GetRepositoryByOwnerAndName(rv.User, rv.Repo)
if err != nil { if err != nil {
if models.IsErrLFSUnauthorizedAction(err) { log.Debug("Could not find repository: %s/%s - %s", rv.User, rv.Repo, err)
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs") writeStatus(ctx, 404)
ctx.JSON(401, api.LFSLockError{
Message: "You must have pull access to list locks : " + err.Error(),
})
return return
} }
ctx.JSON(500, api.LFSLockError{ repository.MustOwner()
Message: "unable to list lock : " + err.Error(),
authenticated := authenticate(ctx, repository, rv.Authorization, false)
if !authenticated {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have pull access to list locks",
}) })
return return
} }
@@ -100,19 +105,19 @@ func GetListLockHandler(ctx *context.Context) {
return return
} }
lock, err := models.GetLFSLockByID(int64(v)) lock, err := models.GetLFSLockByID(int64(v))
handleLockListOut(ctx, lock, err) handleLockListOut(ctx, repository, lock, err)
return return
} }
path := ctx.Query("path") path := ctx.Query("path")
if path != "" { //Case where we request a specific id if path != "" { //Case where we request a specific id
lock, err := models.GetLFSLock(ctx.Repo.Repository, path) lock, err := models.GetLFSLock(repository, path)
handleLockListOut(ctx, lock, err) handleLockListOut(ctx, repository, lock, err)
return return
} }
//If no query params path or id //If no query params path or id
lockList, err := models.GetLFSLockByRepoID(ctx.Repo.Repository.ID) lockList, err := models.GetLFSLockByRepoID(repository.ID)
if err != nil { if err != nil {
ctx.JSON(500, api.LFSLockError{ ctx.JSON(500, api.LFSLockError{
Message: "unable to list locks : " + err.Error(), Message: "unable to list locks : " + err.Error(),
@@ -135,16 +140,36 @@ func PostLockHandler(ctx *context.Context) {
} }
ctx.Resp.Header().Set("Content-Type", metaMediaType) ctx.Resp.Header().Set("Content-Type", metaMediaType)
userName := ctx.Params("username")
repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
authorization := ctx.Req.Header.Get("Authorization")
repository, err := models.GetRepositoryByOwnerAndName(userName, repoName)
if err != nil {
log.Debug("Could not find repository: %s/%s - %s", userName, repoName, err)
writeStatus(ctx, 404)
return
}
repository.MustOwner()
authenticated := authenticate(ctx, repository, authorization, true)
if !authenticated {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to create locks",
})
return
}
var req api.LFSLockRequest var req api.LFSLockRequest
dec := json.NewDecoder(ctx.Req.Body().ReadCloser()) dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
err := dec.Decode(&req) if err := dec.Decode(&req); err != nil {
if err != nil {
writeStatus(ctx, 400) writeStatus(ctx, 400)
return return
} }
lock, err := models.CreateLFSLock(&models.LFSLock{ lock, err := models.CreateLFSLock(&models.LFSLock{
Repo: ctx.Repo.Repository, Repo: repository,
Path: req.Path, Path: req.Path,
Owner: ctx.User, Owner: ctx.User,
}) })
@@ -178,23 +203,29 @@ func VerifyLockHandler(ctx *context.Context) {
} }
ctx.Resp.Header().Set("Content-Type", metaMediaType) ctx.Resp.Header().Set("Content-Type", metaMediaType)
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository, models.AccessModeWrite) userName := ctx.Params("username")
repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
authorization := ctx.Req.Header.Get("Authorization")
repository, err := models.GetRepositoryByOwnerAndName(userName, repoName)
if err != nil { if err != nil {
if models.IsErrLFSUnauthorizedAction(err) { log.Debug("Could not find repository: %s/%s - %s", userName, repoName, err)
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs") writeStatus(ctx, 404)
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to verify locks : " + err.Error(),
})
return return
} }
ctx.JSON(500, api.LFSLockError{ repository.MustOwner()
Message: "unable to verify lock : " + err.Error(),
authenticated := authenticate(ctx, repository, authorization, true)
if !authenticated {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to verify locks",
}) })
return return
} }
//TODO handle body json cursor and limit //TODO handle body json cursor and limit
lockList, err := models.GetLFSLockByRepoID(ctx.Repo.Repository.ID) lockList, err := models.GetLFSLockByRepoID(repository.ID)
if err != nil { if err != nil {
ctx.JSON(500, api.LFSLockError{ ctx.JSON(500, api.LFSLockError{
Message: "unable to list locks : " + err.Error(), Message: "unable to list locks : " + err.Error(),
@@ -223,10 +254,30 @@ func UnLockHandler(ctx *context.Context) {
} }
ctx.Resp.Header().Set("Content-Type", metaMediaType) ctx.Resp.Header().Set("Content-Type", metaMediaType)
userName := ctx.Params("username")
repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
authorization := ctx.Req.Header.Get("Authorization")
repository, err := models.GetRepositoryByOwnerAndName(userName, repoName)
if err != nil {
log.Debug("Could not find repository: %s/%s - %s", userName, repoName, err)
writeStatus(ctx, 404)
return
}
repository.MustOwner()
authenticated := authenticate(ctx, repository, authorization, true)
if !authenticated {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to delete locks",
})
return
}
var req api.LFSLockDeleteRequest var req api.LFSLockDeleteRequest
dec := json.NewDecoder(ctx.Req.Body().ReadCloser()) dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
err := dec.Decode(&req) if err := dec.Decode(&req); err != nil {
if err != nil {
writeStatus(ctx, 400) writeStatus(ctx, 400)
return return
} }

View File

@@ -20,7 +20,7 @@ var (
MaxGitDiffLines int MaxGitDiffLines int
MaxGitDiffLineCharacters int MaxGitDiffLineCharacters int
MaxGitDiffFiles int MaxGitDiffFiles int
GCArgs []string `delim:" "` GCArgs []string `ini:"GC_ARGS" delim:" "`
Timeout struct { Timeout struct {
Default int Default int
Migrate int Migrate int

File diff suppressed because one or more lines are too long

View File

@@ -23,7 +23,7 @@
border-bottom: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea;
} }
.octicon { .octicon, .fa {
margin-left: 1px; margin-left: 1px;
margin-right: 5px; margin-right: 5px;
} }

View File

@@ -698,14 +698,14 @@ func RegisterRoutes(m *macaron.Macaron) {
Delete(reqToken(), reqOrgMembership(), org.ConcealMember) Delete(reqToken(), reqOrgMembership(), org.ConcealMember)
}) })
m.Combo("/teams", reqToken(), reqOrgMembership()).Get(org.ListTeams). m.Combo("/teams", reqToken(), reqOrgMembership()).Get(org.ListTeams).
Post(bind(api.CreateTeamOption{}), org.CreateTeam) Post(reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
m.Group("/hooks", func() { m.Group("/hooks", func() {
m.Combo("").Get(org.ListHooks). m.Combo("").Get(org.ListHooks).
Post(bind(api.CreateHookOption{}), org.CreateHook) Post(bind(api.CreateHookOption{}), org.CreateHook)
m.Combo("/:id").Get(org.GetHook). m.Combo("/:id").Get(org.GetHook).
Patch(reqOrgOwnership(), bind(api.EditHookOption{}), org.EditHook). Patch(bind(api.EditHookOption{}), org.EditHook).
Delete(reqOrgOwnership(), org.DeleteHook) Delete(org.DeleteHook)
}, reqToken(), reqOrgMembership()) }, reqToken(), reqOrgOwnership())
}, orgAssignment(true)) }, orgAssignment(true))
m.Group("/teams/:teamid", func() { m.Group("/teams/:teamid", func() {
m.Combo("").Get(org.GetTeam). m.Combo("").Get(org.GetTeam).

View File

@@ -406,6 +406,7 @@ func NewIssue(ctx *context.Context) {
ctx.Data["BodyQuery"] = body ctx.Data["BodyQuery"] = body
milestoneID := ctx.QueryInt64("milestone") milestoneID := ctx.QueryInt64("milestone")
if milestoneID > 0 {
milestone, err := models.GetMilestoneByID(milestoneID) milestone, err := models.GetMilestoneByID(milestoneID)
if err != nil { if err != nil {
log.Error(4, "GetMilestoneByID: %d: %v", milestoneID, err) log.Error(4, "GetMilestoneByID: %d: %v", milestoneID, err)
@@ -413,6 +414,7 @@ func NewIssue(ctx *context.Context) {
ctx.Data["milestone_id"] = milestoneID ctx.Data["milestone_id"] = milestoneID
ctx.Data["Milestone"] = milestone ctx.Data["Milestone"] = milestone
} }
}
setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates) setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
renderAttachmentSettings(ctx) renderAttachmentSettings(ctx)

View File

@@ -578,7 +578,7 @@ func RegisterRoutes(m *macaron.Macaron) {
}) })
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.UnitTypes(), context.RepoRef()) }, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.UnitTypes(), context.RepoRef())
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), context.RepoMustNotBeArchived(), repo.Action) m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Group("/issues", func() { m.Group("/issues", func() {
@@ -827,7 +827,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/", lfs.PostLockHandler) m.Post("/", lfs.PostLockHandler)
m.Post("/verify", lfs.VerifyLockHandler) m.Post("/verify", lfs.VerifyLockHandler)
m.Post("/:lid/unlock", lfs.UnLockHandler) m.Post("/:lid/unlock", lfs.UnLockHandler)
}, context.RepoAssignment()) })
m.Any("/*", func(ctx *context.Context) { m.Any("/*", func(ctx *context.Context) {
ctx.NotFound("", nil) ctx.NotFound("", nil)
}) })