Skip to content
45 changes: 37 additions & 8 deletions service/internal/access/v2/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,60 @@ func getResourceDecision(
)

var (
resourceID = resource.GetEphemeralId()
resourceAttributeValues *authz.Resource_AttributeValues
resourceID = resource.GetEphemeralId()
registeredResourceValueFQN string
resourceAttributeValues *authz.Resource_AttributeValues
)

switch resource.GetResource().(type) {
case *authz.Resource_RegisteredResourceValueFqn:
regResValueFQN := strings.ToLower(resource.GetRegisteredResourceValueFqn())
regResValue, found := accessibleRegisteredResourceValues[regResValueFQN]
registeredResourceValueFQN = strings.ToLower(resource.GetRegisteredResourceValueFqn())
regResValue, found := accessibleRegisteredResourceValues[registeredResourceValueFQN]
if !found {
return nil, fmt.Errorf("%w: %s", ErrFQNNotFound, regResValueFQN)
return nil, fmt.Errorf("%w: %s", ErrFQNNotFound, registeredResourceValueFQN)
}
l.DebugContext(
ctx,
"registered_resource_value",
slog.String("registered_resource_value_fqn", registeredResourceValueFQN),
slog.Any("action_attribute_values", regResValue.GetActionAttributeValues()),
)

resourceAttributeValues = &authz.Resource_AttributeValues{
Fqns: make([]string, 0),
}
for _, aav := range regResValue.GetActionAttributeValues() {
aavAttrValueFQN := aav.GetAttributeValue().GetFqn()

// skip evaluating attribute rules on any action-attribute-values without the requested action
if aav.GetAction().GetName() != action.GetName() {
continue
}

if !slices.Contains(resourceAttributeValues.GetFqns(), aavAttrValueFQN) {
resourceAttributeValues.Fqns = append(resourceAttributeValues.Fqns, aavAttrValueFQN)
}
}

// if no relevant attributes from action-attribute-values with the requested action,
// indicates a failure before attribute definition rule evaluation
if len(resourceAttributeValues.GetFqns()) == 0 {
failure := &ResourceDecision{
Passed: false,
ResourceID: resourceID,
ResourceName: registeredResourceValueFQN,
}
return failure, nil
}

case *authz.Resource_AttributeValues_:
resourceAttributeValues = resource.GetAttributeValues()

default:
return nil, fmt.Errorf("unsupported resource type: %w", ErrInvalidResource)
}

return evaluateResourceAttributeValues(ctx, l, resourceAttributeValues, resourceID, action, entitlements, accessibleAttributeValues)
return evaluateResourceAttributeValues(ctx, l, resourceAttributeValues, resourceID, registeredResourceValueFQN, action, entitlements, accessibleAttributeValues)
}

// evaluateResourceAttributeValues evaluates a list of attribute values against the action and entitlements
Expand All @@ -85,6 +109,7 @@ func evaluateResourceAttributeValues(
l *logger.Logger,
resourceAttributeValues *authz.Resource_AttributeValues,
resourceID string,
resourceName string,
action *policy.Action,
entitlements subjectmappingbuiltin.AttributeValueFQNsToActions,
accessibleAttributeValues map[string]*attrs.GetAttributeValuesByFqnsResponse_AttributeAndValue,
Expand Down Expand Up @@ -125,11 +150,15 @@ func evaluateResourceAttributeValues(
}

// Return results in the appropriate structure
return &ResourceDecision{
result := &ResourceDecision{
Passed: passed,
ResourceID: resourceID,
DataRuleResults: dataRuleResults,
}, nil
}
if resourceName != "" {
result.ResourceName = resourceName
}
return result, nil
}

func evaluateDefinition(
Expand Down
2 changes: 2 additions & 0 deletions service/internal/access/v2/evaluate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,11 +768,13 @@ func (s *EvaluateTestSuite) TestEvaluateResourceAttributeValues() {

for _, tc := range tests {
s.Run(tc.name, func() {
notRegisteredResourceFQN := ""
resourceDecision, err := evaluateResourceAttributeValues(
s.T().Context(),
s.logger,
tc.resourceAttrs,
"test-resource-id",
notRegisteredResourceFQN,
s.action,
tc.entitlements,
s.accessibleAttrValues,
Expand Down
1 change: 1 addition & 0 deletions service/internal/access/v2/pdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Decision struct {
type ResourceDecision struct {
Passed bool `json:"passed" example:"false"`
ResourceID string `json:"resource_id,omitempty"`
ResourceName string `json:"resource_name,omitempty"`
DataRuleResults []DataRuleResult `json:"data_rule_results"`
}

Expand Down
Loading
Loading