# Client permissions

**URL:** <https://forum.inductiveautomation.com/t/client-permissions/16509>\
**Category:** Ignition\
**Created:** [January 8, 2018, 12:10pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509 "2018-01-08T12:10:00Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Claus\_Nielsen](https://avatars.discourse-cdn.com/v4/letter/c/77aa72/32.png) [@Claus\_Nielsen](https://forum.inductiveautomation.com/u/Claus_Nielsen)\
**Post date:** [January 8, 2018, 12:10pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/1 "2018-01-08T12:10:00Z")

</div>

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.

```auto
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

---

<div class="post-metadata">

**Author:** ![Claus\_Nielsen](https://avatars.discourse-cdn.com/v4/letter/c/77aa72/32.png) [@Claus\_Nielsen](https://forum.inductiveautomation.com/u/Claus_Nielsen)\
**Post date:** [January 8, 2018, 9:31pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/2 "2018-01-08T21:31:55Z")

</div>

No one?

Would really appreciate it.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 9, 2018, 2:48am UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/3 "2018-01-09T02:48:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Claus\_Nielsen](https://avatars.discourse-cdn.com/v4/letter/c/77aa72/32.png) [@Claus\_Nielsen](https://forum.inductiveautomation.com/u/Claus_Nielsen)\
**Post date:** [January 9, 2018, 7:07am UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/4 "2018-01-09T07:07:33Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 9, 2018, 1:07pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/5 "2018-01-09T13:07:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Claus\_Nielsen](https://avatars.discourse-cdn.com/v4/letter/c/77aa72/32.png) [@Claus\_Nielsen](https://forum.inductiveautomation.com/u/Claus_Nielsen)\
**Post date:** [January 9, 2018, 1:24pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/6 "2018-01-09T13:24:47Z")

</div>

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.

```auto
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

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 9, 2018, 1:57pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/7 "2018-01-09T13:57:35Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Claus\_Nielsen](https://avatars.discourse-cdn.com/v4/letter/c/77aa72/32.png) [@Claus\_Nielsen](https://forum.inductiveautomation.com/u/Claus_Nielsen)\
**Post date:** [January 9, 2018, 2:10pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/8 "2018-01-09T14:10:45Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Claus\_Nielsen](https://avatars.discourse-cdn.com/v4/letter/c/77aa72/32.png) [@Claus\_Nielsen](https://forum.inductiveautomation.com/u/Claus_Nielsen)\
**Post date:** [January 9, 2018, 2:14pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/9 "2018-01-09T14:14:34Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 9, 2018, 2:23pm UTC](https://forum.inductiveautomation.com/t/client-permissions/16509/10 "2018-01-09T14:23:12Z")

</div>

> [@Claus\_Nielsen](#):
>
> 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.
