Skip to content

Commit

Permalink
feat: remove middleware for abac
Browse files Browse the repository at this point in the history
[skip ci]
  • Loading branch information
adityathebe committed Sep 24, 2024
1 parent e0d8d70 commit 36f677a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 51 deletions.
40 changes: 2 additions & 38 deletions playbook/controllers.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package playbook

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"

Expand All @@ -30,41 +28,6 @@ func init() {
echoSrv.RegisterRoutes(RegisterRoutes)
}

const maxBodySize = 100 * 1024 // 100KB

func abacResourceGetter(c echo.Context, action string) (string, *rbac.ABACResource, error) {
ctx := c.Request().Context().(context.Context)

preview, err := io.ReadAll(io.LimitReader(c.Request().Body, maxBodySize))
if err != nil && err != io.EOF {
return "", nil, err
}

c.Request().Body = io.NopCloser(bytes.NewReader(preview))

var req RunParams
if err := json.Unmarshal(preview, &req); err != nil {
return "", nil, err
}

var resource rbac.ABACResource
playbook, err := query.FindPlaybook(ctx, req.ID.String())
if err != nil {
return "", nil, err
}
resource.Playbook = *playbook

if req.ComponentID != nil {
component, err := query.GetComponent(ctx, req.ComponentID.String())
if err != nil {
return "", nil, err
}
resource.Component = *component
}

return "playbook:run", &resource, nil
}

func RegisterRoutes(e *echo.Echo) {
logger.Infof("Registering /playbook routes")

Expand All @@ -79,7 +42,7 @@ func RegisterRoutes(e *echo.Echo) {
}, rbac.Authorization(rbac.ObjectMonitor, rbac.ActionRead))

runGroup := playbookGroup.Group("/run")
runGroup.POST("", HandlePlaybookRun, rbac.AuthorizationWithABAC(rbac.ObjectPlaybooks, rbac.ActionRun, abacResourceGetter))
runGroup.POST("", HandlePlaybookRun, rbac.Playbook(rbac.ActionRun))
runGroup.GET("/:id", HandleGetPlaybookRun, rbac.Playbook(rbac.ActionRead))
runGroup.POST("/approve/:run_id", HandlePlaybookRunApproval, rbac.Playbook(rbac.ActionApprove))
}
Expand Down Expand Up @@ -111,6 +74,7 @@ func HandlePlaybookRun(c echo.Context) error {

run, err := Run(ctx, playbook, req)
if err != nil {
// TODO: better error handling
return c.JSON(http.StatusInternalServerError, oops.Wrap(err))
}

Expand Down
14 changes: 14 additions & 0 deletions playbook/playbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import (
"github.com/flanksource/incident-commander/api"
v1 "github.com/flanksource/incident-commander/api/v1"
"github.com/flanksource/incident-commander/db"
"github.com/flanksource/incident-commander/playbook/actions"
"github.com/flanksource/incident-commander/playbook/runner"
"github.com/flanksource/incident-commander/rbac"
yamlutil "k8s.io/apimachinery/pkg/util/yaml"
)

Expand Down Expand Up @@ -130,6 +132,10 @@ func Run(ctx context.Context, playbook *models.Playbook, req RunParams) (*models
return nil, ctx.Oops().Wrap(err)
}

if !rbac.CheckABAC(ctx, ctx.User().ID.String(), abacResourceFromTemplateEnv(templateEnv), rbac.ActionPlaybookRun) {
return nil, ctx.Oops().Code("FORBIDDEN").Errorf("user does not have permission to run playbook")
}

if err := req.setDefaults(ctx, spec, templateEnv); err != nil {
return nil, ctx.Oops().Wrap(err)
}
Expand Down Expand Up @@ -160,6 +166,14 @@ func Run(ctx context.Context, playbook *models.Playbook, req RunParams) (*models
return &run, nil
}

func abacResourceFromTemplateEnv(templateEnv actions.TemplateEnv) *rbac.ABACResource {
return &rbac.ABACResource{
Playbook: templateEnv.Playbook,
Config: lo.FromPtr(templateEnv.Config),
Component: lo.FromPtr(templateEnv.Component),
}
}

func saveRunAsConfigChange(ctx context.Context, playbook *models.Playbook, run models.PlaybookRun, parameters any) error {
if run.ConfigID == nil {
return nil
Expand Down
18 changes: 10 additions & 8 deletions rbac/abac.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ import (
"github.com/labstack/echo/v4"
)

const (
ActionPlaybookRun = "playbook:run"
)

type ABACResource struct {
Playbook models.Playbook `json:"playbook"`
Config models.ConfigItem `json:"config"`
Connection models.Connection `json:"connection"`
Component models.Component `json:"component"`
Playbook models.Playbook `json:"playbook"`
Config models.ConfigItem `json:"config"`
Component models.Component `json:"component"`
}

func (r ABACResource) AsMap() map[string]any {
return map[string]any{
"component": r.Component.AsMap(),
"config": r.Config.AsMap(),
"connection": r.Connection.AsMap(),
"playbook": r.Playbook.AsMap(),
"component": r.Component.AsMap(),
"config": r.Config.AsMap(),
"playbook": r.Playbook.AsMap(),
}
}

Expand Down
16 changes: 11 additions & 5 deletions rbac/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,18 @@ func CheckEchoContext(c echo.Context, object, action string, getResource EchoABA
return false
}

allowed, err := enforcer.Enforce(user.ID.String(), abacReq.AsMap(), abacAction)
if err != nil {
return false
}
return allowed
return CheckABAC(ctx, user.ID.String(), abacReq, abacAction)
}

return true
}

func CheckABAC(ctx context.Context, subject string, object *ABACResource, action string) bool {
allowed, err := enforcer.Enforce(subject, object.AsMap(), action)
if err != nil {
ctx.Debugf("error checking abac for subject=%s action=%s", subject, action)
return false
}

return allowed
}

0 comments on commit 36f677a

Please sign in to comment.