Perspective: Error using hasRole(...) with only 1 argument

v8.0.2

I’m sure this is a bug, as the function description says that the 2nd 2 arguments are optional, and this works in Vision:

Since this is Perspective, it’s running in the gateway scope, which does require all the args.

Hmm, I’ve added these from the system tags but now I’m getting another error:

Hmm. Best I can tell that error would happen if the user source by that name was not found.

[System]Client tags also don’t exist in Perspective, since you’re on the gateway scope. You would use the appropriate session properties, instead - but hasRole probably isn’t the function you should be using at all in Perspective.

How would you disable a button in Perspective if a user doesn’t have a particular role? Is this where you’d use security levels and the identity providers? Which on that note, I can’t seem to add any security levels into my identity providers’ security levels. I can add them into the general Security Levels section, but not when I click on the Identity provider and click security levels from there. I just get:

What you could do is use a property binding to session.props.auth.user.roles and then a simple script transform to check whether the role your user has is in the list of roles:

if value is not None:
	return 'Operator' in value
return False

A similar binding/script could probably also make use of the session.props.auth.securityLevels session property.

2 Likes

There’s also the new isAuthorized expression/scripting function(s):
https://docs.inductiveautomation.com/display/DOC80/isAuthorized

I don’t think that can check for assigned roles though; correct me if I’m wrong, but it just checks that a user has been authenticated to an IP

1 Like

I’m not 100% sure, but i think the security levels suddenly appeared for configuration after i used security levels for a view.
**I’m not sure that ‘use before configure’ is really intended by IA, but it worked for me.

Ok, i have to correct myself. The workflow for using Security Levels has two steps:

First, you have to create a custom level under ‘Security Levels’:
levels
The rules for this levels can then be configured in the Identity Provider:

According to the docs, it should also be possible to add role names direct under Authenticated/Roles without the need for special rules.

Something like this worked for me:

if({session.props.auth.user.userName} = null, false, if(hasRole(‘Operator’,{session.props.auth.user.userName}, ‘default’), true, false))

However, I still can’t figure out how to reference the user source in the session properties. If the source changed from default it would break…

Well, the format goes: hasRole(role[, username][, usersource]).

So, what should be valid is:
hasRole(“Operator”, {session.props.auth.user.userName}, {session.props.auth.idp})

When put into a Label expression as:
“Operator” + " " + {session.props.auth.user.userName} + " " + {session.props.auth.idp}
it returns:
“Operator admin default” (or what ever your current is and whatever your current is).

However, the example is actually written:
// This is an example using a username and userSource:
hasRole(“Administrator”, “bob”, “default”)

Notice how the ‘user’ and ‘usersource’ both have the double quotes?

In SESSION CUSTOM create 2 Custom Properties with the expression binding
• SessionUser : ‘"’ + {session.props.auth.user.userName} + ‘"’ : gives–> “admin”
• SessionIdp : ‘"’ + {session.props.auth.idp} + ‘"’ : gives–> “default”
Notice that there is ‘single quote’ ‘double quote’ ‘single quote’ which puts the double quotes into the value.
Now put in:
hasRole(“Operator”, {session.custom.SessionUser}, {session.custom.SessionIdp})

Sigh. This should have worked.
It should have evaluated, but instead I got the " ! Error_ExpressionEval " again as well. :frowning:

Why are you forcing the double quotes?
The example only has double quotes to display that the value is a String.

Because the code Snippet in the Ignition 8 User Manual under “hasRole” shows the user and idp with quotes.
Either way, we don’t get “true” or “false”, as in your VISION example. In Perspective, we only get “Error_ExpressionEval” in the results.

As far as I can tell, in Perspective the ‘hasRole’ function does not work, and it both should and needs to.
By the way, I’m on version 8.0.13.

How did you add the picture? I would put that in if I knew how.
However, this gives me an idea to try…

I try to avoid double quotes if I can help it, but your original ‘shoulda worked’ works for me:

hasRole('Operator', {session.props.auth.user.userName}, {session.props.auth.idp})

This will work, but what is most likely causing your Expression Eval Error is that your Perspective project isn’t requiring login, so session.props.auth is either an empty object or doesn’t exist when you first start the session. This is the correct expression syntax (you should still use isAuthorized), but you probably want to wrap it in the try function evaluating to false to catch the case when no user is present. OR, make your Perspective project require login.

In the post controls, there is an upload option.
Screen Shot 2020-09-21 at 8.47.42AM

If you hover over the warning in the expression dialog, what does the error say? Given your example, I’m betting it is something about an unexpected character.

My Prospective project already does require login. Has from the beginning, long before I tried to use ‘hasRole’.

However, everyone, I figured out how to get it to work. The third parameter, for Perspective, is not the ‘idp’ that is for the perspective project, but you must use the ‘User, Roles’ that your ‘Identity Provider’ is pointing to. For some unknown reason, that info is not being passed thru.

I learned more about the error “Error_ExpressionEval”: The error description, which finally popped up when pointing to the “!” is
• "Error_ExpressionEval(“Error retrieving users from gateway.”)

The problem with all these examples is that both the ‘Identity Provider’ and the ‘Users, Roles’ name are both “default”. So if you have names defined per project (multiple projects on server for SYSTEM INTEGRTORS and PROGRAMMERS), and the two names are not identical (say for example ‘Identity Provider’ name of ‘CompanyIdentity’ and ‘User, Roles’ name of ‘CompanyUsers’), then that is where the confusion in the ‘hasRole’ comes from. The help menu item needs to be updated.
Also, a way to have the Perspective session ‘Users, Roles’ name needs to be added along with the ‘idp’ parameter. I don’t know yet how to make a custom that can drill down into the Identity Provider settings to get that info.

To Clarify what I’ve said, as it sounds a little confusing even to me. Example:

Identity Provider name of “CompanyIdentity”. The setting ‘User Roles *’ points to “CompanyUsers”
User, Roles name of “CompanyUsers”.

In this situation, the proper Perspective format is:
hasRole(“Operator”, {session.props.auth.user.userName}, “CompanyUsers”)

Screen capture to clipboard (eg printscreen, snipping tool, greenshot, etc) then simply paste it into the forum post. Ahh the benefits of using a modern forum backbone :slightly_smiling_face:

Paste it to here? Really? That easy? Wish the other forum I post on was that easy. There you have to save the picture to a hosting service (like OneDrive) and then go thru hoops to get an embed path, etc.

Thanks. :slight_smile: