mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-18 06:26:30 +00:00
116 lines
2.8 KiB
Go
116 lines
2.8 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"regexp"
|
|
|
|
"github.com/drone/drone/server/datastore"
|
|
"github.com/goji/context"
|
|
"github.com/zenazn/goji/web"
|
|
)
|
|
|
|
// SetRepo is a middleware function that retrieves
|
|
// the repository and stores in the context.
|
|
func SetRepo(c *web.C, h http.Handler) http.Handler {
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
ctx = context.FromC(*c)
|
|
host = c.URLParams["host"]
|
|
owner = c.URLParams["owner"]
|
|
name = c.URLParams["name"]
|
|
user = ToUser(c)
|
|
)
|
|
|
|
repo, err := datastore.GetRepoName(ctx, host, owner, name)
|
|
switch {
|
|
case err != nil && user == nil:
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
case err != nil && user != nil:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
role, _ := datastore.GetPerm(ctx, user, repo)
|
|
RepoToC(c, repo)
|
|
RoleToC(c, role)
|
|
h.ServeHTTP(w, r)
|
|
}
|
|
return http.HandlerFunc(fn)
|
|
}
|
|
|
|
// RequireRepoRead is a middleware function that verifies
|
|
// the user has read access to the repository.
|
|
func RequireRepoRead(c *web.C, h http.Handler) http.Handler {
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
role = ToRole(c)
|
|
user = ToUser(c)
|
|
)
|
|
switch {
|
|
case role == nil:
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
case user == nil && role.Read == false:
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
case user == nil && role.Read == false:
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
case user != nil && role.Read == false:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
h.ServeHTTP(w, r)
|
|
}
|
|
return http.HandlerFunc(fn)
|
|
}
|
|
|
|
// RequireRepoAdmin is a middleware function that verifies
|
|
// the user has admin access to the repository.
|
|
func RequireRepoAdmin(c *web.C, h http.Handler) http.Handler {
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
role = ToRole(c)
|
|
user = ToUser(c)
|
|
)
|
|
|
|
// Admin access is only rquired for POST, PUT, DELETE methods.
|
|
// If this is a GET request we can proceed immediately.
|
|
if r.Method == "GET" {
|
|
h.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
switch {
|
|
case role == nil:
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
case user == nil && role.Admin == false:
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
case user != nil && role.Read == false && role.Admin == false:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
case user != nil && role.Write == true && role.Admin == false:
|
|
if IsRebuild(r.URL.Path) {
|
|
h.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusForbidden)
|
|
return
|
|
case user != nil && role.Read == true && role.Admin == false:
|
|
w.WriteHeader(http.StatusForbidden)
|
|
return
|
|
default:
|
|
h.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
}
|
|
return http.HandlerFunc(fn)
|
|
}
|
|
|
|
func IsRebuild(path string) bool {
|
|
const pattern = `\/(.*)\/(.*)\/(.*)\/branches\/(.*)\/commits\/(.*)`
|
|
ok, _ := regexp.MatchString(pattern, path)
|
|
return ok
|
|
}
|