Skip to content

Commit b5dda73

Browse files
unknwonmpsonntag
authored andcommittedNov 26, 2020
route: bypass require signin check for trigger repo tasks (#6079)
* route: bypass require signin check for trigger repo tasks * CHANGELOG * Fix lint errors
1 parent ce19124 commit b5dda73

File tree

6 files changed

+82
-54
lines changed

6 files changed

+82
-54
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ All notable changes to Gogs are documented in this file.
5151
- Enable Federated Avatar Lookup could cause server to crash. [#5848](https://github.com/gogs/gogs/issues/5848)
5252
- Private repositories are hidden in the organization's view. [#5869](https://github.com/gogs/gogs/issues/5869)
5353
- Server error when changing email address in user settings page. [#5899](https://github.com/gogs/gogs/issues/5899)
54+
- Webhooks are not fired after push when `[service] REQUIRE_SIGNIN_VIEW = true`.
5455

5556
### Removed
5657

‎internal/cmd/hook.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,10 @@ func runHookPostReceive(c *cli.Context) error {
238238
reqURL := fmt.Sprintf("%s%s/%s/tasks/trigger?%s", conf.Server.LocalRootURL, options.RepoUserName, options.RepoName, q.Encode())
239239
log.Trace("Trigger task: %s", reqURL)
240240

241-
resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
242-
InsecureSkipVerify: true,
243-
}).Response()
241+
resp, err := httplib.Get(reqURL).
242+
SetTLSClientConfig(&tls.Config{
243+
InsecureSkipVerify: true,
244+
}).Response()
244245
if err == nil {
245246
_ = resp.Body.Close()
246247
if resp.StatusCode/100 != 2 {

‎internal/cmd/web.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,6 @@ func runWeb(c *cli.Context) error {
635635
m.Get("", repo.Home)
636636
m.Get("/stars", repo.Stars)
637637
m.Get("/watchers", repo.Watchers)
638-
m.Head("/tasks/trigger", repo.TriggerTask) // TODO: Without session and CSRF
639638
}, ignSignIn, context.RepoAssignment(), context.RepoRef())
640639

641640
// GIN specific code
@@ -684,6 +683,8 @@ func runWeb(c *cli.Context) error {
684683
// ***************************
685684

686685
m.Group("/:username/:reponame", func() {
686+
m.Get("/tasks/trigger", repo.TriggerTask)
687+
687688
m.Group("/info/lfs", func() {
688689
lfs.RegisterRoutes(m.Router)
689690
})

‎internal/route/lfs/route.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func authenticate() macaron.Handler {
8585
// Once we found the token, we're supposed to find its related user,
8686
// thus any error is unexpected.
8787
internalServerError(c.Resp)
88-
log.Error("Failed to get user: %v", err)
88+
log.Error("Failed to get user [id: %d]: %v", token.UserID, err)
8989
return
9090
}
9191
}

‎internal/route/repo/pull.go

-49
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/G-Node/gogs/internal/db"
2020
"github.com/G-Node/gogs/internal/form"
2121
"github.com/G-Node/gogs/internal/gitutil"
22-
"github.com/G-Node/gogs/internal/tool"
2322
)
2423

2524
const (
@@ -744,51 +743,3 @@ func CompareAndPullRequestPost(c *context.Context, f form.NewIssue) {
744743
log.Trace("Pull request created: %d/%d", repo.ID, pullIssue.ID)
745744
c.Redirect(c.Repo.RepoLink + "/pulls/" + com.ToStr(pullIssue.Index))
746745
}
747-
748-
func parseOwnerAndRepo(c *context.Context) (*db.User, *db.Repository) {
749-
owner, err := db.GetUserByName(c.Params(":username"))
750-
if err != nil {
751-
c.NotFoundOrError(err, "get user by name")
752-
return nil, nil
753-
}
754-
755-
repo, err := db.GetRepositoryByName(owner.ID, c.Params(":reponame"))
756-
if err != nil {
757-
c.NotFoundOrError(err, "get repository by name")
758-
return nil, nil
759-
}
760-
761-
return owner, repo
762-
}
763-
764-
func TriggerTask(c *context.Context) {
765-
pusherID := c.QueryInt64("pusher")
766-
branch := c.Query("branch")
767-
secret := c.Query("secret")
768-
if len(branch) == 0 || len(secret) == 0 || pusherID <= 0 {
769-
c.NotFound()
770-
log.Trace("TriggerTask: branch or secret is empty, or pusher ID is not valid")
771-
return
772-
}
773-
owner, repo := parseOwnerAndRepo(c)
774-
if c.Written() {
775-
return
776-
}
777-
if secret != tool.MD5(owner.Salt) {
778-
c.NotFound()
779-
log.Trace("TriggerTask [%s/%s]: invalid secret", owner.Name, repo.Name)
780-
return
781-
}
782-
783-
pusher, err := db.GetUserByID(pusherID)
784-
if err != nil {
785-
c.NotFoundOrError(err, "get user by ID")
786-
return
787-
}
788-
789-
log.Trace("TriggerTask '%s/%s' by '%s'", repo.Name, branch, pusher.Name)
790-
791-
go db.HookQueue.Add(repo.ID)
792-
go db.AddTestPullRequestTask(pusher, repo.ID, branch, true)
793-
c.Status(202)
794-
}

‎internal/route/repo/tasks.go

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2020 The Gogs Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package repo
6+
7+
import (
8+
"net/http"
9+
10+
"gopkg.in/macaron.v1"
11+
log "unknwon.dev/clog/v2"
12+
13+
"github.com/G-Node/gogs/internal/db"
14+
"github.com/G-Node/gogs/internal/tool"
15+
)
16+
17+
func TriggerTask(c *macaron.Context) {
18+
branch := c.Query("branch")
19+
pusherID := c.QueryInt64("pusher")
20+
secret := c.Query("secret")
21+
if branch == "" || pusherID <= 0 || secret == "" {
22+
c.Error(http.StatusBadRequest, "Incomplete branch, pusher or secret")
23+
return
24+
}
25+
26+
username := c.Params(":username")
27+
reponame := c.Params(":reponame")
28+
29+
owner, err := db.Users.GetByUsername(username)
30+
if err != nil {
31+
if db.IsErrUserNotExist(err) {
32+
c.Error(http.StatusBadRequest, "Owner does not exist")
33+
} else {
34+
c.Status(http.StatusInternalServerError)
35+
log.Error("Failed to get user [name: %s]: %v", username, err)
36+
}
37+
return
38+
}
39+
40+
// 🚨 SECURITY: No need to check existence of the repository if the client
41+
// can't even get the valid secret. Mostly likely not a legitimate request.
42+
if secret != tool.MD5(owner.Salt) {
43+
c.Error(http.StatusBadRequest, "Invalid secret")
44+
return
45+
}
46+
47+
repo, err := db.Repos.GetByName(owner.ID, reponame)
48+
if err != nil {
49+
if db.IsErrRepoNotExist(err) {
50+
c.Error(http.StatusBadRequest, "Repository does not exist")
51+
} else {
52+
c.Status(http.StatusInternalServerError)
53+
log.Error("Failed to get repository [owner_id: %d, name: %s]: %v", owner.ID, reponame, err)
54+
}
55+
return
56+
}
57+
58+
pusher, err := db.Users.GetByID(pusherID)
59+
if err != nil {
60+
if db.IsErrUserNotExist(err) {
61+
c.Error(http.StatusBadRequest, "Pusher does not exist")
62+
} else {
63+
c.Status(http.StatusInternalServerError)
64+
log.Error("Failed to get user [id: %d]: %v", pusherID, err)
65+
}
66+
return
67+
}
68+
69+
log.Trace("TriggerTask: %s/%s@%s by %q", owner.Name, repo.Name, branch, pusher.Name)
70+
71+
go db.HookQueue.Add(repo.ID)
72+
go db.AddTestPullRequestTask(pusher, repo.ID, branch, true)
73+
c.Status(http.StatusAccepted)
74+
}

0 commit comments

Comments
 (0)
Please sign in to comment.