summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2022-05-17 22:37:57 -0600
committermo khan <mo@mokhan.ca>2022-05-17 22:37:57 -0600
commit8a38385ec7d1ad38fd7c21c5c68065eba999d1b3 (patch)
treec967352c752ef8242c9ec1bada6205997b387583
parent06d5a14da989ce326a7c1e1d39457bc2be0fa882 (diff)
allow public access to wildcard routes
-rw-r--r--cmd/api/main.go82
-rw-r--r--pkg/api/model.conf11
-rw-r--r--pkg/api/policy.conf11
-rw-r--r--pkg/api/policy.csv5
4 files changed, 38 insertions, 71 deletions
diff --git a/cmd/api/main.go b/cmd/api/main.go
index 1ca5e28..0359dc9 100644
--- a/cmd/api/main.go
+++ b/cmd/api/main.go
@@ -31,34 +31,38 @@ func ValidAudience(audiences []string) bool {
return false
}
+func Enforce(e *casbin.Enforcer, subject, resource, action string) bool {
+ ok := x.Must(e.Enforce(subject, resource, action))
+ fmt.Printf("%v: %v %v %v\n", ok, subject, resource, action)
+ return ok
+}
+
func Authorizer(e *casbin.Enforcer, keySet jwk.Set) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var subject string
raw := jwtauth.TokenFromHeader(r)
if raw == "" {
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, "missing token")))
- return
- }
-
- token, err := jwt.ParseString(raw, jwt.WithKeySet(keySet))
- if err != nil {
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, err)))
- return
- }
-
- if !ValidAudience(token.Audience()) {
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, "invalid audience")))
- return
+ subject = ""
+ } else {
+ token, err := jwt.ParseString(raw, jwt.WithKeySet(keySet))
+ if err != nil {
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, err)))
+ return
+ }
+
+ if !ValidAudience(token.Audience()) {
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, "invalid audience")))
+ return
+ }
+ subject = token.Subject()
}
- if ok, _ := e.Enforce(token.Subject(), r.URL.Path, r.Method); ok {
- fmt.Printf("pass: %v %v %v\n", token.Subject(), r.URL.Path, r.Method)
+ if Enforce(e, subject, r.URL.Path, r.Method) {
next.ServeHTTP(w, r)
} else {
- fmt.Printf("fail: %v %v %v\n", token.Subject(), r.URL.Path, r.Method)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, http.StatusText(http.StatusUnauthorized))))
}
@@ -66,44 +70,6 @@ func Authorizer(e *casbin.Enforcer, keySet jwk.Set) func(next http.Handler) http
}
}
-// func BuildJwtMiddleware(issuerURL *url.URL) *jwtmiddleware.JWTMiddleware {
-// provider := jwks.NewCachingProvider(issuerURL, 5*time.Minute)
-// jwtValidator := x.Must(
-// validator.New(
-// provider.KeyFunc,
-// validator.RS256,
-// issuerURL.String(),
-// []string{os.Getenv("AUTH0_AUDIENCE")},
-// validator.WithAllowedClockSkew(time.Minute),
-// validator.WithCustomClaims(func() validator.CustomClaims {
-// return &x.CustomClaims{}
-// }),
-// ),
-// )
-
-// errHandler := func(w http.ResponseWriter, r *http.Request, err error) {
-// w.Header().Set("Content-Type", "application/json")
-// w.WriteHeader(http.StatusUnauthorized)
-// w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, err)))
-// }
-// return jwtmiddleware.New(
-// jwtValidator.ValidateToken,
-// jwtmiddleware.WithCredentialsOptional(true),
-// jwtmiddleware.WithErrorHandler(errHandler),
-// jwtmiddleware.WithValidateOnOptions(false),
-// )
-// }
-
-// func Authorize(middleware *jwtmiddleware.JWTMiddleware, requiredPermissions ...x.Permission) func(http.Handler) http.Handler {
-// return func(next http.Handler) http.Handler {
-// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-// middleware.
-// CheckJWT(next).
-// ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "required_permissions", requiredPermissions)))
-// })
-// }
-// }
-
func readFixture(path string) []byte {
finalPath := filepath.Join(x.Must(os.Getwd()), "pkg/api/fixtures", path)
return x.Must(ioutil.ReadFile(finalPath))
@@ -128,7 +94,7 @@ func main() {
router.Use(middleware.AllowContentType("application/json"))
router.Use(middleware.Heartbeat("/health"))
router.Use(cors.AllowAll().Handler)
- router.Use(Authorizer(x.Must(casbin.NewEnforcer("pkg/api/model.conf", "pkg/api/policy.csv")), keySet))
+ router.Use(Authorizer(x.Must(casbin.NewEnforcer("pkg/api/policy.conf", "pkg/api/policy.csv")), keySet))
// issuer := x.Must(url.Parse("https://" + os.Getenv("AUTH0_DOMAIN") + "/"))
// token := BuildJwtMiddleware(issuer)
diff --git a/pkg/api/model.conf b/pkg/api/model.conf
deleted file mode 100644
index cee2566..0000000
--- a/pkg/api/model.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-[request_definition]
-r = sub, obj, act
-
-[policy_definition]
-p = sub, obj, act
-
-[policy_effect]
-e = some(where (p.eft == allow))
-
-[matchers]
-m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
diff --git a/pkg/api/policy.conf b/pkg/api/policy.conf
new file mode 100644
index 0000000..ee06c27
--- /dev/null
+++ b/pkg/api/policy.conf
@@ -0,0 +1,11 @@
+[request_definition]
+r = subject, resource, action
+
+[policy_definition]
+p = subject, resource, action
+
+[policy_effect]
+e = some(where (p.eft == allow))
+
+[matchers]
+m = (p.subject == "*" || r.subject == p.subject) && r.resource == p.resource && r.action == p.action
diff --git a/pkg/api/policy.csv b/pkg/api/policy.csv
index 888c8cb..fa2451a 100644
--- a/pkg/api/policy.csv
+++ b/pkg/api/policy.csv
@@ -1,3 +1,4 @@
-p, alice, data1, read
-p, bob, data2, write
+p, *, /api/public, GET
+p, auth0|alice, /api/atlas/QwfsJDutXwPD, read
p, auth0|627b10e1019dd10068e03db4, /api/users, GET
+p, auth0|bob, /api/atlas/QwfsJDutXwPD/investigations/FJ9mVozy2TjT, POST