Expression Access Filters

User access lists defined on a policy or rule can accept a filter expression to grant or deny access to a specific user.

Policies and rules should use organization, project, maturity, and reserve logic instead of access filters whenever possible. These security checks ensure the completeness of search results. Instead of access filters, try to use keys in policy and rule definitions. For more information, see Rules to Determine Access.

This page discusses:

For example, the access portion of the policy or rule might be:

user Writer read,modify,fromconnect,toconnect filter ACCESS_FILTER;

Where ACCESS_FILTER is any valid MQL expression. If the filter expression evaluates to “true,” the specified access will be granted; otherwise the access is denied.

To evaluate a filter, at least Read access (and Show access, if enabled) is required so these access checks are disabled when analyzing filters. However, if the filter includes the access selectable, such as one that checks access on a connected object, these access checks are turned back on for evaluation.

A filter in a policy is always executed in the context of the login user. Use localfilter instead of filter in policies and access rules to return only results to which the current user definitely has access. When you use localfilter, the expression is not evaluated by full-text search.

These operands can be used in expression access filters:

Operand Example
Anything that you can select on a business object a" == "High") && (description ~~ "*test**")
Anything that you can select from the context user object context.user.isassigned[Group_Name] == true
Any property defined on the "context user" context.user.property[Export Allowed].value == true
Any expression that checks the access inherited from a connected object to.from.current.access[modify] ~~ true

This expression evaluates to true for a business object at the "to" end of a connection only if the business object at the "from" end has the named access. The $ACCESS macro can be used generically to check the access required for any requested operation. For more information, see $ACCESS Macro.

In a business object attribute value and have 3DSpace evaluate the expression stored in the attribute when checking access evaluate attribute[expattr]

Objects governed by a policy that includes this filter, must be of a type that includes the expattr attribute. 3DSpace first extracts the expression stored as the value of the attribute “expattr” and then evaluates that expression against the business object. For example, if the value of the attribute “expattr” is context.user.isassigned[MX-GROUP-1] == true && context.user.isassigned[Role_1] == true, access is given only to users with these assignments.

In a business object description and have 3DSpace evaluate the expression stored in the description. evaluate description

For objects governed by a policy that includes this filter, 3DSpace first extracts the expression stored as the description and then evaluates that expression against the business object. For example, if the value of the description is context.user.isassigned[MX-GROUP-1] == true && context.user.isassigned[Role_1] == true, access is given only to users with these assignments.

A dynamic expression stored in a description of a connected control object

This allows you to store the expression filter rule in some central object to which all objects to be controlled are connected.

If Assembly MTC1234 0 is connected to Control Rule1 0 by relationship Control, you could define this expression filter: evaluate to[Control].businessObject.description

For objects governed by the policy that includes this filter, 3DSpace first extracts the expression stored as the description of the object connected by the Control relationship and then evaluates that expression against the business object. For example, if the value of that description is:

context.user.isassigned[MX-GROUP-1] == true &&
 context.user.isassigned[Role_1] == true
then access is given only to users with these assignments.

If a revoke filter expression evaluates to “true,” the specified access will not be granted. If it evaluates to “false,” the specified access will not be revoked but it will also not be granted. Before access is granted, the system checks to see if access has been explicitly granted.

Filter expressions of the form current.access[ACCESS_TYPE] == TRUE accept minorrevise as an ACCESS_TYPE. However, filter expressions of the form current.access ~~ *ACCESS_TYPE* are risky because revise is a substring of both minorrevise and majorrevise.

$ACCESS Macro

The $ACCESS macro can be used generically to check the access required for any requested operation. For example: to.from.current.access[$ACCESS] ~~ true. This access filter results in modify replacing $ACCESS during macro processing for mod bus T N R on the child object. The expression evaluates to true only if the object at the from end of the connection has modify access.

If an object is connected to more than one parent object, the expression evaluates to true if any one of the parents has the required access. To specify that a child should inherit the access from only one of the parents, the expression must identify the relevant connection between the parent and the child. For example: to[relationship1].from.current.access[$ACCESS] ~~ true

The $ACCESS macro within brackets is recognized for the "access" selectable of the state of a business object, as in one of the following:

current.access[$ACCESS] 
state[STATE1].access[$ACCESS]

The macro is not expanded if it appears anywhere else in the expression, including if a program is called as part of the access filter. There will be no macro substitution for $ACCESS in this access filter:

program[checkAccess $ACCESS]
However, if the checkAccess program itself creates a command of the form print bus $OBJECTID select current.access[$ACCESS], it will be evaluated.

In the following show, read, modify access filter, the $ACCESS macro appears outside brackets:

filter '("$ACCESS" == "show") || ("$ACCESS" == "modify" && (from.owner == context.user))'
This expanded use of $ACCESS can be used to create rules that define the access a user has on a relationship.

The $ACCESS macro can be used in an access rule filter and is populated with the current access being checked whenever the filter is evaluated. For example, the following rule allows a different condition for modify versus revise access:

($ACCESS == modify && <modify-condition>) || ($ACCESS == revise $$ <revise-condition>)

Output from the revise portion of this filter continues to be "revise" instead of "minorrevise" to maintain backward compatibility.

Expression Access Filter Example

When developing filters, you can use the eval expr command on the filter to qualify that the expression is valid before including it in the policy or rule.

For example:

MQL<15> eval expr '(attribute[Actual Weight] > 100) AND
("relationship[Designed Part Quantity].to.type" == "Body Shell")' on
bus Comment 12345 1;
From the above we can say that the expression
'(attribute[Actual Weight] > 100) AND ("relationship[Designed Part
Quantity].to.type" == "Body Shell")' 
is a valid expression and thus can be used for an expression access filter.

Context in which the filter is executed, for example:

MQL<1>add person pgrantor;

MQL<2>add person pgrantee;

MQL<3>add type test_typ;

MQL<4>add policy ptest type test_typ state exists public show,read
user pgrantor grant,revoke,changevault filter
'state[toggle].access[execute]' state toggle public show user pgrantor
execute;

# Add the bus and the grant
MQL<5> add bus test_typ bus1 0 policy ptest vault xxxx;
MQL<6> set context user pgrantor;
MQL<7> mod bus test_typ bus1 0 grant pgrantee access changevault;
MQL<8> set context user pgrantor;
MQL<9> print bus test_typ bus1 0 select current.access[changevault];
>>TRUE
MQL<10> set context user pgrantee;
MQL<11> print bus t2 ptest 0 select current.access[changevault]
>> FALSE

This is because the pgrantor has execute access in state toggle. Even though pgrantee is granted the changevault access, the login user (pgrantee) has no execute access in state ‘toggle’ resulting in filter ('state[toggle].access[execute]') condition to fail and thus it shows FALSE for: print bus test_typ bus1 0 select current.access[changevault].

MQL<12> set context user creator;
MQL<13> mod policy ptest state toggle remove user pgrantor execute; 
MQL<14> mod policy ptest state toggle user pgrantee execute;
MQL<15> set context user pgrantor; 
MQL<16> print bus test_typ bus1 0 select current.access[changevault]; 
>> FALSE 
MQL<17> set context user pgrantee; 
MQL<18> print bus test_typ bus1 0 select current.access[changevault];
>> TRUE 

It should be TRUE since even though the policy state ‘exist ’ has NO access or rule for pgrantee, the business object already has a changevault access granted to pgrantee by pgrantor. Pgrantor is then validated against the access rule from policy state ‘exist’ and it is found to be valid. Even the filter condition is satisfied since the login user (pgrantee) has execute access in state ‘toggle’.