mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-11-04 01:22:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			193 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package handler
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"log"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
 | 
						|
	"github.com/drone/drone/pkg/database"
 | 
						|
	. "github.com/drone/drone/pkg/model"
 | 
						|
)
 | 
						|
 | 
						|
// ErrorHandler wraps the default http.HandleFunc to handle an
 | 
						|
// error as the return value.
 | 
						|
type ErrorHandler func(w http.ResponseWriter, r *http.Request) error
 | 
						|
 | 
						|
func (h ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
	if err := h(w, r); err != nil {
 | 
						|
		log.Print(err)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// UserHandler wraps the default http.HandlerFunc to include
 | 
						|
// the currently authenticated User in the method signature,
 | 
						|
// in addition to handling an error as the return value.
 | 
						|
type UserHandler func(w http.ResponseWriter, r *http.Request, user *User) error
 | 
						|
 | 
						|
func (h UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
	user, err := readUser(r)
 | 
						|
	if err != nil {
 | 
						|
		redirectLogin(w, r)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if err = h(w, r, user); err != nil {
 | 
						|
		log.Print(err)
 | 
						|
		RenderError(w, err, http.StatusBadRequest)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// AdminHandler wraps the default http.HandlerFunc to include
 | 
						|
// the currently authenticated User in the method signature,
 | 
						|
// in addition to handling an error as the return value. It also
 | 
						|
// verifies the user has Administrative priveleges.
 | 
						|
type AdminHandler func(w http.ResponseWriter, r *http.Request, user *User) error
 | 
						|
 | 
						|
func (h AdminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
	user, err := readUser(r)
 | 
						|
	if err != nil {
 | 
						|
		redirectLogin(w, r)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// User MUST have administrative priveleges in order
 | 
						|
	// to execute the handler.
 | 
						|
	if user.Admin == false {
 | 
						|
		RenderNotFound(w)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if err = h(w, r, user); err != nil {
 | 
						|
		log.Print(err)
 | 
						|
		RenderError(w, err, http.StatusBadRequest)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RepoHandler wraps the default http.HandlerFunc to include
 | 
						|
// the currently authenticated User and requested Repository
 | 
						|
// in the method signature, in addition to handling an error
 | 
						|
// as the return value.
 | 
						|
type RepoHandler func(w http.ResponseWriter, r *http.Request, user *User, repo *Repo) error
 | 
						|
 | 
						|
func (h RepoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
	user, err := readUser(r)
 | 
						|
	if err != nil {
 | 
						|
		redirectLogin(w, r)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// repository name from the URL parameters
 | 
						|
	hostParam := r.FormValue(":host")
 | 
						|
	userParam := r.FormValue(":owner")
 | 
						|
	nameParam := r.FormValue(":name")
 | 
						|
	repoName := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)
 | 
						|
 | 
						|
	repo, err := database.GetRepoSlug(repoName)
 | 
						|
	if err != nil {
 | 
						|
		RenderNotFound(w)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// The User must own the repository OR be a member
 | 
						|
	// of the Team that owns the repository.
 | 
						|
	if user.ID != repo.UserID {
 | 
						|
		if member, _ := database.IsMember(user.ID, repo.TeamID); !member {
 | 
						|
			RenderNotFound(w)
 | 
						|
			return
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if err = h(w, r, user, repo); err != nil {
 | 
						|
		log.Print(err)
 | 
						|
		RenderError(w, err, http.StatusBadRequest)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RepoHandler wraps the default http.HandlerFunc to include
 | 
						|
// the currently authenticated User and requested Repository
 | 
						|
// in the method signature, in addition to handling an error
 | 
						|
// as the return value.
 | 
						|
type RepoAdminHandler func(w http.ResponseWriter, r *http.Request, user *User, repo *Repo) error
 | 
						|
 | 
						|
func (h RepoAdminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
	user, err := readUser(r)
 | 
						|
	if err != nil {
 | 
						|
		redirectLogin(w, r)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// repository name from the URL parameters
 | 
						|
	hostParam := r.FormValue(":host")
 | 
						|
	userParam := r.FormValue(":owner")
 | 
						|
	nameParam := r.FormValue(":name")
 | 
						|
	repoName := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)
 | 
						|
 | 
						|
	repo, err := database.GetRepoSlug(repoName)
 | 
						|
	if err != nil {
 | 
						|
		RenderNotFound(w)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// The User must own the repository OR be a member
 | 
						|
	// of the Team that owns the repository.
 | 
						|
	if user.ID != repo.UserID {
 | 
						|
		if admin, _ := database.IsMemberAdmin(user.ID, repo.TeamID); admin == false {
 | 
						|
			RenderNotFound(w)
 | 
						|
			return
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if err = h(w, r, user, repo); err != nil {
 | 
						|
		log.Print(err)
 | 
						|
		RenderError(w, err, http.StatusBadRequest)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// helper function that reads the currently authenticated
 | 
						|
// user from the given http.Request.
 | 
						|
func readUser(r *http.Request) (*User, error) {
 | 
						|
	username := GetCookie(r, "_sess")
 | 
						|
	if len(username) == 0 {
 | 
						|
		return nil, fmt.Errorf("No user session")
 | 
						|
	}
 | 
						|
 | 
						|
	// get the user from the database
 | 
						|
	user, err := database.GetUserEmail(username)
 | 
						|
	if err != nil || user == nil || user.ID == 0 {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	return user, nil
 | 
						|
}
 | 
						|
 | 
						|
// helper function that retrieves the repository based
 | 
						|
// on the URL parameters
 | 
						|
func readRepo(r *http.Request) (*Repo, error) {
 | 
						|
	// get the repo data from the URL parameters
 | 
						|
	hostParam := r.FormValue(":host")
 | 
						|
	userParam := r.FormValue(":owner")
 | 
						|
	nameParam := r.FormValue(":slug")
 | 
						|
	repoSlug := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)
 | 
						|
 | 
						|
	// get the repo from the database
 | 
						|
	return database.GetRepoSlug(repoSlug)
 | 
						|
}
 | 
						|
 | 
						|
// helper function that sends the user to the login page.
 | 
						|
func redirectLogin(w http.ResponseWriter, r *http.Request) {
 | 
						|
	v := url.Values{}
 | 
						|
	v.Add("return_to", r.URL.String())
 | 
						|
	http.Redirect(w, r, "/login?"+v.Encode(), http.StatusSeeOther)
 | 
						|
}
 | 
						|
 | 
						|
func renderNotFound(w http.ResponseWriter, r *http.Request) {
 | 
						|
	w.WriteHeader(http.StatusNotFound)
 | 
						|
	RenderTemplate(w, "404.amber", nil)
 | 
						|
}
 | 
						|
 | 
						|
func renderBadRequest(w http.ResponseWriter, r *http.Request) {
 | 
						|
	w.WriteHeader(http.StatusBadRequest)
 | 
						|
	RenderTemplate(w, "500.amber", nil)
 | 
						|
}
 |