You can use these OCL review queries to find unreachable ViewModels and potential mismatches between the access groups on actions and the ViewModels those actions open; this page is for model maintainers reviewing a large MDriven model.
Purpose
As a model grows, review whether users can reach the intended ViewModels and whether the access configuration of an action agrees with the ViewModel it navigates to.
Typical questions include:
- Does an action have an access group that its target ViewModel does not have?
- Does a ViewModel have no access group even though access-controlled actions navigate to it?
- Is a ViewModel intended for the user interface but not reachable through an action?
These queries produce review candidates. A result is not automatically an error. For example, a ViewModel without access groups can be intentional, and a ViewModel can be reached by a mechanism that is not represented by the query's action-navigation check. Review each result against the intended use case before changing the model.
Before you review
An access group controls whether a user can see and/or use associated actions and ViewModels. Read Access groups for the group evaluation rules. Access groups are distinct from interest groups: interest groups only filter the visibility of actions and are evaluated after access groups.
A ViewModel can also use an AccessExpression. When a ViewModel's AccessExpression evaluates to false, MDriven looks for a ViewModel named AccessDenied; if it cannot find one, it shows a blank screen. Use canAccess when an action needs to determine whether its current root object can open a ViewModel. See OCLOperators canAccess and Access control system in MDriven.
In the internal model used by these queries, a ViewModel is named Span. Therefore, the queries use Span.allInstances.
Review workflow
- Run one query at a time in the OCL query environment you use for model inspection.
- Inspect the returned ViewModel and action names, access-group lists, class names, and comments.
- Decide whether the configuration is intentional for that use case.
- If it is not intentional, change the relevant action, ViewModel, or access rule in MDriven Designer.
- Run the query again to confirm that the finding is resolved or remains documented as intentional.
- Test the affected use case with users for the relevant access groups. Also test the denied case, including the behavior of any
AccessDeniedViewModel.
Do not treat the absence of an access group as proof that access is unrestricted in every situation. AccessExpression and other model rules can still determine whether a ViewModel is available for a particular root object.
Queries
Use this query to identify ViewModels that appear to be user-interface ViewModels but have no action that opens them.
Span.allinstances->select(s|s.ShowByActions->isEmpty and s.CriteriaForServerSideExecute->isEmpty and s.UsePlacingHints )->collect(span | span.Category.Name, span.Name, span.Class.Name, span.CodeComment)->orderBy(x|x.Name, x.Name1)The query excludes ViewModels with server-side execution criteria and selects ViewModels that use placing hints. It returns the category name, ViewModel name, class name, and code comment.
For example, if CustomerSummary is returned, check whether an action should navigate to it. If it is an intentionally embedded or otherwise non-navigable UI ViewModel, retain it and record that intent in its code comment or the team's review record.
Find ViewModels with no access group that are opened by access-controlled actions
Use this query to find ViewModels with no assigned access groups when one or more actions that navigate to them do have access groups.
Span.allInstances->select(s|s.AccessGroups->isEmpty and s.CriteriaForServerSideExecute->isEmpty and s.UsePlacingHints and s.ShowByActions->notEmpty)->
collect(s|s.Name, s.AccessGroups.Name->asCommaList, (s.ShowByActions->collect(a|a.Name + ' AG:' + a.AccessGroups.Name->asCommaList))->asCommaList)The output contains:
| Column | Meaning |
|---|---|
| ViewModel name | The ViewModel under review. |
| ViewModel access groups | The access groups assigned directly to that ViewModel. This value is empty for every result because the query selects only ViewModels with no access groups. |
| Navigating actions and their access groups | Each action that shows the ViewModel, followed by that action's access groups. |
For example, if AdminOverview has no access groups but OpenAdminOverview is assigned to an administrator access group, decide whether the ViewModel itself must also be protected. Check its AccessExpression as part of that decision. Apply access settings at the level required by the use case; do not add groups only to make the query return no rows.
Find actions whose access groups are not present on their target ViewModel
Use this query to find actions that have one or more access groups missing from the ViewModel they bring up.
AbstractAction.allInstances->select(aa|aa.BringUpViewModel.notNull and aa.BringUpViewModel.CriteriaForServerSideExecute->isEmpty and aa.AccessGroups->difference(aa.BringUpViewModel.AccessGroups)->notEmpty)->
collect(aa|aa.oclType.asString, aa.Name, aa.AccessGroups.Name->asCommaList, aa.BringUpViewModel.Name, aa.BringUpViewModel.AccessGroups.Name->asCommaList)->orderBy(x|x.Part1, x.Name)The expression aa.AccessGroups->difference(aa.BringUpViewModel.AccessGroups) identifies access groups assigned to the action but not to its target ViewModel.
The output lists the action type, action name, action access groups, target ViewModel name, and target ViewModel access groups. For example, if OpenPayroll has the Payroll access group but its target PayrollOverview does not, review whether users could reach that ViewModel through another route. If the ViewModel must be restricted wherever it is reached, align its access configuration or define the appropriate AccessExpression.
Resolve findings deliberately
Use the finding type to guide the change:
| Finding | Review question | Possible outcome |
|---|---|---|
| No action navigates to a ViewModel | Is the ViewModel meant to be opened directly by an action, or is it intentionally used only as part of another UI arrangement? | Add or correct the navigation action, or retain the ViewModel as intentionally non-navigable. |
| ViewModel has no access groups; navigating actions do | Must the ViewModel be protected independently of the actions that currently open it? | Add the required ViewModel access groups, define an appropriate AccessExpression, or document why no direct ViewModel group is needed. |
| Action groups are absent from its target ViewModel | Can the target ViewModel be reached by another route, and should the same users be able to open it there? | Align the ViewModel's access configuration, change the action's group assignment, or retain a deliberate difference. |
Do not use an action's Enable expression as a substitute for the overall access-control design. Access groups address role- or situation-based visibility and enablement, while action Enable expressions can provide more specific conditions. For the broader model security approach, see Documentation:Restricting data access and Training:Information security.
