Hello,

I'm very new to Outsystems so sorry if this has been asked before. I'm trying to show or hide a link based on if the current user is in the Admin role, which I have defined, and added a user to. I can see the action in Logic > Roles > Admin > CheckAdminRole but I cannot use it.

In an expression I see the error "Unknown object 'CheckAdminRole' in expression". I also cannot drag CheckAdminRole to an action in my screen or block. When I try it shows a little "no symbol" (red circle with a line through it). I've watched the Master Class on Security course and it shows me what to do but when I try to do it Outsystems won't let me. Is this a limitation of the free version?

Thanks,

Jim

....

Forgot to mention, I do see the Admin role listed as a check box in the screen properties, so it seems to be working somewhat. I just can't figure out how to call CheckAdminRole.

Hi James,

If you want to hide or show a link based on the role, you can simply put the condition by dragging checkAdminRole() on link's visible property. 

You also find this on Screen level as well. If you want only authorize users to view your page, You can simply mark checkbox selected. 

https://www.outsystems.com/help/ServiceStudio/9.1/index.htm#t=Handling_security%2FUse_Roles.htm


Sachin

Sachin Mahawar wrote:

Hi James,

If you want to hide or show a link based on the role, you can simply put the condition by dragging checkAdminRole() on link's visible property. 

You also find this on Screen level as well. If you want only authorize users to view your page, You can simply mark checkbox selected. 

https://www.outsystems.com/help/ServiceStudio/9.1/index.htm#t=Handling_security%2FUse_Roles.htm


Sachin


Thanks,

My If Condition window looks like this:

Only the GetUserId() function is available. 

My Logic tab looks like this:

So the role seems to exist.

When I try to drag CheckAdminRole to an action I see this:

So the role is defined I just can't use it. Am I missing something obvious?


Also I tried this for an expression, still no luck:


Sorry, one more edit.

I tried to edit the expression on the link Visible property as you suggested, and I got the same error "Unknown function 'CheckAdminRole' in expression".

Hello James.

First thing: Did you create the role? If not, you need first create the role. Go to the Logic layer and add a role (and change it to Admin, like you are trying to use.

If you already create it, you are trying to use it in a different module than that you create the role.
In this case, set the role to be "Public", publish the module, than go to the module where you are trying to use it, go to Manage Dependencies (the plugin icon in the tool bar), select the module where you create it and than select the role).

Now you can use it in the module. :)

Cheers,
Eduardo Jauch

Solution

Sorry,

You put your comment before I finish mine.
I'm seeing you are in a Mobile.

In Mobile, the Check...Role actions work only in Server Actions. 

Solution

You can take a look in this post to see how to work with Roles in Mobile :)

Eduardo Jauch wrote:

Sorry,

You put your comment before I finish mine.
I'm seeing you are in a Mobile.

In Mobile, the Check...Role actions work only in Server Actions. 


That was it. Here's what I did, I wonder if it's the right way. I created a Server Action called AdminCheck where I call the CheckAdminRole function and output the result. Then in the menu block I added a Data Action that executes AdminCheck and sets it's output to the result. Then my If Condition uses the output from the Data Action. Seems a little convoluted, but it works. Thanks!

-Jim

Hi James,

It is easier using JavaScript.

Add a JavaScript whenever you want to check a role, with the following syntax:

Than you can use the Output (IsManager, or any other name), that will be True if the user has the role, and False otherwise.

You can use this on ClientActions :)

Cheers,
Eduardo Jauch

Eduardo Jauch wrote:

Hi James,

It is easier using JavaScript.

Add a JavaScript whenever you want to check a role, with the following syntax:

Than you can use the Output (IsManager, or any other name), that will be True if the user has the role, and False otherwise.

You can use this on ClientActions :)

Cheers,
Eduardo Jauch

Thanks, I'll try it out.


