Perspective Inactive Logout for specific Roles

I'm trying to figure out a way to get Inactivity Logout working but only for specific roles

For example, on our current system, there is some information you can see even when not logged, in.
To Operator equipment you just need to be authenticated
but to do certain things you need the Administrator Role

Someone with an Operator Role will be logged in most of the time, we don't want this auto logging out.
However if someone with Administrator privileges logs in, and then walks away forgetting to logout, we want them to be logged out after X minutes of inactivity.

I've looked into a few ways of doing this

  • Project Properties, has no way to configure auto logout per Role
  • Trying to access lastActivity on a timer triggered gateway script by looping through the open sessions. It appears the lastActivity info isn't returned from the system.perspective.getSessionInfo() function, and I couldn't figure out any info returned through this that I could use
  • I came across these posts about using a propertyChange script on the lastActivity session property. I got part of this working, but not fully.
    • I can't actually seem to get the logout to work. I have it triggering something in the log if it thinks it should be logging out, as well as logging the inactive time to make sure my regex and calculations are correct
    • Below is the on change script set to auto logout after 10 seconds of inactivity. I can see the log events when it thinks it should logout but it never logs out.
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
	from threading import Timer
	
	def runThisLater(session, prev_time):
		logger = system.util.getLogger("Auto Logout Inner")
		curr_time = system.tag.readBlocking(['[System]Gateway/CurrentDateTime'])
		logger.info("{}".format(curr_time))
		
		import re
		unix_ts_regex = '\(([0-9]+)\)'
		try:
			prev_time = int(re.search(unix_ts_regex, str(prev_time)).group(1))
			logger.info("{}".format(prev_time))
			cur_time = int(re.search(unix_ts_regex, str(curr_time)).group(1))
			logger.info("{}".format(cur_time))
			
			inac_time = (cur_time - prev_time) / 1000
			logger.info(str(inac_time))
			if inac_time > 10:
				logger.info("Should be trying to logout now: {}".format(self.session.info["id"]))
				system.perspective.logout(self.session.info["id"], self.session.page.id, "message")
		except:
			logger.error("Unable to properly determine activity time")
	
	Timer(15.0, runThisLater, [self.session, currentValue]).start()

Anyone having any clue what I'm doing wrong...I feel like I'm so close...but it's just not quite working

This is what I use in my session custom props. Apologies for the format...

"propConfig": {
    "custom.security.autoLogout.enabled": {
      "binding": {
        "config": {
          "expression": "{this.props.auth.user.userName} !\u003d None \u0026\u0026\r\nif(tostr({this.custom.security.client.info}) !\u003d \u0027{}\u0027\r\n\t,indexof({this.custom.security.client.info.AutoLogoutDisableUserNames}, {this.props.auth.user.userName}) \u003d -1\r\n\t,True\r\n)"
        },
        "type": "expr"
      }
    },
    "custom.security.autoLogout.inactiveTime": {
      "binding": {
        "config": {
          "expression": "if({this.props.lastActivity} !\u003d None\r\n\t,secondsBetween({this.props.lastActivity}, now(5000))\r\n\t,-1\r\n)"
        },
        "type": "expr"
      }
    },
    "custom.security.autoLogout.logoutUserTrigger": {
      "binding": {
        "config": {
          "expression": "if({this.custom.security.autoLogout.enabled}\r\n\t,{this.custom.security.autoLogout.logoutTimePresetSeconds} - {this.custom.security.autoLogout.inactiveTime} \u003c\u003d 0 \r\n\t,False\r\n)"
        },
        "type": "expr"
      },
      "onChange": {
        "enabled": null,
        "script": "\tid \u003d self.props.id\n\tsystem.perspective.sendMessage(messageType\u003d\u0027logout\u0027, sessionId\u003did, scope\u003d\u0027session\u0027)"
      }
    },
    "custom.security.autoLogout.remainingTime": {
      "binding": {
        "config": {
          "expression": "if({this.custom.security.autoLogout.enabled}\r\n\t,max({this.custom.security.autoLogout.logoutTimePresetSeconds} - {this.custom.security.autoLogout.inactiveTime}, 0)\r\n\t,-1\r\n)"
        },
        "type": "expr"
      }
    }

and in my header:

"messageHandlers": [
        {
          "messageType": "logout",
          "pageScope": false,
          "script": "\t# called by session.custom.security.autoLogout.logoutUserTrigger\n\tsystem.perspective.logout()",
          "sessionScope": true,
          "viewScope": false
        }
      ]

I could probably do it without the message... not sure why I went that route. Maybe I couldn't work out how to log a session out, and system.perspective may not exist in the session's scope?

2 Likes

Hmm, I've taken a quick glance at what you have put, it's an interesting way to try and go about it.

I'm being pulled onto some other projects for a week or so, so I'll have to take a closer look and try my hand at it later.

Thanks.

And if anyone else has some other thoughts or ideas in the mean time, let me know, I can give them all a try and see what works best.