AS ABAP Release 758, ©Copyright 2024 SAP SE. All rights reserved.
ABAP - Keyword Documentation → ABAP - Core Data Services (ABAP CDS) → ABAP CDS - Access Control → ABAP CDS - DCL Statements → CDS DCL - DEFINE ROLE → CDS DCL - DEFINE ROLE, condition → CDS DCL - DEFINE ROLE, inherit_condition → CDS DCL - DEFINE ROLE, replacing →CDS DCL - DEFINE ROLE, replacement_step
Syntax
... { PFCG_FILTER [ OBJECT auth_object ] FIELD auth_field VALUE old WITH new }
| { PARAMETERS WITH ( param1 : value1 [, param2 : value2 ...] ) }
| { ROOT WITH path_expr [INCLUDING PARAMETERS ] }
| { ELEMENT source_match WITH target }
| { PREFIX WITH prefix }
| { CONDITIONS ON ANY OF ( element1 [, element2 ... ] ) WITH (TRUE|FALSE |VOID ) }
| { IF ALL CONDITIONS VOID THEN (TRUE|FALSE|VOID) } ...
1. ... PFCG_FILTER [OBJECT auth_object] FIELD auth_field VALUE old WITH new
2. ... PARAMETERS WITH ( param1 : value1 [, param2 : value2 ...] )
3. ... ROOT WITH path_expr [INCLUDING PARAMETERS ]
4. ... ELEMENT source_match WITH target
5. ... PREFIX WITH prefix
6. ... CONDITIONS ON ANY OF (element1 [, element2 ...]) WITH (TRUE |FALSE |VOID)
7. ... IF ALL CONDITIONS VOID THEN (TRUE |FALSE |VOID)
Effect
A replacement step operates on a set of inherited access conditions and can update or replace them.
... PFCG_FILTER [OBJECT auth_object] FIELD auth_field VALUE old WITH new
Effect
This replacement step processes the literal values which are mapped to authorization fields in PFCG conditions.
auth_field selects the authorization field. Occurrences of the value
old are then replaced with the value new. Both values must be written as literals in single quotes.
... OBJECT auth_object
Effect
With this addition, the replacement process can be restricted to the authorization object auth_object.
Hints
Example
Replacement based on authorization field name independent of authorization object.
Input:
(...) = ASPECT PFCG_AUTH( OBJECT_1, ..., ACTVT = '03' ) OR
(...) = ASPECT PFCG_AUTH( OBJECT_2, ..., ACTVT = '03' )
Replacement step:
PFCG_FILTER FIELD ACTVT VALUE '03' WITH 'F4'
Output:
(...) = ASPECT PFCG_AUTH( OBJECT_1, ..., ACTVT = 'F4' ) OR
(...) = ASPECT PFCG_AUTH( OBJECT_2, ..., ACTVT = 'F4' )
Example
Replacement of authorization field in a dedicated authorization object only.
Input:
(...) = ASPECT PFCG_AUTH( OBJECT_1, ..., ACTVT = '03' ) OR
(...) = ASPECT PFCG_AUTH( OBJECT_2, ..., ACTVT = '03' )
Replacement step:
PFCG_FILTER OBJECT OBJECT_1 FIELD ACTVT VALUE '03' WITH 'F4'
Output:
(...) = ASPECT PFCG_AUTH( OBJECT_1, ..., ACTVT = 'F4' ) OR
(...) = ASPECT PFCG_AUTH( OBJECT_2, ..., ACTVT = '03' )
Example
Exchange of two authorization field values using a temporary helper value.
Input:
(...) = ASPECT PFCG_AUTH( OBJECT_1, ..., ACTVT = '01' ) OR
(...) = ASPECT PFCG_AUTH( OBJECT_2, ..., ACTVT = '02' )
Replacement step:
PFCG_FILTER FIELD ACTVT VALUE '02' WITH 'TEMP',
PFCG_FILTER FIELD ACTVT VALUE '01' WITH '02',
PFCG_FILTER FIELD ACTVT VALUE 'TEMP' WITH '01'
Output:
(...) = ASPECT PFCG_AUTH( OBJECT_1, ..., ACTVT = '02' ) OR
(...) = ASPECT PFCG_AUTH( OBJECT_2, ..., ACTVT = '01' )
... PARAMETERS WITH ( param1 : value1 [, param2 : value2 ...] )
Effect
References to CDS parameters ($parameters param...) used in the inherited access conditions (either within path filters of left side elements or as left side host expressions) are replaced by new parameter values value.
For value you can insert:
Hints
Example
Replacement of the parameters P1 and P2 or the source entity with a parameter of the target entity and a literal.
Input:
toX ( F = $PARAMETERS.P1 OR G = $PARAMETERS.P2 )
Replacement step:
PARAMETERS WITH ( P1 : $PARAMETERS.P2, P2 : 'U' )
Output:
toX ( F = $PARAMETERS.P2 OR G = 'U' )
The same result would have been created with two separate steps:
PARAMETERS WITH ( P1 : $PARAMETERS.P2 ),
PARAMETERS WITH ( P2 : 'U' )
... ROOT WITH path_expr [INCLUDING PARAMETERS]
Effect
This replacement step processes left side CDS elements and relocates them into the provided association path_expr.
The path expression can have one or more levels and can be specified in the same way as in the CDS entity.
The entity of the last path component must be the source entity of the inheritance condition.
Hints
...INCLUDING PARAMETERS
Effect
When the entity of the last association component of path_expr has parameters and some of them are specified as part of the ROOT WITH statement, this parameter binding is used to perform parameter replacement in the condition set.
Hints
Example
You have a base entity S (for example a released SAP entity) and create a custom entity C using S as datasource.
DEFINE VIEW ENTITY C
AS SELECT FROM S
ASSOCIATION [1..1] TO S AS toS ON ...
{ ... }
Using the association toS, access control of S can now be taken over to C:
GRANT SELECT ON C WHERE INHERITING CONDITIONS FROM ENTITY S
REPLACING { ROOT WITH toS };
An access condition of S like
state = 'X'
will then be executed for C as
toS.state = 'X'
Example
In the example above, S has a parameter DEMO and the access condition is
toState[ f = $parameters.DEMO ].value = 'A'
In entity C, this parameter is supplied with a fixed value 'P'
DEFINE VIEW ENTITY C AS SELECT FROM S( DEMO : 'P' ) ...
In the access control, the usage of the unchanged toS allows and eventually even requires the parameter to be supplied.
GRANT SELECT ON C WHERE INHERITING CONDITIONS FROM ENTITY S
REPLACING { ROOT WITH toS( DEMO : 'P' ) };
This would result in the access condition
toS.toState[ f = $parameters.DEMO ].value = 'X'
This still requires that also C has the parameter DEMO.
By adding INCLUDING PARAMETERS
GRANT SELECT ON C WHERE INHERITING CONDITIONS FROM ENTITY S
REPLACING { ROOT WITH toS( DEMO : 'P' ) INCLUDING PARAMETERS };
you apply a parameter replacement and the result is
toS.toState[ f = 'P' ].value = 'X'
...ELEMENT source_match WITH target
Effect
This replacement step searches for left side CDS elements matching the given source_match and replaces them by the given target.
Both source_match and target must together belong to one of the following categories:
In this flavor, the statement replaces dedicated left side CDS elements.
In this flavor, the statement allows renaming of associations, while preserving all parts after the matching source components.
Parameter bindings or path filters of the last source match component can either by specified in the source match and by this get consumed or can remain unmentioned in the source match in which case they are taken over to the resulting element.
The provided target may contain parameter bindings or path filters at all locations.
The source matching process has the following properties:
Hints
Example
Instead of full examples for each possible case, the following table shows in compact form various combinations of source match and target in the ELEMENT WITH operator and how they operate on incoming left side elements.
| source_match | Input Left Side Element | Match | target | Output Left Side Element | Explanation |
| A | A | Yes | B | B | Simple entity field |
| A | B | No | Must match exactly. | ||
| A | toB | Error | You cannot replace a field with an association. | ||
| A | toB.A | No | Match must be complete. That the left-side ends with a field named A is different from a field named A. | ||
| A | A | Yes | toB.C | toB.C | You can replace a field with a path expression. |
| A | A | Yes | toB (p:'x' ).toC [i=3 ].toD(q:'Y') [j=5].E | toB (p:'X').toC [i=3].toD(q:'Y') [j=5].E | Parameters and filters are supported in the target. |
| A | A | Yes | A | A | At first, this looks like a NOOP, but it isn't. It has a meaning when
optional elements are involved. With this replacing, the author of the DCL source containing the ELEMENT A WITH A explicitly declares that he/she knows that the inherited entity containes element A (otherwise, the own DCL source would be syntactically incorrect already here). Optionality for A from the inherited source is therefore removed, as from that point on, the existence of A is certain. Similarly, when the inherited source contains A and the author of the current DCL source wants to have A optional from this point on, this statement is the only way to let the own WITH OPTIONAL ELEMENTS (A DEFAULT ...) become applicable to the inherited A. |
| toA.B | toA.B | Yes | ? | ? | You can match path expressions and replace them as above with anything you like (? can be field or path expression, the latter with parameters and filters, see above). |
| toA.B | toA.C | No | Match must be complete. | ||
| toA.B | toB.B | No | Match must be complete. | ||
| toA.B | toC | Error | You cannot replace a (terminated) path expression with an (open) association. | ||
| toA(p:'X').toB[i=3].C, | toA(p:'X').toB[i=3].C | Yes | ? | ? | Source matcher can have parameter bindings and filters |
| toA(p:'X').toB[i=3].C | toA(p:'Y').toB[i=3].C | No | Parameter bindings must be literally the same (name-case and technical whitespace ignored, but count, order and values are relevant). | ||
| toA(p:'X').toB[i=3].C | toA(p:'X').toB[3=i].C | No | Filters are not semantically normalized. | ||
| toA | toA.B | Yes | toX | toX.B | Replacement of an (open) association with another one in the target entity. The trailing part after the match is taken over after the target fragment. |
| toA.toB | toA.toB.toC.toD.E | Yes | toX.toY | toX.toY.toC.toD.E | The same with longer chains. |
| toA[i=3] | toA[i=3].B | Yes | toX | toX.B | The filter from the left-side has been consumed by the source matcher (this and the following examples use a path filter for demonstration, with parameter bindings the same would happen, and when parameter bindings and filters come together, both operate independently from each other). |
| toA[i=3] | toA[i=3].B | Yes | toX[i=4] | toX[i=4].B | The target fragment can supply the resulting left-side with its own path filter. |
| toA[i=3] | toA[i=4].B | No | When filters are present in the source matcher, they must match. | ||
| toA | toA[i=3].B | Yes | toX | toX[i=3].B | The filter has not been consumed by the matcher and is therefore taken over from the left-side and attached to the target fragment. |
| toA | toA[i=3].B | Yes | toX[i=3] | Error | As the filter from the left side has not been consumed, it must be taken over to the target fragment. But this one already has a filter. This potential conflict is not permissive (even when both are literally the same). |
PREFIX WITH prefix
This replacement step is not released for usage in customer created access controls but only internally at SAP.
Effect
This replacement step processes left side CDS elements and changes the name of the first component such that it starts with the provided prefix.
When the concatenation of prefix and component name exceeds the maximum component name length of 30 characters, a name compression algorithm will shorten the component name accordingly in a way that ensures name uniqueness but preserves some readability.
The prefix can contain the ampersand character & at a single location. Then, this location of the resulting component name will contain an upwards counting number which is used when the same component name is handled with this replacement step again.
Hints
Example
The following table demonstrates the effects of the statement.
| Input element | Prefix | Output element | Comment |
| A | P_ | P_A | |
| toB.C | P_ | P_toB.C | |
| ALREADY_LONG_ELEMENT_NAME | LONGPF | LONGPFALREAD_F3BD3673_ENT_NAME | The exact syntax of the shortening may look different, this shall only provide the idea. The algorithm of the shortening is not published and only available internally at SAP as API for the components eligible to use this feature. |
| A | SAP_&_ | SAP_1_A | Initial prefix for view stacks. |
| SAP_1_A | SAP_&_ | SAP_2_A | Follow-up prefix for view stacks. |
... CONDITIONS ON ANY OF (element1[, element2 ...]) WITH (TRUE|FALSE| VOID)
Effect
This replacement step replaces an entire access condition with one of the given operators TRUE, FALSE or VOID, when any of its left side elements matches one of the given elements element1, element2, ... .
The match elements can be either fields or path expressions, also open associations are supported.
Parameter bindings and path filters must not be specified, as a match element only considers the component
names and matches incoming path expressions irrespectively of whether they contain parameter bindings or path filters.
Hints
Example
The inherited condition
( toA[F = 1].B, C ) = ASPECT PFCG_AUTH( ... )
will be replaced by TRUE with any of the following steps:
IF ALL CONDITIONS VOID THEN (TRUE|FALSE|VOID)
Effect
This step analyzes the current state of the condition set in the inheritance/replacement procedure. When it comprises only the VOID operator, the entire condition set is replaced by the given replacement value
Hints