Hello, this is an old topic but meanwhile we have Reactive Web which has the same "problem". My question is if this solution used in OnInitialize will not be prone to tampering since this is JS and the browser allows us to edit it at will.

If this is a problem in Reactive, which approach is the best?

Hi Nuno,

This is a very interesting question.

But the reality is that with Traditional Web applications, you also have the same problem. Anything done with JavaScript at the Client Side is not "safe". So, in Traditional, the approach is to validate everything server-side.

This means that even if you use an IF widget with a Check...Role action, that will be evaluated at the server, to show or not a button (that calls a screen action), the user can still work around it in the Browser. The best practice is that at the server Screen Action, you validate if the user making the request has or not the Role.

It is no different for Reactive Applications.

Client-side you use this approach using JS to improve the User Experience, but at the end, when a server action is to be executed or the data is sent to the server, you need to validate if the current user has the roles/right to do it. 

Cheers.


Eduardo Jauch wrote:

Hi Nuno,

This is a very interesting question.

But the reality is that with Traditional Web applications, you also have the same problem. Anything done with JavaScript at the Client Side is not "safe". So, in Traditional, the approach is to validate everything server-side.

This means that even if you use an IF widget with a Check...Role action, that will be evaluated at the server, to show or not a button (that calls a screen action), the user can still work around it in the Browser. The best practice is that at the server Screen Action, you validate if the user making the request has or not the Role.

It is no different for Reactive Applications.

Client-side you use this approach using JS to improve the User Experience, but at the end, when a server action is to be executed or the data is sent to the server, you need to validate if the current user has the roles/right to do it. 

Cheers.



Thanks Eduardo for your speed. My point is that in Traditional we have the Preparation where we can check the permission and redirect to another site manually if we want. In reactive if I do that in OnInitialize, it will complain about using server actions. But if I put the above JS this is client size so it's editable.

I saw an option by doing a "Fetch Data From Other Sources" to do that but this seems a misusage of this feature.

Hi Nuno,

This is true. And the user will probably be able to mess with the page code.

That's why you should fetch data (from server), only if the user can see it. It will not be able to mess with it, as the aggregates run in the server. So, even if he can, somehow, reach a page he shouldn't, he will not be able to fetch data it was not supposed to they to see.

Most of the time, this will not be a problem. But for those that are trying to hack the system, even if they see the page, they don't see the data.

It's a tradeoff. Client-side code provides a more enjoyable user experience, but some security concerns must be addressed in a more explicitly way. 

Cheers

Eduardo Jauch wrote:

Hi Nuno,

This is true. And the user will probably be able to mess with the page code.

That's why you should fetch data (from server), only if the user can see it. It will not be able to mess with it, as the aggregates run in the server. So, even if he can, somehow, reach a page he shouldn't, he will not be able to fetch data it was not supposed to they to see.

Most of the time, this will not be a problem. But for those that are trying to hack the system, even if they see the page, they don't see the data.

It's a tradeoff. Client-side code provides a more enjoyable user experience, but some security concerns must be addressed in a more explicitly way. 

Cheers

The Fetch is not actually fetching an aggregate, it calls a server action of CheckRole and outputs it. That's why I was asking if this was the correct way of doing things.


Hi, 

I would say this is "useless", as the result will be client-side, and client-side a hacker is king.
So, I would not use this approach. 

I would use the normal approach, using Roles client-side for a better UI experience, and validating server-side if the user requesting the data can actually see it.

For a "regular" user, this approach is nice, as the Interface will be much faster and the experience will be nice.
For a "hacker", doesn't matter if he can reach a page or not by messing client-side, because he will not be allowed to see any data he does not have access.

I just put this on display and saw the id in the database


GetUserId() = 6


it comes out:

Unexpected data type by number



But it works well

Canasta Muisca wrote:

I just put this on display and saw the id in the database


GetUserId() = 6


it comes out:

Unexpected data type by number



But it works well


 You need to use

GetUserId() = IntegerToIdentifier(6)