generated from ZEISS/template-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6b9c065
commit fccc156
Showing
5 changed files
with
237 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "Attach to Air", | ||
"type": "go", | ||
"mode": "remote", | ||
"request": "attach", | ||
"host": "127.0.0.1", | ||
"apiVersion": 2, | ||
"trace": "verbose", | ||
"port": 2345 | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"editor.codeActionsOnSave": { | ||
"source.fixAll": "explicit" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"version": "2.0.0", | ||
"options": { | ||
"env": {} | ||
}, | ||
"tasks": [ | ||
{ | ||
"label": "Start Web Server", | ||
"type": "shell", | ||
"command": "air", | ||
"options": { | ||
"cwd": "${workspaceFolder}" | ||
}, | ||
"args": [ | ||
"-c", | ||
"${workspaceFolder}/cmd/web/.air.toml" | ||
], | ||
"problemMatcher": [] | ||
}, | ||
{ | ||
"label": "Start API Server", | ||
"type": "shell", | ||
"command": "air", | ||
"options": { | ||
"cwd": "${workspaceFolder}" | ||
}, | ||
"args": [ | ||
"-c", | ||
"${workspaceFolder}/cmd/api/.air.toml" | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package oas | ||
|
||
import ( | ||
"context" | ||
|
||
openapi "github.com/zeiss/knox/pkg/apis" | ||
|
||
"github.com/gofiber/fiber/v2" | ||
"github.com/openfga/go-sdk/client" | ||
) | ||
|
||
// User is the subject. | ||
type User string | ||
|
||
// String returns the string representation of the user. | ||
func (u User) String() string { | ||
return string(u) | ||
} | ||
|
||
// Relation is the object. | ||
type Relation string | ||
|
||
// String returns the string representation of the relation. | ||
func (r Relation) String() string { | ||
return string(r) | ||
} | ||
|
||
// Object is the action. | ||
type Object string | ||
|
||
// String returns the string representation of the object. | ||
func (o Object) String() string { | ||
return string(o) | ||
} | ||
|
||
const ( | ||
NoopUser User = "" | ||
NoopRelation Relation = "" | ||
NoopObject Object = "" | ||
) | ||
|
||
// Checker is the interface for the FGA authz checker. | ||
type Checker interface { | ||
Allowed(ctx context.Context, user User, relation Relation, object Object) (bool, error) | ||
} | ||
|
||
var _ Checker = (*fgaImpl)(nil) | ||
|
||
type fgaImpl struct { | ||
client *client.OpenFgaClient | ||
} | ||
|
||
// NewChecker returns a new FGA authz checker. | ||
func NewChecker(c *client.OpenFgaClient) *fgaImpl { | ||
return &fgaImpl{c} | ||
} | ||
|
||
// Allowed returns true if user has the relation with the object. | ||
func (f *fgaImpl) Allowed(ctx context.Context, user User, relation Relation, object Object) (bool, error) { | ||
body := client.ClientCheckRequest{ | ||
User: user.String(), | ||
Relation: relation.String(), | ||
Object: object.String(), | ||
} | ||
|
||
allowed, err := f.client.Check(ctx).Body(body).Execute() | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
return allowed.GetAllowed(), nil | ||
} | ||
|
||
type noopImpl struct{} | ||
|
||
// NewNoop returns a new Noop authz checker. | ||
func NewNoop() *noopImpl { | ||
return &noopImpl{} | ||
} | ||
|
||
// Allowed returns true if user has the relation with the object. | ||
func (n *noopImpl) Allowed(ctx context.Context, user User, relation Relation, object Object) (bool, error) { | ||
return false, nil | ||
} | ||
|
||
// NoopResolvers is a map of Noop resolvers. | ||
func NoopResolvers() map[string]AuthzResolverFunc { | ||
return map[string]AuthzResolverFunc{} | ||
} | ||
|
||
// Config ... | ||
type Config struct { | ||
// Next defines a function to skip the current middleware. | ||
Next func(c *fiber.Ctx) bool | ||
// Checker defines a function to check the authorization. | ||
Checker Checker | ||
// Resolvers defines the resolvers for a specific operation. | ||
Resolvers map[string]AuthzResolverFunc | ||
// DefaultError defines the default error. | ||
DefaultError error | ||
} | ||
|
||
// DefaultConfig contains the default configuration. | ||
var DefaultConfig = Config{ | ||
Checker: NewNoop(), | ||
Resolvers: NoopResolvers(), | ||
DefaultError: fiber.ErrForbidden, | ||
} | ||
|
||
// NoopResolver is a resolver that always returns Noop values. | ||
func NoopResolver() AuthzResolverFunc { | ||
return func(ctx *fiber.Ctx) (User, Relation, Object, error) { | ||
return NoopUser, NoopRelation, NoopObject, nil | ||
} | ||
} | ||
|
||
// AuthzResolverFunc is a function to resolve the authz values. | ||
type AuthzResolverFunc func(ctx *fiber.Ctx) (User, Relation, Object, error) | ||
|
||
// NewAuthz returns a new authz middleware. | ||
func NewAuthz(config ...Config) openapi.StrictMiddlewareFunc { | ||
cfg := configDefault(config...) | ||
|
||
return func(f openapi.StrictHandlerFunc, operationID string) openapi.StrictHandlerFunc { | ||
return func(ctx *fiber.Ctx, args interface{}) (interface{}, error) { | ||
if cfg.Next != nil && cfg.Next(ctx) { | ||
return f(ctx, args) | ||
} | ||
|
||
resolver, ok := cfg.Resolvers[operationID] | ||
if !ok { | ||
return nil, cfg.DefaultError | ||
} | ||
|
||
user, relation, object, err := resolver(ctx) | ||
if err != nil { | ||
return nil, cfg.DefaultError | ||
} | ||
|
||
allowed, err := cfg.Checker.Allowed(ctx.Context(), user, relation, object) | ||
if err != nil { | ||
return nil, cfg.DefaultError | ||
} | ||
|
||
if !allowed { | ||
return nil, cfg.DefaultError | ||
} | ||
|
||
return f(ctx, args) | ||
} | ||
} | ||
} | ||
|
||
// Helper function to set default values | ||
func configDefault(config ...Config) Config { | ||
if len(config) < 1 { | ||
return DefaultConfig | ||
} | ||
|
||
// Override default config | ||
cfg := config[0] | ||
|
||
if cfg.Checker == nil { | ||
cfg.Checker = DefaultConfig.Checker | ||
} | ||
|
||
if cfg.DefaultError == nil { | ||
cfg.DefaultError = DefaultConfig.DefaultError | ||
} | ||
|
||
return cfg | ||
} |