Skip to content

Commit

Permalink
add header for user id (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
krtkvrm authored Apr 19, 2022
1 parent 85d9f0a commit f00dcf8
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cmd/serve_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
func buildMiddlewarePipeline(logger log.Logger, proxy http.Handler, ruleRepo store.RuleRepository, identityProxyHeader string, deps handler.Deps, authZCheckService permission.CheckService) http.Handler {
// Note: execution order is bottom up
prefixWare := prefix.New(logger, proxy)
casbinAuthz := authz.New(logger, identityProxyHeader, deps, prefixWare, authZCheckService)
casbinAuthz := authz.New(logger, identityProxyHeader, deps, prefixWare, authZCheckService, authZCheckService.PermissionsService)
basicAuthn := basic_auth.New(logger, casbinAuthz)
matchWare := rulematch.New(logger, basicAuthn, rulematch.NewRouteMatcher(ruleRepo))
return matchWare
Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ type Service struct {
// Headers which will have user's email id
IdentityProxyHeader string `yaml:"identity_proxy_header" mapstructure:"identity_proxy_header" default:"X-Shield-Email"`

// Header which will have user_id
UserIDHeader string `yaml:"user_id_header" mapstructure:"user_id_header" default:"X-Shield-User-Id"`

// ResourcesPath is a directory path where resources is defined
// that this service should implement
ResourcesConfigPath string `yaml:"resources_config_path" mapstructure:"resources_config_path"`
Expand Down
22 changes: 20 additions & 2 deletions middleware/authz/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,34 @@ import (
"github.com/odpf/salt/log"
)

const (
userIDHeader = "X-Shield-User-Id"
)

type AuthzCheckService interface {
CheckAuthz(ctx context.Context, resource model.Resource, action model.Action) (bool, error)
}

type PermissionService interface {
FetchCurrentUser(ctx context.Context) (model.User, error)
}

type Authz struct {
log log.Logger
identityProxyHeader string
next http.Handler
Deps handler.Deps
AuthzCheckService AuthzCheckService
PermissionService PermissionService
}

type Config struct {
Actions []string `yaml:"actions" mapstructure:"actions"`
Attributes map[string]middleware.Attribute `yaml:"attributes" mapstructure:"attributes"` // auth field -> Attribute
}

func New(log log.Logger, identityProxyHeader string, deps handler.Deps, next http.Handler, authzCheckService AuthzCheckService) *Authz {
return &Authz{log: log, identityProxyHeader: identityProxyHeader, Deps: deps, next: next, AuthzCheckService: authzCheckService}
func New(log log.Logger, identityProxyHeader string, deps handler.Deps, next http.Handler, authzCheckService AuthzCheckService, permissionService PermissionService) *Authz {
return &Authz{log: log, identityProxyHeader: identityProxyHeader, Deps: deps, next: next, AuthzCheckService: authzCheckService, PermissionService: permissionService}
}

func (c Authz) Info() *structs.MiddlewareInfo {
Expand All @@ -47,6 +56,15 @@ func (c Authz) Info() *structs.MiddlewareInfo {
}

func (c *Authz) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
user, err := c.PermissionService.FetchCurrentUser(req.Context())
if err != nil {
c.log.Error("middleware: failed to get user details", "err", err.Error())
c.notAllowed(rw)
return
}

req.Header.Set(userIDHeader, user.Id)

rule, ok := middleware.ExtractRule(req)
if !ok {
c.next.ServeHTTP(rw, req)
Expand Down

0 comments on commit f00dcf8

Please sign in to comment.