1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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))
})
}
|