Skip to content

Commit

Permalink
fix: move to attribute package
Browse files Browse the repository at this point in the history
  • Loading branch information
FemiNoviaLina committed Jul 3, 2024
1 parent 6303132 commit 6d0e1a3
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package middleware
package attribute

import (
"strings"

"github.com/valyala/fasttemplate"
)

const (
AttributeTypeQuery AttributeType = "query"
AttributeTypeHeader AttributeType = "header"
AttributeTypeJSONPayload AttributeType = "json_payload"
AttributeTypeGRPCPayload AttributeType = "grpc_payload"
AttributeTypePathParam AttributeType = "path_param"
AttributeTypeQuery AttributeType = "query"
AttributeTypeHeader AttributeType = "header"
AttributeTypeConstant AttributeType = "constant"
AttributeTypeComposite AttributeType = "composite"

SourceRequest AttributeType = "request"
SourceResponse AttributeType = "response"
)

type AttributeType string
Expand All @@ -18,4 +27,13 @@ type Attribute struct {
Path string `yaml:"path" mapstructure:"path"`
Params []string `yaml:"params" mapstructure:"params"`
Value string `yaml:"value" mapstructure:"value"`
Source string `yaml:"source" mapstructure:"source"`
}

func ComposeAttribute(attribute string, attrs map[string]interface{}) string {
if strings.Contains(attribute, "{") {
template := fasttemplate.New(attribute, "{", "}")
return template.ExecuteString(attrs)
}
return attribute
}
15 changes: 0 additions & 15 deletions internal/proxy/helper.go

This file was deleted.

24 changes: 12 additions & 12 deletions internal/proxy/hook/authz/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/goto/shield/core/relation"
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/proxy"
proxyattr "github.com/goto/shield/internal/proxy/attribute"
"github.com/goto/shield/internal/proxy/hook"
"github.com/goto/shield/internal/proxy/middleware"
"github.com/goto/shield/pkg/body_extractor"
Expand Down Expand Up @@ -93,9 +93,9 @@ type Relation struct {
}

type Config struct {
Action string `yaml:"action" mapstructure:"action"`
Attributes map[string]hook.Attribute `yaml:"attributes" mapstructure:"attributes"`
Relations []Relation `yaml:"relations" mapstructure:"relations"`
Action string `yaml:"action" mapstructure:"action"`
Attributes map[string]proxyattr.Attribute `yaml:"attributes" mapstructure:"attributes"`
Relations []Relation `yaml:"relations" mapstructure:"relations"`
}

