Perspective: check permissions before navigating to view

I have a settings view, which requires a Service role to access. I have set up the view permissions, and now if I am not logged in when I try to navigate to that view, it appears very briefly, before being replaced by the “Access Denied” graphic. This isn’t ideal from a user experience point of view.

What I’d like, is for perspective to somehow check whether I have permission to load that view, and if not, prompt me to log in first. If my login succeeds, and the logged in user has permission to access that view, perspective navigates there as intended by the user. If the login fails, or the logged in user doesn’t have permission to access that view, we get some sort of notification.

I can cobble something together with multiple layered buttons that are visible or invisible depending on the roles of the currently logged in user and some popups, but I can’t think of any way to automatically redirect to the requested view once the login is successful. At any rate, it seems like the sort of thing that might have a simpler solution.

Are there any existing features that I might be able to use to get partway toward achieving this functionality? Could I run a script that checks the user roles, and calls either a login function or a navigate function based on the result? Can a script be queued up to run after the login function, and/or dependant on the results of that login function? Is this the sort of feature that could be added in future versions?

I’m not able to see a View which requires Permissions to be in place if I don’t have those permissions, even for a fraction of a second - I’m immediately taken to the Access Denied page. How are you performing the navigation/arriving on the page which you should not be able to see without permissions?

From my experience, if I am in a project (either authenticated or not) and I attempt to navigate to a page which I don not have permissions for, I am immediately sent to the Access Denied page.

I believe there’s an internal ticket to provide a “state” page more like the “you must log in to view this Project” screen when you hit a View which denies access, but if there isn’t I’ll open a Feature request for it.

You can use scripting and expressions for user Roles/Zones/Security Levels, but what would the logic look like? Would you be hard-coding “userX has these permissions, so complete Login”? If so, that leaves you vulnerable when the requirements change.

You could provide the logic on the navigation mechanism (not a great solution if there are multiple avenues for reaching the page in question), by checking the current user’s permissions and if they don’t meet requirements forcing a login.

I'm just using an onClick event on an icon, which navigates to a page, which contains the restricted view. The restricted view pops into view for a split second, then reverts to the Access Denied view.

Great, that's what I'd ultimately prefer to use. Would this feature include the ability to automatically complete the navigation after logging in?

I wasn't envisioning scripting the login, as you say, hard coding that sort of thing seems like a bad idea all round.

My only idea at this stage is putting a transparent button on top of the navigation control that leads to the restricted page. The button triggers a login, and is invisible if the currently logged in user has the correct privileges to access that page. It works, but there are some disadvantages:

  • If there are several ways of navigating to the page I have to implement it everywhere (in my specific application, not a real concern, but I can definitely see that it would be in other applications)
  • Once the login is completed, I have to manually re-trigger the navigation action by clicking on the navigation link again (which is why the auto-completing navigation would be a really useful part of the "you must log in to continue" feature)
  • I've gotten quite accustomed to not having to resort to invisible transparent buttons in Ignition (like I have to repeatedly in FTView, Wonderware, etc), and having to do so now seems a bit of a let down :wink:

Interested to hear any other solutions. Might there be a way to at least remove the need for the transparent button by having the onClick actions check the current user authentication before deciding what further actions to take? e.g.

if hasRole(myRole):
    display page
else:
    display login

(pseudocode, obviously)

Absolutely, as long as you're performing each step within a singular Script Action.

If you have an onCLick event which does navigation to some page with a Navigate Action, then you're bypassing the ability to supply any deterministic logic to your event.

If you need to do apply ANY logic to an Event of any type in Perspective, you should ALWAYS use a Script action. Within that script Action, you have access to every single one fo the regular Perspective Actions, you just need to invoke them with system.perspective.desiredFunction(). Perform your logic here, and you can then determine whether or not the onClick Event performs ANY action at all.

While it would appear that you could supply multiple Actions for each Event, we do not recommend you do so in most cases as each of these Actions is run on its own thread, and they are therefore not executed in order. For example, if you supply a Script Action and a Navigate Action for an onClick Event and that event is triggered, then the navigate action could complete before the script has executed.

1 Like

Great, thanks for the info. I probably should have clarified - I was after a little guidance on which script functions were available here, because last time I checked the documentation for perspective scripting was still just a “coming soon” page. But I’ve just checked again and there’s some detail there now which should get me moving.

Thanks!

Just had the thought - is there any way I could have the script complete the navigation automatically? e.g. is it plausible that I could do something like:

  • Create a shared script which accepts a page to navigate to and a user role to check for
  • Call the shared script from my navigation link
  • If user already has role, just navigate to page
  • If not, trigger a login, then wait for the results of that login
  • After the login is completed, check roles again. If login failed, take no action. If login succeeded but user doesn’t have the right role, display a popup to that effect. If login succeeded and user has right role, navigate to page

Is this sort of thing possible? I can put together most of the script, but I’m just not sure if it’s possible to do things like pause and wait for a login to happen, or to get the results of an attempted login once it does.

Getting the script to “wait” is the hard part. What you should probably try instead is using message handlers to perform a sort of session/Gateway handshake.

  1. Users presses aButton, which sends a message (where the payload includes the user’s roles and a destination Page Configuration path) to the Gateway.
  2. The Gateway checks some logic, then takes an action on the session (open a Popup, or navigate the session).

This methodology removes “waiting” from the equation while still giving you the flexibility to apply any logic you need in smaller chunks.

You’ll want to make sure that the Gateway-origin message handling is using the sessionId from the received message for any targeting of Popups or navigation, but yes, I think you should be able to do what you want.

1 Like

Thanks, I'll have a play with that if time permits. Deadlines are rapidly approaching now, so I'm having to prioritise the nice-to-haves and the essential functionality :slight_smile:

Just noted that as well as the brief display of the page before being sent to the access denied page - if I'm logged in and able to access the page, then log out, the page remains active and I can interact with it, without the correct authorisation. Obviously, as soon as I navigate away from the page, I can't get back, but should this be allowed?

Does the Project have required Permissions, or just the View?

Project Requires Permissions:
As soon as I click Sign Out, I’m taken to the Sign-In Page for the Project.
Additional tabs are likewise taken to the Sign-In Page.

View Requires Permissions, But Project Does Not:
As soon as I click Sign Out, I remain on the same “Page”/url, but I now see Access Denied for the View.
Additional tabs likewise display Access Denied.

In neither case am I able to replicate your behavior where you continue to see the View after logging out, or where you see the View before having signed in. Could you give some more specifics about the Permissions required for the View?

Sorry, realised I had temporarily disabled the view permissions while I worked out a solution and forgot to put them back in. Because I was re-directing to a login page when trying to get to the page, it still looked like the restriction was there, but it wasn’t. Classic PICNIC error :man_facepalming:

2 Likes

The feature being discussed- the ability to give out a direct link to a page normally restricted, then when the user clicks on the link, they go there if they are already logged into a session, or they go to the login if not (then complete the original navigation once logged in)-would seem to me to be a pretty big deal. Or at least it is important to many of the ways that I foresee using Perspective.

Is there any update on this?

Apparently not?

If you’re logged into a Perspective Session for a project (ProjectA), and you click a link for a restricted View, and you
have permission: then you go to the View
Do NOT have permission: then you arrive on a Terminal State Page informing you that you don’t have the required permissions.

If you’re not logged into a Perspective Session for ProjectA and you click the same link, then you arrive on the Terminal State Page informing you that you don’t have the required permissions.

The last remaining use-case is for projects that do not “require” authentication, but which still have View restrictions in place based on user attributes. In this case, authentication is actually implicitly required, as user attributes are not defined until a user has authenticated.