diff options
| author | Max Resnick <max@ofmax.li> | 2022-11-11 15:28:22 -0800 |
|---|---|---|
| committer | Max Resnick <max@ofmax.li> | 2022-11-11 15:28:22 -0800 |
| commit | 9317407369c72a43c5f2f0bdf8f006169669cdf8 (patch) | |
| tree | c6cfbf13f1391907d946b348d909456430b15296 /internal/authz/handler.go | |
| parent | 301b7abdf48f843975f02a675fa7995886629eb3 (diff) | |
| download | go-git-server-9317407369c72a43c5f2f0bdf8f006169669cdf8.tar.gz | |
re-org
Diffstat (limited to '')
| -rw-r--r-- | internal/authz/handler.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/authz/handler.go b/internal/authz/handler.go new file mode 100644 index 0000000..e47dd33 --- /dev/null +++ b/internal/authz/handler.go @@ -0,0 +1,62 @@ +package authz + +import ( + "context" + "encoding/base64" + "fmt" + "log" + "net/http" + + "github.com/casbin/casbin/v2" + "golang.org/x/crypto/bcrypt" +) + +// Authentication middleware to enforce authentication of all requests. +func Authentication(authMap TokenMap, next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + u, p, ok := req.BasicAuth() + if !ok { + rw.Header().Set("WWW-Authenticate", `Basic realm="git"`) + http.Error(rw, "Authentication Required", 401) + return + } + urn := fmt.Sprintf("uid:%s", u) + hash, ok := authMap[urn] + if !ok { + http.Error(rw, "Bad Request", 400) + return + } + token, err := base64.URLEncoding.DecodeString(p) + if err != nil { + http.Error(rw, "Bad Request", 400) + return + } + if err := bcrypt.CompareHashAndPassword([]byte(hash), token); err != nil { + http.Error(rw, "Bad Request", 400) + return + } + ctx := context.WithValue(req.Context(), "urn", urn) + next.ServeHTTP(rw, req.WithContext(ctx)) + }) +} + +// Authorization middleware to enforce authoirzation of all requests. +func Authorization(enf *casbin.Enforcer, next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + ctx := req.Context() + urn := ctx.Value("urn") + repo := req.URL.Path + action := req.Method + ok, err := enf.Enforce(urn, repo, action) + if err != nil { + log.Printf("error running enforce %s", err) + http.Error(rw, "Bad Request", http.StatusBadRequest) + } + if !ok { + log.Printf("Access denied") + http.Error(rw, "Access denied", http.StatusUnauthorized) + } + log.Printf("Method %s Url %s", action, repo) + next.ServeHTTP(rw, req.WithContext(ctx)) + }) +} |