func (a Authz) Info() hook.Info {
Expand Down Expand Up @@ -152,17 +152,17 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
for id, attr := range config.Attributes {
bdy, _ := middleware.ExtractRequestBody(res.Request)
bodySource := &res.Body
if attr.Source == string(hook.SourceRequest) {
if attr.Source == string(proxyattr.SourceRequest) {
bodySource = &bdy
}

headerSource := &res.Header
if attr.Source == string(hook.SourceRequest) {
if attr.Source == string(proxyattr.SourceRequest) {
headerSource = &res.Request.Header
}

switch attr.Type {
case hook.AttributeTypeGRPCPayload:
case proxyattr.AttributeTypeGRPCPayload:
if !strings.HasPrefix(res.Header.Get("Content-Type"), "application/grpc") {
a.log.Error("middleware: not a grpc request", "attr", attr)
return a.escape.ServeHook(res, fmt.Errorf("invalid header for http request: %s", res.Header.Get("Content-Type")))
Expand All @@ -176,7 +176,7 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
attributes[id] = payloadField

a.log.Info("middleware: extracted", "field", payloadField, "attr", attr)
case hook.AttributeTypeJSONPayload:
case proxyattr.AttributeTypeJSONPayload:
if attr.Key == "" {
a.log.Error("middleware: payload key field empty")
return a.escape.ServeHook(res, fmt.Errorf("payload key field empty"))
Expand All @@ -190,7 +190,7 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
attributes[id] = payloadField

a.log.Info("middleware: extracted", "field", payloadField, "attr", attr)
case hook.AttributeTypeHeader:
case proxyattr.AttributeTypeHeader:
if attr.Key == "" {
a.log.Error("middleware: header key field empty")
return a.escape.ServeHook(res, fmt.Errorf("failed to parse json payload"))
Expand All @@ -204,7 +204,7 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
attributes[id] = headerAttr
a.log.Info("middleware: extracted", "field", headerAttr, "attr", attr)

case hook.AttributeTypeQuery:
case proxyattr.AttributeTypeQuery:
if attr.Key == "" {
a.log.Error("middleware: query key field empty")
return a.escape.ServeHook(res, fmt.Errorf("failed to parse json payload"))
Expand All @@ -218,7 +218,7 @@ func (a Authz) ServeHook(res *http.Response, err error) (*http.Response, error)
attributes[id] = queryAttr
a.log.Info("middleware: extracted", "field", queryAttr, "attr", attr)

case hook.AttributeTypeConstant, hook.AttributeTypeComposite:
case proxyattr.AttributeTypeConstant, proxyattr.AttributeTypeComposite:
if attr.Value == "" {
a.log.Error("middleware:", string(attr.Type), "value empty")
return a.escape.ServeHook(res, fmt.Errorf("failed to parse json payload"))
Expand Down Expand Up @@ -396,7 +396,7 @@ func getAttributesValues(attributes interface{}) ([]string, error) {
func composeResourcesName(resourceList []string, permissionAttributes map[string]interface{}) []string {
var resourcesName []string
for _, res := range resourceList {
resourcesName = append(resourcesName, proxy.ComposeAttribute(res, permissionAttributes))
resourcesName = append(resourcesName, proxyattr.ComposeAttribute(res, permissionAttributes))
}
return resourcesName
}
11 changes: 6 additions & 5 deletions internal/proxy/hook/authz/authz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/goto/shield/core/relation"
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/rule"
"github.com/goto/shield/internal/proxy/attribute"
"github.com/goto/shield/internal/proxy/hook"
"github.com/goto/shield/internal/proxy/hook/authz/mocks"
shieldlogger "github.com/goto/shield/pkg/logger"
Expand Down Expand Up @@ -275,7 +276,7 @@ func TestServeHook(t *testing.T) {
rule.HookSpec{
Name: "authz",
Config: map[string]interface{}{
"attributes": map[string]hook.Attribute{
"attributes": map[string]attribute.Attribute{
"project": {
Type: "constant",
Value: testPermissionAttributesMap["project"].(string),
Expand Down Expand Up @@ -346,7 +347,7 @@ func TestServeHook(t *testing.T) {
rule.HookSpec{
Name: "authz",
Config: map[string]interface{}{
"attributes": map[string]hook.Attribute{
"attributes": map[string]attribute.Attribute{
"project": {
Type: "constant",
Value: testPermissionAttributesMap["project"].(string),
Expand Down Expand Up @@ -442,7 +443,7 @@ func TestServeHook(t *testing.T) {
rule.HookSpec{
Name: "authz",
Config: map[string]interface{}{
"attributes": map[string]hook.Attribute{
"attributes": map[string]attribute.Attribute{
"project": {
Type: "constant",
Value: testPermissionAttributesMap["project"].(string),
Expand Down Expand Up @@ -541,7 +542,7 @@ func TestServeHook(t *testing.T) {
rule.HookSpec{
Name: "authz",
Config: map[string]interface{}{
"attributes": map[string]hook.Attribute{
"attributes": map[string]attribute.Attribute{
"project": {
Type: "constant",
Value: testPermissionAttributesMap["project"].(string),
Expand Down Expand Up @@ -641,7 +642,7 @@ func TestServeHook(t *testing.T) {
rule.HookSpec{
Name: "authz",
Config: map[string]interface{}{
"attributes": map[string]hook.Attribute{
"attributes": map[string]attribute.Attribute{
"project": {
Type: "constant",
Value: testPermissionAttributesMap["project"].(string),
Expand Down
22 changes: 0 additions & 22 deletions internal/proxy/hook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,6 @@ type Info struct {
Description string
}

const (
AttributeTypeJSONPayload AttributeType = "json_payload"
AttributeTypeGRPCPayload AttributeType = "grpc_payload"
AttributeTypeQuery AttributeType = "query"
AttributeTypeHeader AttributeType = "header"
AttributeTypeConstant AttributeType = "constant"
AttributeTypeComposite AttributeType = "composite"

SourceRequest AttributeType = "request"
SourceResponse AttributeType = "response"
)

type AttributeType string

type Attribute struct {
Key string `yaml:"key" mapstructure:"key"`
Type AttributeType `yaml:"type" mapstructure:"type"`
Index string `yaml:"index" mapstructure:"index"` // proto index
Source string `yaml:"source" mapstructure:"source"`
Value string `yaml:"value" mapstructure:"value"`
}

func ExtractHook(r *http.Request, name string) (rule.HookSpec, bool) {
rl, ok := ExtractRule(r)
if !ok {
Expand Down
13 changes: 7 additions & 6 deletions internal/proxy/middleware/attributes/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/goto/salt/log"
"github.com/goto/shield/core/project"
"github.com/goto/shield/internal/proxy/attribute"
"github.com/goto/shield/internal/proxy/middleware"
"github.com/goto/shield/pkg/body_extractor"
)
Expand All @@ -24,7 +25,7 @@ type Attributes struct {
}

type Config struct {
Attributes map[string]middleware.Attribute `yaml:"attributes" mapstructure:"attributes"`
Attributes map[string]attribute.Attribute `yaml:"attributes" mapstructure:"attributes"`
}

type ProjectService interface {
Expand Down Expand Up @@ -86,7 +87,7 @@ func (a *Attributes) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
_ = res

switch attr.Type {
case middleware.AttributeTypeGRPCPayload:
case attribute.AttributeTypeGRPCPayload:
// check if grpc request
if !strings.HasPrefix(req.Header.Get("Content-Type"), "application/grpc") {
a.log.Error("middleware: not a grpc request", "attr", attr)
Expand All @@ -105,7 +106,7 @@ func (a *Attributes) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
requestAttributes[res] = payloadField
a.log.Info("middleware: extracted", "field", payloadField, "attr", attr)

case middleware.AttributeTypeJSONPayload:
case attribute.AttributeTypeJSONPayload:
if attr.Key == "" {
a.log.Error("middleware: payload key field empty")
a.notAllowed(rw)
Expand All @@ -121,7 +122,7 @@ func (a *Attributes) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
requestAttributes[res] = payloadField
a.log.Info("middleware: extracted", "field", payloadField, "attr", attr)

case middleware.AttributeTypeHeader:
case attribute.AttributeTypeHeader:
if attr.Key == "" {
a.log.Error("middleware: header key field empty")
a.notAllowed(rw)
Expand All @@ -137,7 +138,7 @@ func (a *Attributes) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
requestAttributes[res] = headerAttr
a.log.Info("middleware: extracted", "field", headerAttr, "attr", attr)

case middleware.AttributeTypeQuery:
case attribute.AttributeTypeQuery:
if attr.Key == "" {
a.log.Error("middleware: query key field empty")
a.notAllowed(rw)
Expand All @@ -153,7 +154,7 @@ func (a *Attributes) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
requestAttributes[res] = queryAttr
a.log.Info("middleware: extracted", "field", queryAttr, "attr", attr)

case middleware.AttributeTypeConstant:
case attribute.AttributeTypeConstant:
if attr.Value == "" {
a.log.Error("middleware: constant value empty")
a.notAllowed(rw)
Expand Down
20 changes: 10 additions & 10 deletions internal/proxy/middleware/authz/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/goto/shield/core/group"
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/proxy"
"github.com/goto/shield/internal/proxy/attribute"
"github.com/goto/shield/internal/proxy/middleware"
"github.com/goto/shield/internal/schema"
"github.com/goto/shield/pkg/body_extractor"
Expand Down Expand Up @@ -44,9 +44,9 @@ type Authz struct {
}

type Config struct {
Actions []string `yaml:"actions" mapstructure:"actions"`
Permissions []Permission `yaml:"permissions" mapstructure:"permissions"`
Attributes map[string]middleware.Attribute `yaml:"attributes" mapstructure:"attributes"`
Actions []string `yaml:"actions" mapstructure:"actions"`
Permissions []Permission `yaml:"permissions" mapstructure:"permissions"`
Attributes map[string]attribute.Attribute `yaml:"attributes" mapstructure:"attributes"`
}

type Permission struct {
Expand Down Expand Up @@ -133,7 +133,7 @@ func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
_ = res

switch attr.Type {
case middleware.AttributeTypeGRPCPayload:
case attribute.AttributeTypeGRPCPayload:
// check if grpc request
if !strings.HasPrefix(req.Header.Get("Content-Type"), "application/grpc") {
c.log.Error("middleware: not a grpc request", "attr", attr)
Expand All @@ -151,7 +151,7 @@ func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
permissionAttributes[res] = payloadField
c.log.Info("middleware: extracted", "field", payloadField, "attr", attr)

case middleware.AttributeTypeJSONPayload:
case attribute.AttributeTypeJSONPayload:
if attr.Key == "" {
c.log.Error("middleware: payload key field empty")
c.notAllowed(rw, nil)
Expand All @@ -167,7 +167,7 @@ func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
permissionAttributes[res] = payloadField
c.log.Info("middleware: extracted", "field", payloadField, "attr", attr)

case middleware.AttributeTypeHeader:
case attribute.AttributeTypeHeader:
if attr.Key == "" {
c.log.Error("middleware: header key field empty")
c.notAllowed(rw, nil)
Expand All @@ -183,7 +183,7 @@ func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
permissionAttributes[res] = headerAttr
c.log.Info("middleware: extracted", "field", headerAttr, "attr", attr)

case middleware.AttributeTypeQuery:
case attribute.AttributeTypeQuery:
if attr.Key == "" {
c.log.Error("middleware: query key field empty")
c.notAllowed(rw, nil)
Expand All @@ -199,7 +199,7 @@ func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
permissionAttributes[res] = queryAttr
c.log.Info("middleware: extracted", "field", queryAttr, "attr", attr)

case middleware.AttributeTypeConstant:
case attribute.AttributeTypeConstant:
if attr.Value == "" {
c.log.Error("middleware: constant value empty")
c.notAllowed(rw, nil)
Expand Down Expand Up @@ -279,7 +279,7 @@ func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
func (c Authz) preparePermissionResource(ctx context.Context, perm Permission, attrs map[string]interface{}) (resource.Resource, error) {
resourceName, ok := attrs[perm.Attribute].(string)
if !ok {
resourceName = proxy.ComposeAttribute(perm.Attribute, attrs)
resourceName = attribute.ComposeAttribute(perm.Attribute, attrs)
}

res := resource.Resource{
Expand Down
Loading

0 comments on commit 6d0e1a3

Please sign in to comment.