aboutsummaryrefslogtreecommitdiff
path: root/internal/authz/middleware.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/authz/middleware.go')
-rw-r--r--internal/authz/middleware.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/internal/authz/middleware.go b/internal/authz/middleware.go
new file mode 100644
index 0000000..1dd06e3
--- /dev/null
+++ b/internal/authz/middleware.go
@@ -0,0 +1,61 @@
+package authz
+
+import (
+ "context"
+ "encoding/base64"
+ "fmt"
+ "log"
+ "net/http"
+
+ "github.com/casbin/casbin/v2"
+ "golang.org/x/crypto/bcrypt"
+)
+
+func Authentication(authMap TokenMap, next http.HandlerFunc) 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", http.StatusUnauthorized)
+ return
+ }
+ urn := fmt.Sprintf("uid:%s", u)
+ hash, ok := authMap[urn]
+ if !ok {
+ http.Error(rw, "Bad Request", http.StatusForbidden)
+ return
+ }
+ token, err := base64.URLEncoding.DecodeString(p)
+ if err != nil {
+ http.Error(rw, "Bad Request", http.StatusBadRequest)
+ return
+ }
+ if err := bcrypt.CompareHashAndPassword([]byte(hash), token); err != nil {
+ http.Error(rw, "Bad Request", http.StatusForbidden)
+ 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.HandlerFunc) 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.StatusForbidden)
+ }
+ log.Printf("Method %s Url %s", action, repo)
+ next.ServeHTTP(rw, req.WithContext(ctx))
+ })
+}