checkDirectCall creates and returns a CheckFunction that performs direct permission checking. The function evaluates permissions based on rule definitions, arguments, and attributes.
( request *base.PermissionCheckRequest, )
| 525 | // checkDirectCall creates and returns a CheckFunction that performs direct permission checking. |
| 526 | // The function evaluates permissions based on rule definitions, arguments, and attributes. |
| 527 | func (engine *CheckEngine) checkDirectCall( |
| 528 | request *base.PermissionCheckRequest, |
| 529 | ) CheckFunction { |
| 530 | return func(ctx context.Context) (*base.PermissionCheckResponse, error) { |
| 531 | var err error |
| 532 | |
| 533 | // If an error occurs during the check, this default "denied" response will be returned. |
| 534 | emptyResp := denied(emptyResponseMetadata()) |
| 535 | |
| 536 | // Read the rule definition from the schema. If an error occurs, return the default denied response. |
| 537 | var ru *base.RuleDefinition |
| 538 | ru, _, err = engine.schemaReader.ReadRuleDefinition(ctx, request.GetTenantId(), request.GetPermission(), request.GetMetadata().GetSchemaVersion()) |
| 539 | if err != nil { |
| 540 | return emptyResp, err |
| 541 | } |
| 542 | |
| 543 | // Initialize an arguments map to hold argument values. |
| 544 | arguments := map[string]any{ |
| 545 | "context": map[string]any{ |
| 546 | "data": request.GetContext().GetData().AsMap(), |
| 547 | }, |
| 548 | } |
| 549 | |
| 550 | // List to store computed attributes. |
| 551 | attributes := make([]string, 0) |
| 552 | |
| 553 | // Iterate over request arguments to classify and process them. |
| 554 | for _, arg := range request.GetArguments() { |
| 555 | switch actualArg := arg.Type.(type) { |
| 556 | case *base.Argument_ComputedAttribute: |
| 557 | // Handle computed attributes: Set them to a default empty value. |
| 558 | attrName := actualArg.ComputedAttribute.GetName() |
| 559 | emptyValue := getEmptyValueForType(ru.GetArguments()[attrName]) |
| 560 | arguments[attrName] = emptyValue |
| 561 | attributes = append(attributes, attrName) |
| 562 | default: |
| 563 | // Return an error for any unsupported argument types. |
| 564 | return denied(emptyResponseMetadata()), errors.New(base.ErrorCode_ERROR_CODE_INTERNAL.String()) |
| 565 | } |
| 566 | } |
| 567 | |
| 568 | // If there are computed attributes, fetch them from the data source. |
| 569 | if len(attributes) > 0 { |
| 570 | filter := &base.AttributeFilter{ |
| 571 | Entity: &base.EntityFilter{ |
| 572 | Type: request.GetEntity().GetType(), |
| 573 | Ids: []string{request.GetEntity().GetId()}, |
| 574 | }, |
| 575 | Attributes: attributes, |
| 576 | } |
| 577 | |
| 578 | ait, err := engine.dataReader.QueryAttributes(ctx, request.GetTenantId(), filter, request.GetMetadata().GetSnapToken(), database.NewCursorPagination()) |
| 579 | if err != nil { |
| 580 | return denied(emptyResponseMetadata()), err |
| 581 | } |
| 582 | |
| 583 | cta, err := storageContext.NewContextualAttributes(request.GetContext().GetAttributes()...).QueryAttributes(filter, database.NewCursorPagination()) |
| 584 | if err != nil { |
no test coverage detected