Vision security roles

In Vision, what would be the recommended way of achieving the following?

I have 4 user roles: Administrator, Engineer, Technician, and Operator.

Each role has access to different parts of the application but I would like a user (Administrator) to be able to edit which parts of the application each role has access to from within the client.

In previous projects we have dealt with this outside of Ignitions security features, but I was wondering if Ignition is flexible enough to do this?

This is a table that I would like to achieve. The X’s representing checkboxes so an admin can choose which permissions apply to which role.

Is this possible, or is there an alternative route in Vision I can take to achieve the same thing?

Thanks,

Tom

Going to be a lot of scripting and I haven’t done this but this is how I imagine it could go. You will need a databse to keep track of certain things. A mapping database table that keeps track of what you’re picture is - what role has what permission?

Then, all event scripts, button presses, system.nav.openWindows should be within functions.

Then you can make a decorator to check permissions. Here’s an example for Permission1

def requirePermission1(fn):
	"""
	Decorator to make sure user a user has at least Driver_2 role bef doing something.
	"""
	@wraps(fn)
	def wrap(*args, **kwargs):
		username, userSource = [t.value for t in system.tag.readBlocking(['[System]Client/User/Username', '[System]Client/System/UserSource'])]
		user = system.user.getUser(userSource, username)
		# Now you can user.roles to get their roles
        # Query the database, see if they have permission 1
        if allowed:
           return fn(*args, **kwargs)
		else:
			raise ValueError("You must have permission 1 to perform this action.")
	return wrap

Then as long as all your scripts are in the project library, changing the user permissions would just be a UI where the Admin can change the contents of your database table.

The decorator you may want to modify such that it can accept a param for the permission so its only one decorator and you can do something like

@requirePermission(2)
def openSomeWindow():
    system.nav.openWindow('blah')

You can find examples of parameterized decorators around the forum.

If you’re also talking about changing what permissions are needed for a given action well that would reqiure yet another db mapping table and honestly I would not recommend this, it will be a headache.

Alternatively you can make some client tags like Permission1, Permission2 that query from your mapping table a dataset of the roles that have it on a polling rate, and then you can bind via these things. So then the admin changes the mapping table the client tags datasets get updated and then your bindings that would probably be doing a lookup would look at the new dataset.

Having said all this - I still would recommend just using roles strictly with Ignitions built in security. If roles/permissions change - that is reason enough to have to force someone to open up designer to make the change. It’s always easier to use their built-in solutions. If you do any of what I suggest and now you have a bug - it is a bug YOU own.

What about making more specific roles, like Permission1 role, Permission2 role, etc and just giving users multiple roles? Then you can use Ignition’s built in security on components, and the admin could use the User Managment component to actively change these. Would also let you get granular about specific users.

1 Like

I think I agree with your last point. It would be better to make the roles more granular instead of having 3 top level roles. That would allow and admin to change them with the user management control.

Thanks for the assist. We have utilised something like you described in the past and it worked but it was prone to issues.

Thanks

1 Like

Yea I’ve run into projects like this where they basically rolled their own user management system because they didn’t know how to handle things when a user logged out/switchUser and all the screens refreshed.

Probably my biggest pet peeve coming onto existing projects - seeing someone roll their own whatever, when Ignition has a built in way to do it. You’re basically always making the wrong call doing that, and you do not have the development time or QA that IA had when making it so it will also likely not be as good.

1 Like

We've done the client tag route that uses hasRole on the user to check multiple super roles. IE we have a client tag called isMaintenance that is comprised of the maintenance and operator roles and checks if the user has them. The user is assigned to the specific roles in Ignition user manager.Then we can use that tag as part of expressions for enabled etc... That way if we need to stack roles its a bit easier.

2 Likes