Tag security insufficient security role permission feedback

Hi,

I’m having an issue with not getting a feedback to the user when a write attempt is made without sufficient permission.

The setup is a very simple. I have 2 buttons, one that sets 1 to a boolean tag and one that sets 0 to the tag. The boolean tag has its write security set so only users with Manager role can write to it.

The buttons work correctly. When a user without Manager role tries to click on the buttons, the boolean tag value doesn’t change, but there is no feedback to the user to let them know the action was denied due to security.

Thanks,
Ali

What result codes are you getting back from your call to system.tag.writeBlocking() ?

{ Hint: you’ll have to pop up a notice yourself. }

Hi,

The event script on mouse click is:

self.view.params.Start=1

The Start parameter is bound to the start tag, which has its write security set. When a user with the correct write access security presses the button, the tag value changes. If the user does not have access, nothing happens and there is no feedback to the user to let them know.

There is also a numeric entry field tied to an tag with security. When a user without write access tries to change the value, the system shows this error message:

Capture

Shouldn’t the behavior of the system be consistent among components? According to the documentation, it is preferable to set the security at the tag level rather than component level.

Thanks,
Ali

Hi Ali,

I've had similar frustrations with this, but I think I can help make sense of it. The way I view it, a task like using a numeric input or changing a property value has a very concrete goal - change the value. If something prevents you from doing so, an exception is thrown.

Scripting functions are very much the opposite - ideally they throw an exception only as a last resort. There are plenty of conceivable reasons you might want a script continue even if writeBlocking does not succeed. The function was built with this in mind. In the docs, you'll see it returns a list of QualityCodes. It's up to us to interpret these codes within our script and throw an exception if needed.

Single tag
If you're writing to a single tag*, there's a simple workaround. Simply use a bidirectional binding in your template parameter, perspective param, etc and change that in your script, rather than using writeBlocking().
(*If you're hardcoding a button or something, this approach can also be used to write multiple tags. It just gets more cumbersome as the number of tags increases.)

# Vision (e.g. template or custom property logic)
write_value = event.source.parent.write_value
event.source.parent.value = write_value

# Perspective
write_value = self.custom.write_value
self.custom.value = write_value

## In either context, the value parameter must be bi-directionally bound to a tag ##

Multiple tags
Here's an example script that will provide an error when writing multiple tags simultaneously. This is particularly useful for templates that are configured to write to a dynamic number of tags.

write_paths = ['tag/path/1', 'tag/path/2']
write_values = [value_1, value_2]
codes = system.tag.writeBlocking(write_paths, write_values)

# check Quality Codes returned from writeBlocking
# if not good, store diagnostic message (if any) and tag path
diags = []
bad_paths = []
for i, code in enumerate(codes):
if code.isNotGood():
	diag = code.getDiagnosticMessage()
	diags.append(diag)
	bad_path = write_paths[i]
	bad_paths.append(bad_path)

# if any writes were not good, display an error to the user
if len(diags):
	msg = '<HTML>Error writing to the following tags:<BR><BR>'
	for i, diag in enumerate(diags):
		system.gui.messageBox(diag)
		msg = ''.join([
			msg,
			'Tag: ', bad_paths[i], '<BR>', 
			'Reason: ', str(diag), '<BR><BR>'
		])
	system.gui.errorBox(msg)

Note that as written, this script will not stop at the errorBox - errorBox is purely visual. If you need the script to actually stop, you'll want to include exit() after your error checking.

As a side note for the devs, it would be great if writeBlocking had a flag that caused an exception when it returns anything except Good. It would more or less eliminate my need for the code above.

(Edited for simplicity when writing to a single tag)