mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-27 12:21:03 +00:00
210 lines
5.5 KiB
Go
210 lines
5.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/drone/drone/server/database"
|
|
"github.com/drone/drone/server/session"
|
|
"github.com/drone/drone/shared/httputil"
|
|
"github.com/drone/drone/shared/model"
|
|
"github.com/gorilla/pat"
|
|
)
|
|
|
|
type CommitHandler struct {
|
|
users database.UserManager
|
|
perms database.PermManager
|
|
repos database.RepoManager
|
|
commits database.CommitManager
|
|
sess session.Session
|
|
queue chan *model.Request
|
|
}
|
|
|
|
func NewCommitHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, queue chan *model.Request) *CommitHandler {
|
|
return &CommitHandler{users, perms, repos, commits, sess, queue}
|
|
}
|
|
|
|
// GetFeed gets recent commits for the repository and branch
|
|
// GET /v1/repos/{host}/{owner}/{name}/branches/{branch}/commits
|
|
func (h *CommitHandler) GetFeed(w http.ResponseWriter, r *http.Request) error {
|
|
var host, owner, name = parseRepo(r)
|
|
var branch = r.FormValue(":branch")
|
|
|
|
// get the user form the session.
|
|
user := h.sess.User(r)
|
|
|
|
// get the repository from the database.
|
|
repo, err := h.repos.FindName(host, owner, name)
|
|
switch {
|
|
case err != nil && user == nil:
|
|
return notAuthorized{}
|
|
case err != nil && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
// user must have read access to the repository.
|
|
ok, _ := h.perms.Read(user, repo)
|
|
switch {
|
|
case ok == false && user == nil:
|
|
return notAuthorized{}
|
|
case ok == false && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
commits, err := h.commits.ListBranch(repo.ID, branch)
|
|
if err != nil {
|
|
return notFound{err}
|
|
}
|
|
|
|
return json.NewEncoder(w).Encode(commits)
|
|
}
|
|
|
|
// GetCommit gets the commit for the repository, branch and sha.
|
|
// GET /v1/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit}
|
|
func (h *CommitHandler) GetCommit(w http.ResponseWriter, r *http.Request) error {
|
|
var host, owner, name = parseRepo(r)
|
|
var branch = r.FormValue(":branch")
|
|
var sha = r.FormValue(":commit")
|
|
|
|
// get the user form the session.
|
|
user := h.sess.User(r)
|
|
|
|
// get the repository from the database.
|
|
repo, err := h.repos.FindName(host, owner, name)
|
|
switch {
|
|
case err != nil && user == nil:
|
|
return notAuthorized{}
|
|
case err != nil && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
// user must have read access to the repository.
|
|
ok, _ := h.perms.Read(user, repo)
|
|
switch {
|
|
case ok == false && user == nil:
|
|
return notAuthorized{}
|
|
case ok == false && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
commit, err := h.commits.FindSha(repo.ID, branch, sha)
|
|
if err != nil {
|
|
return notFound{err}
|
|
}
|
|
|
|
return json.NewEncoder(w).Encode(commit)
|
|
}
|
|
|
|
// GetCommitOutput gets the commit's stdout.
|
|
// GET /v1/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit}/console
|
|
func (h *CommitHandler) GetCommitOutput(w http.ResponseWriter, r *http.Request) error {
|
|
var host, owner, name = parseRepo(r)
|
|
var branch = r.FormValue(":branch")
|
|
var sha = r.FormValue(":commit")
|
|
|
|
// get the user form the session.
|
|
user := h.sess.User(r)
|
|
|
|
// get the repository from the database.
|
|
repo, err := h.repos.FindName(host, owner, name)
|
|
switch {
|
|
case err != nil && user == nil:
|
|
return notAuthorized{}
|
|
case err != nil && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
// user must have read access to the repository.
|
|
ok, _ := h.perms.Read(user, repo)
|
|
switch {
|
|
case ok == false && user == nil:
|
|
return notAuthorized{}
|
|
case ok == false && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
commit, err := h.commits.FindSha(repo.ID, branch, sha)
|
|
if err != nil {
|
|
return notFound{err}
|
|
}
|
|
|
|
output, err := h.commits.FindOutput(commit.ID)
|
|
if err != nil {
|
|
return notFound{err}
|
|
}
|
|
|
|
w.Write(output)
|
|
return nil
|
|
}
|
|
|
|
// PostCommit gets the commit for the repository and schedules to re-build.
|
|
// GET /v1/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit}
|
|
func (h *CommitHandler) PostCommit(w http.ResponseWriter, r *http.Request) error {
|
|
var host, owner, name = parseRepo(r)
|
|
var branch = r.FormValue(":branch")
|
|
var sha = r.FormValue(":commit")
|
|
|
|
// get the user form the session.
|
|
user := h.sess.User(r)
|
|
if user == nil {
|
|
return notAuthorized{}
|
|
}
|
|
|
|
// get the repo from the database
|
|
repo, err := h.repos.FindName(host, owner, name)
|
|
switch {
|
|
case err != nil && user == nil:
|
|
return notAuthorized{}
|
|
case err != nil && user != nil:
|
|
return notFound{}
|
|
}
|
|
|
|
// user must have admin access to the repository.
|
|
if ok, _ := h.perms.Admin(user, repo); !ok {
|
|
return notFound{err}
|
|
}
|
|
|
|
c, err := h.commits.FindSha(repo.ID, branch, sha)
|
|
if err != nil {
|
|
return notFound{err}
|
|
}
|
|
|
|
// we can't start an already started build
|
|
if c.Status == model.StatusStarted || c.Status == model.StatusEnqueue {
|
|
return badRequest{}
|
|
}
|
|
|
|
c.Status = model.StatusEnqueue
|
|
c.Started = 0
|
|
c.Finished = 0
|
|
c.Duration = 0
|
|
if err := h.commits.Update(c); err != nil {
|
|
return internalServerError{err}
|
|
}
|
|
|
|
repoOwner, err := h.users.Find(repo.UserID)
|
|
if err != nil {
|
|
return badRequest{err}
|
|
}
|
|
|
|
// drop the items on the queue
|
|
// drop the items on the queue
|
|
go func() {
|
|
h.queue <- &model.Request{
|
|
User: repoOwner,
|
|
Host: httputil.GetURL(r),
|
|
Repo: repo,
|
|
Commit: c,
|
|
}
|
|
}()
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
return nil
|
|
}
|
|
|
|
func (h *CommitHandler) Register(r *pat.Router) {
|
|
r.Get("/v1/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit}/console", errorHandler(h.GetCommitOutput))
|
|
r.Get("/v1/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit}", errorHandler(h.GetCommit))
|
|
r.Post("/v1/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit}", errorHandler(h.PostCommit)).Queries("action", "rebuild")
|
|
r.Get("/v1/repos/{host}/{owner}/{name}/branches/{branch}/commits", errorHandler(h.GetFeed))
|
|
}
|