Client permissions

Hello all,

Working on a little project where I need to start a transaction on a database, and up until now I have just used named queries to run SQL commands. Starting a transaction is not possible using named queries and the startTransaction function requires client permissions to be enabled.
My question is, instead of allowing all user roles legacy database access (I am aware that the client roles can be restricted), is there a way to run a function (any function really) using another users credentials without switching user?

I thought about making a decorator, just can’t figure out how to run the function with different credentials.

def runAsUser(username, password):

	"""
		Description: Decorator for running a function using an alternative set of client permissions
			e.g.   @runAsUser('Username', 'Password')
			e.g.2. runAsUser('Username', 'Password')(IRequireSpecialCredentialsFunction)(*args, **kwargs)
	"""

	def decorator(function):
		def wrapper(*args, **kwargs):
			
			print "Has legacy database access: %s" % ('LegacyDatabaseAcces' in system.security.getUserRoles(username, password))
			
			# return RUN_WITH_CREDENTIALS(username, password, function(*args, **kwargs))
					
		return wrapper
	return decorator

Thanks in advance

No one?

Would really appreciate it.

You cannot. The active user credentials apply to all traffic from client to gateway. Consider using system.util.sendMessage() to pass requests for privileged operations to the gateway, and to return the results.

Thank you for your reply.

Can’t see how using the sendMessage/sendRequest functions should make any difference though as these still require a preconfigured set of roles (or allow Any). Getting the same result from just enabling legacy database access without restrictions, or am I missing something?

Allowing sendMessage is much lower risk, as the gateway will only execute code supplied by the designer as the gateway’s message handler. Clients that can submit actual queries could theoretically be hacked to submit arbitrary queries – a message handler that performs a limited set of privileged tasks is not so vulnerable. Note – I’m not suggesting you send a SQL query in a message – that would defeat the entire purpose.

I tried the approach, ran into some issues though.
What I was trying to do was making a decorator that would run any function on the gateway. This is just not possible as non-builtin functions aren’t serializable. Python is new to me and after a few hours of trying, I decided to drop it.
That said, it would be real nice to be able to run on the gateway only having to decorate the function definition.

The following code generates a NotSerializableError when function is any non-builin function.

def runOnGateway():

	"""
		Description: Decorator for running a function on the gateway
			e.g.   @runOnGateway(')
			e.g.2. runOnGateway()(IRunOnGatewayFunction)(*args, **kwargs)
	"""

	def decorator(function):
		def wrapper(*args, **kwargs):

			return system.util.sendRequest(project = system.util.getProjectName(),
						messageHandler = "runFunction",
						payload = {'function':function, 'args':args, 'kwargs'=kwargs})

					
		return wrapper
	return decorator

Don’t go there. Having client-supplied code run on the gateway is precisely the security hole these client permissions are trying to close. Define your code in a script module that a gateway message handler can run. Supply non-code arguments to that code in the sendMessage dictionary of parameters.

1 Like

Well, this was just a proof of concept test. My plan was to pass the current user in the payload as well, then filter in the gateway script.

I do agree though, this might not be the optimal way and I did drop it. Would rather have a way to run the function directly on the client using another users credentials.

Yeah, would be convenient. But would entirely defeat the security limits, as the desired user to run as is supplied by the client. The whole point is to not trust what the client supplies.

2 Likes