MCPcopy Create free account
hub / github.com/Permify/permify / checkIntersection

Function checkIntersection

internal/engines/check.go:689–736  ·  view source on GitHub ↗

checkIntersection checks if the subject has permission by running multiple CheckFunctions concurrently, the permission check is successful only when all CheckFunctions succeed (intersection).

(ctx context.Context, functions []CheckFunction, limit int)

Source from the content-addressed store, hash-verified

687// checkIntersection checks if the subject has permission by running multiple CheckFunctions concurrently,
688// the permission check is successful only when all CheckFunctions succeed (intersection).
689func checkIntersection(ctx context.Context, functions []CheckFunction, limit int) (*base.PermissionCheckResponse, error) {
690 // Initialize the response metadata
691 responseMetadata := emptyResponseMetadata()
692
693 // If there are no functions, deny the permission and return
694 if len(functions) == 0 {
695 return denied(responseMetadata), nil
696 }
697
698 // Create a channel to receive the results of the CheckFunctions
699 decisionChan := make(chan CheckResponse, len(functions))
700 // Create a context that can be cancelled
701 cancelCtx, cancel := context.WithCancel(ctx)
702
703 // Run the CheckFunctions concurrently
704 clean := checkRun(cancelCtx, functions, decisionChan, limit)
705
706 // When the function returns, ensure to cancel the context and clean up the resources
707 defer func() {
708 cancel()
709 clean()
710 close(decisionChan)
711 }()
712
713 // Iterate over the results of the CheckFunctions
714 for range len(functions) {
715 select {
716 // If a result is received
717 case d := <-decisionChan:
718 // Merge the response metadata with the received metadata
719 responseMetadata = joinResponseMetas(responseMetadata, d.resp.Metadata)
720 // If there was an error, deny the permission and return the error
721 if d.err != nil {
722 return denied(responseMetadata), d.err
723 }
724 // If the CheckFunction denied the permission, deny the permission and return
725 if d.resp.GetCan() == base.CheckResult_CHECK_RESULT_DENIED {
726 return denied(responseMetadata), nil
727 }
728 // If the context is done, deny the permission and return a cancellation error
729 case <-ctx.Done():
730 return denied(responseMetadata), errors.New(base.ErrorCode_ERROR_CODE_CANCELLED.String())
731 }
732 }
733
734 // If all CheckFunctions allowed the permission, allow the permission and return
735 return allowed(responseMetadata), nil
736}
737
738// checkExclusion is a function that checks if there are any exclusions for given CheckFunctions
739func checkExclusion(ctx context.Context, functions []CheckFunction, limit int) (*base.PermissionCheckResponse, error) {

Callers

nothing calls this directly

Calls 8

emptyResponseMetadataFunction · 0.85
deniedFunction · 0.85
checkRunFunction · 0.85
closeFunction · 0.85
joinResponseMetasFunction · 0.85
allowedFunction · 0.85
GetCanMethod · 0.80
StringMethod · 0.65

Tested by

no test coverage detected