I have an Ignition project where I need to read permissions from a SQL database for a specific user, then access them across several views. The permissions are per user, meaning one user's permissions could be different than another's. More information can be found in this post I previously made: Permissions on custom session properties - #7 by parker.williams
It seems that the custom session properties sometimes disappear. I'm aware this is a known bug, but from my attempts to find a fix in other posts, it doesn't look like it's been solved. It seems to happen completely at random so I'm not sure if I could replicate it for a bug report. Some posts suggested reopening the project within the designer, unfortunately the issue happens both in a browser session and in the designer.
Is there any other way I can store the permissions of the logged in user? Specifically so that I don't have to keep querying the database every time I need to check the user's permissions.
I am using Ignition 8.3.2 on Windows 11 for context.
I would use my Integration Toolkit's sessionVarMap() expression function (value lookup) and the corresponding system.perspective.sessionVarMap() scripting function (value assignment and propagation).
In a shared docked view, binding the session user ID information to one or more view custom properties, and use a property change script to run your permissions calculation. Save that result in the sessionVarMap and use its refresh method to propagate it to any views that have the expression function already running.
I've seen session properties disappear, but don't recall seeing the bindings for those disappear. Typically, the binding will execute and recreate the prop at runtime. Also, bindings are more likely to 'disappear' when they are set to private (there's a chance that you are trying to access a property by executing logic in a context that cannot access those properties).
I'd strongly recommend you find a way to properly authenticate a user at the Identity Provider level. Else, there are too many places that you'll be adding unnecessary logic to your workflow in order to permit & restrict access.
Have you tried to follow: Database Authentication | Ignition User Manual ?
This is sort of what I am already doing. I have an Identity Provider setup purely to authenticate the user using the database, and after the user logs in, I have a script that executes that populates the permissions. Below is code pulled from the post I linked that does this.
from util.auth import get_login_row
from util.const import LOGIN_COLUMNS # a list of column names from the db as strings
username = "testuser"
data = get_login_row(username) # pulls the row (all columns) from the database
user_globals = self.session.custom.userGlobals
for column in LOGIN_COLUMNS:
user_globals[column] = data[column]
I looked into using the Identity Provider to store permissions retrieved from a SQL query, but based on the way the database is setup, it's going to be a headache. The developer before me stored permissions as "Yes" and "No" rather than a boolean.
I'll try using a binding.
I think the binding might be the way to go. If I remember correctly, there is a scripting function that I can call to refresh the binding. I could have that executed after the user logs in as well. I think the reason behind my issue is that when the userGlobals object disappears, my script errors because it can't access it. I don't think I ever had it create that object if it's missing.
Thanks for your help!
I urge you to add the requirement to return roles at the Identity Provider step, at login, not after. Without roles maintained at the Identity Provider level, you're likely to multiply your efforts to develop a secure app, and additional headaches to maintain it. You're likely to overlook someone's ability to write to specific tags, access projects, execute named queries, etc.
With the Database Authentication, I believe you are able to use Manual Mode in order to configure the exact queries used for returning user roles. I assume you've already developed these queries (within your get_login_row function), perhaps only a slight tweak will be necessary. However, this option would require (I think) that the user's passwords are stored in the database (encrypted). If I understand your workflow correctly, this appears to be the case. If not, you might need to pivot...
Within your existing Identity Provider, there is a section under User Attributes called Roles, you should be able to customize this field in your existing IdP via an expression which calls your existing script. If your script can be tweaked to return the results in a (complicated) SQL query, then this is an unnecessary step, and you should focus on a User's Roles Query within the Manual Mode of DB Auth.
Are you able to share the table schema for the user database (perhaps include a sample row with column headers)? Also, include specifics of your get_login_row function?