Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove orgId dependency in authz #132

Merged
merged 12 commits into from
Aug 9, 2022
2 changes: 0 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ linters:
- vet
- goimports
- thelper
- tparallel
- unconvert
- wastedassign
- revive
- unused
- gofmt
Expand Down
2 changes: 1 addition & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func serve(logger log.Logger, cfg *config.Shield) error {
}

// serving proxies
cbs, cps, err := serveProxies(ctx, logger, cfg.App.IdentityProxyHeader, cfg.App.UserIDHeader, cfg.Proxy, deps.ResourceService, deps.UserService)
cbs, cps, err := serveProxies(ctx, logger, cfg.App.IdentityProxyHeader, cfg.App.UserIDHeader, cfg.Proxy, deps.ResourceService, deps.UserService, deps.ProjectService)
if err != nil {
return err
}
Expand Down
11 changes: 7 additions & 4 deletions cmd/serve_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/odpf/salt/log"
"github.com/odpf/shield/core/project"
"github.com/odpf/shield/core/resource"
"github.com/odpf/shield/core/rule"
"github.com/odpf/shield/core/user"
Expand All @@ -23,16 +24,18 @@ import (
func serveProxies(
ctx context.Context,
logger log.Logger,
identityProxyHeaderKey, userIDHeaderKey string,
identityProxyHeaderKey,
userIDHeaderKey string,
cfg proxy.ServicesConfig,
resourceService *resource.Service,
userService *user.Service,
projectService *project.Service,
) ([]func() error, []func(ctx context.Context) error, error) {
var cleanUpBlobs []func() error
var cleanUpProxies []func(ctx context.Context) error

for _, svcConfig := range cfg.Services {
hookPipeline := buildHookPipeline(logger, identityProxyHeaderKey, resourceService)
hookPipeline := buildHookPipeline(logger, identityProxyHeaderKey, resourceService, projectService)

h2cProxy := proxy.NewH2c(
proxy.NewH2cRoundTripper(logger, hookPipeline),
Expand Down Expand Up @@ -67,9 +70,9 @@ func serveProxies(
return cleanUpBlobs, cleanUpProxies, nil
}

func buildHookPipeline(log log.Logger, identityProxyHeaderKey string, resourceService v1beta1.ResourceService) hook.Service {
func buildHookPipeline(log log.Logger, identityProxyHeaderKey string, resourceService v1beta1.ResourceService, projectService v1beta1.ProjectService) hook.Service {
rootHook := hook.New()
return authz_hook.New(log, rootHook, rootHook, identityProxyHeaderKey, resourceService)
return authz_hook.New(log, rootHook, rootHook, identityProxyHeaderKey, resourceService, projectService)
}

// buildPipeline builds middleware sequence
Expand Down
44 changes: 31 additions & 13 deletions internal/proxy/hook/authz/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (
"net/http"
"strings"

"github.com/mitchellh/mapstructure"

"github.com/odpf/salt/log"
"github.com/odpf/shield/core/namespace"
"github.com/odpf/shield/core/project"
"github.com/odpf/shield/core/resource"
"github.com/odpf/shield/core/user"
"github.com/odpf/shield/internal/proxy/hook"
"github.com/odpf/shield/internal/proxy/middleware"
"github.com/odpf/shield/pkg/body_extractor"

"github.com/mitchellh/mapstructure"
"github.com/odpf/salt/log"
)

type ResourceService interface {
Expand All @@ -30,18 +31,26 @@ type Authz struct {
// To skip all the next hooks and just respond back
escape hook.Service

projectService ProjectService

// TODO need to figure out what best to pass this
identityProxyHeaderKey string

resourceService ResourceService
}

func New(log log.Logger, next, escape hook.Service, identityProxyHeaderKey string, resourceService ResourceService) Authz {
type ProjectService interface {
Get(ctx context.Context, id string) (project.Project, error)
}

func New(log log.Logger, next, escape hook.Service, identityProxyHeaderKey string, resourceService ResourceService, projectService ProjectService) Authz {
return Authz{
log: log,
next: next,
escape: escape,
identityProxyHeaderKey: identityProxyHeaderKey,
resourceService: resourceService,
projectService: projectService,
}
}

Expand Down Expand Up @@ -177,7 +186,7 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
attributes[key] = value
}

resources, err := createResources(attributes)
resources, err := a.createResources(res.Request.Context(), attributes)
if err != nil {
a.log.Error(err.Error())
return a.escape.ServeHook(res, fmt.Errorf(err.Error()))
Expand All @@ -194,16 +203,25 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
return a.next.ServeHook(res, nil)
}

func createResources(permissionAttributes map[string]interface{}) ([]resource.Resource, error) {
func (a Authz) createResources(ctx context.Context, permissionAttributes map[string]interface{}) ([]resource.Resource, error) {
var resources []resource.Resource
projects, err := getAttributesValues(permissionAttributes["project"])
AkarshSatija marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
var organizationIds []string
var projectIds []string
for _, proj := range projects {
project, err := a.projectService.Get(ctx, proj)
if err != nil {
return nil, err
}

orgs, err := getAttributesValues(permissionAttributes["organization"])
if err != nil {
return nil, err
organizationId := project.Organization.ID
organizationIds = append(organizationIds, organizationId)

projectId := project.ID
projectIds = append(projectIds, projectId)
}

teams, err := getAttributesValues(permissionAttributes["team"])
Expand All @@ -226,12 +244,12 @@ func createResources(permissionAttributes map[string]interface{}) ([]resource.Re
return nil, err
}

if len(projects) < 1 || len(orgs) < 1 || len(resourceList) < 1 || (backendNamespace[0] == "") || (resourceType[0] == "") {
return nil, fmt.Errorf("namespace, resource type, projects, organizations, resource, and team are required")
if len(projects) < 1 || len(organizationIds) < 1 || len(resourceList) < 1 || (backendNamespace[0] == "") || (resourceType[0] == "") {
return nil, fmt.Errorf("namespace, resource type, projects, resource, and team are required")
}

for _, org := range orgs {
for _, project := range projects {
for _, org := range organizationIds {
for _, project := range projectIds {
for _, res := range resourceList {
if len(teams) > 0 {
for _, team := range teams {
Expand Down
Loading