Table of Contents

Global Filter

The global filter is used to filter the data returned by the entity repository and to check that the data created, modified or deleted respects this filter.

It is a LINQ predicate.

Entering the Filter Expression

In the entity editor, you can enter the boolean expression for the Global Filter.

The variable e represents the entity instance in the LINQ expression.

Warning

The syntax of the expression is not checked and will be generated as-is.
The syntax error will only occur at runtime.

Examples of expression:

  • Filters the entities whose Enabled boolean property value is true:
e.Enabled
  • Filters the entities whose Type property value is Customer in a Party entity:
e.Type == PartyType.Customer

You can also use some context values in the expression.

Authenticated User

You can use two properties related to the authenticated user:

Example:

  • Filters the entities whose UserId property value is the identifier of the currently authenticated user:
e.UserId == UserId
Warning

Due to Entity Framework, the below expression can throw a null reference exception if the user is not authenticated:

 User != null && e.UserId == User.Identifier

To avoid this, you can use the UserId property:

 e.UserId == UserId

ApplicationContext

You can use the property ApplicationContext GroupeIsa.Neos.Shared.Metadata.IApplicationContext to access the application context values.

Examples:

  • Filters the entities whose CompanyId property value is equal to CompanyId context value:
e.CompanyId == ApplicationContext.GetIntValue("CompanyId")
  • Filters the entities whose CompanyId property value is contained in CompanyId context values:
ApplicationContext.GetIntValues("CompanyId").Contains(e.CompanyId)
  • Filters the entities whose CompanyId property value is contained in CompanyId context values by checking that the application context has a CompanyId entry with values:
ApplicationContext.FindRequiredIntValues("CompanyId").Any() && ApplicationContext.FindRequiredIntValues("CompanyId").Contains(e.CompanyId)
Note

If you want to set up value authorization for context keys, see Checking the allowed values

Permissions

You can use the static classes FunctionAuthorizer or FunctionResourceAuthorizer to check if the authenticated user has permission.

FunctionAuthorizer

FunctionAuthorizer checks if the user has a permission or not on a function, without considering a specific resource.

Two overloads of the method IsAllowed are available:

Overload 1: Allow/Deny function

bool IsAllowed(string functionName, bool defaultAuthorization = false);

Examples:

  • Filters the entities whose Activated boolean property value is true or allows all entities for a user having a role allowing it (by the function CanAccessNotActivatedItems), when the function's permission cannot be determined or when no scoped permissions are available, the default authorization is false (no access):
e.Activated || FunctionAuthorizer.IsAllowed("CanAccessNotActivatedItems")
  • Filters the entities whose Activated boolean property value is true or allows all entities for a user having a role allowing it (by the function CanAccessNotActivatedItems), when the function's permission cannot be determined or when no scoped permissions are available, the default authorization is true (access allowed):
e.Activated || FunctionAuthorizer.IsAllowed("CanAccessNotActivatedItems", true)

Overload 2: Function with access operation

bool IsAllowed(string functionName, AccessOperation? operation, bool defaultAuthorization = false);

Examples:

  • Filters the entities whose Actived boolean property value is true or allows all entities for a user having a role allowing it (by the function CanAccessNotActivedItems with the Read operation), when the function's permission cannot be determined or when no scoped permissions are available, the default authorization is false (no access):
e.Actived || FunctionAuthorizer.IsAllowed("CanAccessNotActivedItems", AccessOperation.Read)
  • Filters the entities whose Actived boolean property value is true or allows all entities for a user having a role allowing it (by the function CanAccessNotActivedItems with the Read operation), when the function's permission cannot be determined or when no scoped permissions are available, the default authorization is true (access allowed):
e.Actived || FunctionAuthorizer.IsAllowed("CanAccessNotActivedItems", AccessOperation.Read, true)

FunctionResourceAuthorizer

FunctionResourceAuthorizer checks if the user has a permission on a specific resource.

Two overloads of the method IsAllowed are available:

Overload 1: Allow/Deny function on resource

 bool IsAllowed(AccessResourceType type, string name, bool defaultAuthorization = false);

Examples:

  • Filters the entities whose Activated boolean property value is true or allows all entities for a user having a role allowing it (by the resource type MyEntityView), when the permission cannot be determined or when no scoped permissions are available, the default authorization is false (no access):
e.Activated || FunctionResourceAuthorizer.IsAllowed(AccessResourceType.EntityView, "MyEntityView")
  • Filters the entities whose Activated boolean property value is true or allows all entities for a user having a role allowing it (by the resource type MyEntityView), when the permission cannot be determined or when no scoped permissions are available, the default authorization is true (access allowed):
e.Activated || FunctionResourceAuthorizer.IsAllowed(AccessResourceType.EntityView, "MyEntityView", true)

Overload 2: Function with access operation on resource

bool IsAllowed(AccessResourceType type, string name, AccessOperation? operation, bool defaultAuthorization = false);

Examples:

  • Filters the entities whose Actived boolean property value is true or allows all entities for a user having a role allowing it (by the resource type MyEntityView with the Read operation), when the permission cannot be determined or when no scoped permissions are available, the default authorization is false (no access):
e.Actived || FunctionResourceAuthorizer.IsAllowed(AccessResourceType.EntityView, "MyEntityView", AccessOperation.Read)
  • Filters the entities whose Actived boolean property value is true or allows all entities for a user having a role allowing it (by the resource type MyEntityView with the Read operation), when the permission cannot be determined or when no scoped permissions are available, the default authorization is true (access allowed):
e.Actived || FunctionResourceAuthorizer.IsAllowed(AccessResourceType.EntityView, "MyEntityView", AccessOperation.Read, true)
Warning

In database migration, the permissions are not available, so if you use an entity repository with a global filter in a migration interceptor, you must set the defaultAuthorization parameter to true to access all the data.

Query

Repository queries filter the data according to the LINQ expression.

Creation and Modification

At the application layer, when saving via IUnitOfWork.SaveAsync(), the entity is checked for compliance with the LINQ expression after executing the Saving rules. On a non-compliant API POST or PUT call, the HTTP status code returned is 400:

{
    "errors": [
        {
            "detail": "A value is not allowed according to data access permissions.",
            "extensions": {},
            "instance": "/entity-view-validation-failed",
            "technical": false,
            "title": "Some entries are invalid.",
            "type": "https://doc.todo.com/errors/entity-view-validation-failed"
        }
    ],
    "technical": false,
    "traceId": "0HMPLKMV3L7MJ:00000003",
    "type": "https://doc.todo.com/errors/entity-view-validation-failed",
    "title": "Some entries are invalid.",
    "status": 400,
    "detail": null,
    "instance": null,
    "extensions": {}
}

Deletion

Deleting a non-compliant record is not allowed; the HTTP status code returned is 404:

{
    "errors": [],
    "technical": false,
    "traceId": "0HMPLKMV3L7MJ:00000004",
    "type": "https://doc.todo.com/errors/entity-fetch-failed",
    "title": "The entity could not be fetched.",
    "status": 404,
    "detail": "The entity view \"AgencyView\" with the key (Id : 5) was not found.",
    "instance": "/not-found",
    "extensions": {
        "keyProperties": [
            {
                "propertyName": "Id",
                "value": 5
            }
        ]
    }
}

Database Migration

The global filter is applied during database migration, so you must take it into account when you use your entity repositories in migration interceptors.

Under the Hood

A global EF Core filter is generated in the entity's EF configuration.
The filter is applied to the created or deleted entity instances to check their compliance with the filter.