Skip to main content
Version: 8.3

Implement a custom record permission extension

Level: advanced
note

This functionality is available for Creatio 8.3.4 and later.

Out-of-the-box record-level access rights cover the common Creatio scenarios. Users with the organizational or functional role can read, edit, or delete only the records their access rights allow. Learn more: Record permissions (user documentation).

The out-of-the-box mechanism can implement any access condition, but doing so requires recalculating access rights in advance and whenever the record data changes — typically through business processes or triggers. For a condition that depends on frequently changing data, or that applies to a large number of records, this recalculation can require significant computation and affect Creatio performance.

Since version 8.3.4, Creatio lets you extend the out-of-the-box record-level access rights with a condition, evaluated directly wherever Creatio checks access, instead of recalculating and storing access rights in advance. A record permission extension is the class you implement to add a custom condition for the read, edit, or delete operation and one or more "Object" type schemas. Learn more about how record permission extensions work: Extending record permissions.

To implement a custom record permission extension, complete the following steps.

1. Implement the extension class

  1. Create the "Source code" type schema. Instructions: Implement the source code (steps 1-5).

  2. Create a class that implements one or more interfaces listed in the following table. Select the interface based on the type of operation you need to extend.

    Operation to extend

    Interface

    Read

    IReadRecordPermissionExtension

    Edit

    IEditRecordPermissionExtension

    Delete

    IDeleteRecordPermissionExtension

    Implement one interface per operation you need to extend. Use a single class if several operations share the same rule, or separate classes if the operations must follow different business rules.

  3. Build the QueryCondition object inside the method that corresponds to the operation, using only the method arguments and local variables.

    Operation

    Method

    Read

    QueryCondition GetReadRightCondition(UserConnection userConnection, PermissionExtensionContext context)

    Edit

    QueryCondition GetEditRightCondition(UserConnection userConnection, PermissionExtensionContext context)

    Delete

    QueryCondition GetDeleteRightCondition(UserConnection userConnection, PermissionExtensionContext context)

    Follow the recommendations when you build the QueryCondition object:

    • Build the QueryCondition object from scratch on every call, and do not store the current user, schema code, aliases, or previously built conditions in instance fields or properties. A record permission extension implementation must be stateless.
    • Use the SchemaName property as the outer query source name. The context argument is a PermissionExtensionContext object, and its SchemaName property contains the schema code or alias of the "Object" type schema being evaluated.
    • Do not hardcode the outer schema code — the same extension might run for several "Object" type schemas, or the query might use an alias instead of the physical schema code.
    • If the extension builds a correlated subquery, link the subquery to the outer record through the SchemaName property, and give the subquery its own unique inner alias.
    • Keep the condition as simple as possible. The condition becomes part of the SQL filter Creatio uses whenever it evaluates record-level access rights for the configured operations and "Object" type schemas, so a complex or inefficient condition can noticeably affect system performance, especially for large tables, frequently used schemas, correlated subqueries, and conditions that make index usage less effective.
    • Prefer selective conditions, avoid unnecessary nested subqueries, and review the generated SQL before you use the extension in a pre-production environment.
  4. Add the [DefaultBinding(typeof(IReadRecordPermissionExtension), Name = nameof(UsrSomeAccessRightExtension))] attribute to the class, where UsrSomeAccessRightExtension is the schema name (the Code property).

    The following example implements the IReadRecordPermissionExtension and IEditRecordPermissionExtension interfaces for the "Read" and "Edit" operations.

    Implement the "IReadRecordPermissionExtension" and "IEditRecordPermissionExtension" interfaces
    [DefaultBinding(typeof(IReadRecordPermissionExtension),
    Name = nameof(UsrContactOwnerReadEditExtension))]
    [DefaultBinding(typeof(IEditRecordPermissionExtension),
    Name = nameof(UsrContactOwnerReadEditExtension))]
    public class UsrContactOwnerReadEditExtension :
    IReadRecordPermissionExtension, IEditRecordPermissionExtension
    {
    /* Implement the business logic. */
    }

    Creatio resolves the class through the ClassFactory class by this name.

As a result, you have a class that returns a custom QueryCondition object for one or more record permission operations.

2. Add the extension to Creatio

  1. Click btn_system_designer_8_shell.png in the top right → System setupLookups.

  2. Open the Record permission extension lookup. Out of the box, the lookup is empty.

  3. Click New.

  4. Fill out the properties of the lookup value. Even if one class implements several interfaces, each operation still needs its own row in the Record permission extension lookup. Out of the box, the lookup includes columns listed in the following table.

    Property

    Description

    Schema names

    One or more target "Object" type schemas for this rule. Separate several schema names with ";". For example, "Contact;Account." Creatio applies the rule separately to each schema.

    Extension combination mode

    The mode Creatio uses to combine the extension condition with the out-of-the-box record-right condition. Learn more about combination modes: Extension combination modes.

    Record permission operation type

    The operation this rule extends. Learn more about out-of-the-box operations: Record permissions (user documentation).

    Extension name

    The binding name of the extension class, exactly as specified in the DefaultBinding attribute during implementation. If the values do not match, the lookup value stays active, but Creatio does not use the class.

    Is active

    The checkbox that determines whether to apply the extension.

    Position

    The extension priority. A lower Position parameter value means higher priority. If several active extensions exist for the same operation and "Object" type schema, only the extension with the lowest Position parameter value applies at runtime. If the positions are equal, the most recently created extension applies instead.

  5. Check whether a higher-priority extension already exists for the same Schema names and Record permission operation type parameter values. Otherwise, the new extension stays inactive even if the Is active checkbox is selected.

  6. Click icn_save_lookup_value.png.

As a result, Creatio combines the returned condition with the out-of-the-box record-right logic according to the configured combination mode. Test both a scenario where the rule should grant access and one where it should deny access, to confirm the extension and the combination mode behave as expected.

Learn more about common implementation patterns: Record permission extension patterns.


See also

Record permissions (user documentation)

Extending record permissions

Record permission extension patterns