Commit 30bbdad
Changed files (7)
cmd/authzd/main.go
@@ -1,27 +1,17 @@
package main
import (
- "context"
"log"
"net"
"github.com/xlgmokha/x/pkg/env"
"github.com/xlgmokha/x/pkg/x"
+ "gitlab.com/mokhax/spike/pkg/authz"
"gitlab.com/mokhax/spike/pkg/rpc"
- "google.golang.org/grpc"
)
-type CedarServer struct {
- rpc.UnimplementedAbilityServer
-}
-
-func (srv *CedarServer) Allowed(context.Context, *rpc.AllowRequest) (*rpc.AllowReply, error) {
- return &rpc.AllowReply{Result: true}, nil
-}
-
func main() {
- server := grpc.NewServer()
- rpc.RegisterAbilityServer(server, &CedarServer{})
+ server := rpc.New(authz.WithCedar())
log.Fatal(server.Serve(x.Must(net.Listen(
"tcp",
env.Fetch("BIND_ADDR", "localhost:50051"),
pkg/app/app.go
@@ -1,95 +1,13 @@
package app
import (
- "encoding/json"
- "fmt"
- "net"
- "net/http"
- "os"
-
- "github.com/casbin/casbin/v3"
- cedar "github.com/cedar-policy/cedar-go"
- "github.com/cedar-policy/cedar-go/types"
- "github.com/xlgmokha/x/pkg/x"
"gitlab.com/mokhax/spike/pkg/authz"
"gitlab.com/mokhax/spike/pkg/cfg"
- xlog "gitlab.com/mokhax/spike/pkg/log"
"gitlab.com/mokhax/spike/pkg/srv"
)
-func WithCasbin() authz.Authorizer {
- enforcer := x.Must(casbin.NewEnforcer("casbin.conf", "casbin.csv"))
-
- return authz.AuthorizerFunc(func(r *http.Request) bool {
- host, _, err := net.SplitHostPort(r.Host)
- if err != nil {
- xlog.WithFields(r, xlog.Fields{"error": err})
- return false
- }
-
- subject, found := authz.TokenFrom(r).Subject()
- if !found {
- subject = "*"
- }
- ok, err := enforcer.Enforce(subject, host, r.Method, r.URL.Path)
- if err != nil {
- xlog.WithFields(r, xlog.Fields{"error": err})
- return false
- }
-
- fmt.Printf("%v: %v -> %v %v%v\n", ok, subject, r.Method, host, r.URL.Path)
- xlog.WithFields(r, xlog.Fields{
- "ok": ok,
- "subject": subject,
- "action": r.Method,
- "domain": host,
- "object": r.URL.Path,
- })
- return ok
- })
-}
-
-func WithCedar() authz.Authorizer {
- var policy cedar.Policy
- x.Check(policy.UnmarshalCedar(x.Must(os.ReadFile("cedar.conf"))))
-
- policies := cedar.NewPolicySet()
- policies.Add("cedar.conf", &policy)
-
- var entities cedar.EntityMap
- if err := json.Unmarshal(x.Must(os.ReadFile("cedar.json")), &entities); err != nil {
- xlog.Logger.Error("Error", "error", err)
- return nil
- }
-
- return authz.AuthorizerFunc(func(r *http.Request) bool {
- host, _, err := net.SplitHostPort(r.Host)
- if err != nil {
- return false
- }
-
- subject, found := authz.TokenFrom(r).Subject()
- if !found {
- subject = "*"
- }
-
- req := cedar.Request{
- Principal: cedar.NewEntityUID("Subject", cedar.String(subject)),
- Action: cedar.NewEntityUID("Action", cedar.String(r.Method)),
- Resource: cedar.NewEntityUID("Path", cedar.String(r.URL.Path)),
- Context: cedar.NewRecord(cedar.RecordMap{
- "Host": cedar.String(host),
- }),
- }
-
- ok, diagnostic := policies.IsAuthorized(entities, req)
- fmt.Printf("%v: %v -> %v %v%v %v\n", ok, subject, r.Method, host, r.URL.Path, diagnostic.Reasons)
- return ok == types.Allow
- })
-}
-
func Start(bindAddr string) error {
- mux := authz.HTTP(WithCasbin(), Routes())
+ mux := authz.HTTP(authz.WithCasbin(), Routes())
return srv.Run(cfg.New(
bindAddr,
cfg.WithMux(mux),
pkg/app/routes.go
@@ -9,9 +9,10 @@ import (
func Routes() http.Handler {
mux := http.NewServeMux()
mux.Handle("/", prxy.New(map[string]string{
- "idp.example.com": "http://localhost:8282",
- "ui.example.com": "http://localhost:8283",
- "api.example.com": "http://localhost:8284",
+ "api.example.com": "http://localhost:8284",
+ "authzd.example.com": "http://localhost:50051",
+ "idp.example.com": "http://localhost:8282",
+ "ui.example.com": "http://localhost:8283",
}))
return mux
}
pkg/authz/casbin.go
@@ -0,0 +1,43 @@
+package authz
+
+import (
+ "fmt"
+ "net"
+ "net/http"
+
+ "github.com/casbin/casbin/v3"
+ "github.com/xlgmokha/x/pkg/x"
+ xlog "gitlab.com/mokhax/spike/pkg/log"
+)
+
+func WithCasbin() Authorizer {
+ enforcer := x.Must(casbin.NewEnforcer("casbin.conf", "casbin.csv"))
+
+ return AuthorizerFunc(func(r *http.Request) bool {
+ host, _, err := net.SplitHostPort(r.Host)
+ if err != nil {
+ xlog.WithFields(r, xlog.Fields{"error": err})
+ return false
+ }
+
+ subject, found := TokenFrom(r).Subject()
+ if !found {
+ subject = "*"
+ }
+ ok, err := enforcer.Enforce(subject, host, r.Method, r.URL.Path)
+ if err != nil {
+ xlog.WithFields(r, xlog.Fields{"error": err})
+ return false
+ }
+
+ fmt.Printf("%v: %v -> %v %v%v\n", ok, subject, r.Method, host, r.URL.Path)
+ xlog.WithFields(r, xlog.Fields{
+ "ok": ok,
+ "subject": subject,
+ "action": r.Method,
+ "domain": host,
+ "object": r.URL.Path,
+ })
+ return ok
+ })
+}
pkg/authz/cedar.go
@@ -0,0 +1,53 @@
+package authz
+
+import (
+ "encoding/json"
+ "fmt"
+ "net"
+ "net/http"
+ "os"
+
+ cedar "github.com/cedar-policy/cedar-go"
+ "github.com/cedar-policy/cedar-go/types"
+ "github.com/xlgmokha/x/pkg/x"
+ xlog "gitlab.com/mokhax/spike/pkg/log"
+)
+
+func WithCedar() Authorizer {
+ var policy cedar.Policy
+ x.Check(policy.UnmarshalCedar(x.Must(os.ReadFile("cedar.conf"))))
+
+ policies := cedar.NewPolicySet()
+ policies.Add("cedar.conf", &policy)
+
+ var entities cedar.EntityMap
+ if err := json.Unmarshal(x.Must(os.ReadFile("cedar.json")), &entities); err != nil {
+ xlog.Logger.Error("Error", "error", err)
+ return nil
+ }
+
+ return AuthorizerFunc(func(r *http.Request) bool {
+ host, _, err := net.SplitHostPort(r.Host)
+ if err != nil {
+ return false
+ }
+
+ subject, found := TokenFrom(r).Subject()
+ if !found {
+ subject = "*"
+ }
+
+ req := cedar.Request{
+ Principal: cedar.NewEntityUID("Subject", cedar.String(subject)),
+ Action: cedar.NewEntityUID("Action", cedar.String(r.Method)),
+ Resource: cedar.NewEntityUID("Path", cedar.String(r.URL.Path)),
+ Context: cedar.NewRecord(cedar.RecordMap{
+ "Host": cedar.String(host),
+ }),
+ }
+
+ ok, diagnostic := policies.IsAuthorized(entities, req)
+ fmt.Printf("%v: %v -> %v %v%v %v\n", ok, subject, r.Method, host, r.URL.Path, diagnostic.Reasons)
+ return ok == types.Allow
+ })
+}
pkg/rpc/ability_handler.go
@@ -0,0 +1,20 @@
+package rpc
+
+import (
+ context "context"
+ "net/http"
+
+ "github.com/xlgmokha/x/pkg/x"
+ "gitlab.com/mokhax/spike/pkg/authz"
+)
+
+type AbilityHandler struct {
+ authorizer authz.Authorizer
+ UnimplementedAbilityServer
+}
+
+func (h *AbilityHandler) Allowed(ctx context.Context, req *AllowRequest) (*AllowReply, error) {
+ // TODO:: Replace http.Request with authz.Request
+ request := x.Must(http.NewRequestWithContext(ctx, req.Permission, req.Resource, nil))
+ return &AllowReply{Result: h.authorizer.Authorize(request)}, nil
+}
pkg/rpc/server.go
@@ -0,0 +1,14 @@
+package rpc
+
+import (
+ "gitlab.com/mokhax/spike/pkg/authz"
+ grpc "google.golang.org/grpc"
+)
+
+func New(authorizer authz.Authorizer, options ...grpc.ServerOption) *grpc.Server {
+ server := grpc.NewServer(options...)
+ RegisterAbilityServer(server, &AbilityHandler{
+ authorizer: authorizer,
+ })
+ return server
+}