AccessGroups, InterestGroups and ViewModel-Enable

This article describes new features introduced in January 2024.

Access Groups

An AccessGroup is a collection of Enable, Visible and View-Enable expressions. The expressions are not rooted - meaning they have no particular context like a user or anything. To get the context of the current user that is very common for AccessGroups, one could simply use SysSingleton.oclSingleton.CurrentUser from the SysUserAuthentication-pattern described here.

The InterestGroup - The Clutter Reducer

What differentiates an InterestGroup from an AccessGroup: The InterestGroup is a softer sibling to the AccessGroup. The AccessGroup is used to control if Access is granted - and this has precedence. The InterestGroup is evaluated after AccessGroups and controls if we should bother to show the tagged action to the user or not. In a large system, the left-side menu can be filled with Class-Actions and ViewModel-Actions; a user from the SalesDepartment may not be interested in actions leading to views or having functionality specific to the Supply department - or vice versa.

To avoid clutter and confusing options, you can tag your users, or have your users tag themselves in a way that you pick up on in an interestgroup. This way, users can reduce clutter of left-side menu themselves. If the action is Visible=true for any InterestGroup that tags the action - the action will be visible - but only if any AccessGroups on the action also agree that it should be visible.

Since the whole point of an InterestGroup is to reduce clutter, the InterestGroup only offers the VisibleExpression - whether tagged actions should show or not.

A particular user may be interested in both Sales and Supply and as such, the user should get Visible=true for both these InterestGroups - and will thus show actions tagged with any of these groups.

A particular action may always be interesting to both Sales and Supply departments and as such, it can be tagged with both InterestGroups - or no InterestGroup. Until you introduce a third group, for example, the Quality-department, that will be the same. Having no groups or all groups tagged on an action will be equivalent if all users get Visible=true from at least one InterestGroup.

Global Apply of Given AccessGroup(s)

A setting RuntimeDefaultOnViews has been added to AccessGroups. If this is true, all views that DO NOT HAVE ANY AccessGroups designed will be assigned these. This offers a way to make sure the new views reach a minimum requirement like maybe "IsLoggedIn" - and you will sleep a bit better at night:

2024-02-09 16h11 28.png

The View-Enable expression - Considerable Complexity Reduced to Almost Nothing

The View-Enable expression has been available on the AccessGroups for some time - but it was a bit clumsy (up till now) as it knocked out all fields on the tagged View when evaluated to Enable=false.

This was good for some use-cases, like protecting strict data entry forms - but bad in many cases since many views are not 100% data capture. Most views make use of some local variables - or maybe they change something transient - like an object of a Class marked Persistent=false. And in these cases, we really want the user to be able to change the local variables - but not allowing them to change anything that will need a save to the database (anything marked being persistent=true as is default on classes, attributes and associations).

A common example is a Seeker. The Seeker may have a few actions on it to things you want to restrict - maybe a CreateNew-action. At the same time, you have actions that you want to allow - like search. You also want the user to be able to enter a search criteria in the search box - and maybe set some other search filters. The one separating thing between the "Don't allow this" and "Allow this" is (feel free to challenge this bold statement) that the "Allow this" group of actions and edits are all Transient (they do not change persistent data) - and the "Don't allow this" group DOES change persistent data. Please take a moment to think about this axiom.

  • Is this true for most cases?
  • Are there cases when it is not true?
  • If it is true very often, would you benefit from a platform that could figure this out this on its own?

How can we statically figure out if an expression will affect persistent data or not?

How can we statically figure out if an expression will affect persistent data or not? This is the question we wanted to find an answer to and that we deemed important enough - because if we could, the View-Enable expression of the AccessGroups would go from - "Yes, it works and locks or opens everything" to "YES, it can read my mind and lets the user do benign things but stops the user from doing anything that risks permanently changing data".

Long story short: We solved it! For OCL-expressions, we check if the resulting element is part of the model and if it is persistent. If it is, we lock the expression if View-Enable evaluates to false. For Action-Expressions, the story is a bit more complex; we deem Action-Expressions to affect persistent data if:

  1. It uses one of these operators: Create, Delete and if so, that Class is Persistent
  2. It includes a class member that is Persistent on the left side of any of these operators: ":=" , "add" , "insertat" , "clear" , "removeat", "remove"
  3. It uses a Method that is a Persistent class and is not marked with IsQuery

The above distinction between AffectingPersistentData and not is only possible because we are in a managed environment when it comes to data management. If you would have implemented your system in most other modern object oriented languages, the lack of available meta information on what is truly persistent, the lack of knowledge on what an association is and if it is persistent, the lack of knowing what properties belong to and if they are persistent would make this kind of static analysis very much harder. Luckily, you have chosen wisely and managed your Gist separate from your Modernity emoticon-smile.

2024-02-06: A tagged value WillEffectPersistedDataOverrideValue has been introduced to allow override of the logic that deduce if an expression effects persistent data or not. The TaggedValue has effect on Column,ContextAction(ViewModelAction) and ClassAction. 2024-02-07: A per viewmodel ReadOnly mode

This page was edited 12 days ago on 10/29/2024. What links here