Hello everyone,
I have a question regarding automatic Timer / BPT Execution in relation to predefined User Roles, more specifically whether Timers / BPTs execution threads are treated as regular "Users" or if they have elevated privileges. I tried to look for answers in the forums and in the trainings but didn't find answers to this specific question, my apologies if I missed something.
For example, let's say I define a MyAppUser User Role inside one of my applications, and then I create a handful of Server Actions (e.g. CRUD Create/Update/Delete_MyEntity wrappers) that can only be executed successfully if the user passes a CheckMyAppUserRole() check as part of server-side security validations, such as the following flow:
Now, let's suppose I want to create a Timer / BPT Process automatic action that could hopefully use some of these CRUD wrappers. My questions here would be:
I will be doing a test myself for this sometime soon, but thought I might ask anyway in case these details are already available from a trusted source. Any relevant specifics about how these work behind the scenes would also be appreciated.
Hi Francisco,
Yes, CheckRole will always return False and GetUserId() will return NullIdentifier() in BPT and Timers (and on exposed Rest API's calls by the way).
What you can do is create a Wrapper that does the CheckRole and is called on screens, and you call the action on the BPT. In this way, you can reuse the action.
For instance, let's say the action you want to reuse is CreatePatient. You can create a Wrapper_CreatePatient that includes the role check before calling the CreatePatient action:
The Wrapper_CreatePatient would be call on screens where you have the user context and it makes sense the role checking and on asynchronous processes you call the CreatePatient action.
Hi Francisco Calderón,
CheckRole functions check if the user in session has a given role as well as GetUserId function returns you the user in session. Timers and BPTs run asynchronously so there is no user in session and therefore no check role functions will return you a value.
Timers and BPTs intend to run activities in the background (many times automatically via scheduling in case of timers or triggers in case of BPTs). Why would you want to check if the user has a role in the case when there is no user?
Given the aforementioned, these actions do not apply in the scope of timer or BPT process execution.
I get the point. I agree that I normally wouldn’t want to check for a User Role inside an asynchronous process; however, I am asking in the context of potentially reusing an existing codebase (where the actions already perform these checks) and whether that forces me to define new actions just for the timer/BPT or refactor the existing ones for a cleaner organization.
An example that comes to mind is a Delete_MyEntity action with the CheckRole() that originally was only called from a Screen Action (that maybe does some additional cleanup, auxiliary entity records being deleted, etc.). Now in the future I might want to directly reuse the Delete_MyEntity action for some asynchronous cleanup/purging process inside a scheduled timer/BPT Process. Not sure if this helps understand the intention of my question beyond the expected use of asynchronous processes. The question just came to me mostly out of curiosity, so for practical purposes you could just interpret it as a “what happens if..?” type of question.
So just to make sure I understand everything, for the last thing, does that mean the CheckRole() actions will always return False for those cases (i.e. GetUserId() = NullIdentifier())?
EDIT: Similarly, is there a way to check whether the action is running from a BPT Process / Timer or synchronously from a user session?
Hi, João Marques.
In the proposed solution, both Actions are public and only the wrapper has its access controlled, wright? The timer/BPT calls the non-checked Action and the screen calls the checked (wrapper)?
Thanks for this dscussion. It does make a lot clear.
I will also implement this solution, but want to point out that there can be another solution implemented, by architectural choice:
You can create a "System User" or specific "Timer User" and perform a login in the timer. This way you can use the same role-checked code for both user processes as async system processes. Not sure if i would recommend this solution, as you would have to know in the code which user this is.
Just for the sake of the discussion.