NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Editing User Passwords / Privileges via API

Solved!
Go to solution

 

I'm working with the User API in a custom user manager utility to perform all the basic operations of a fixture admin (create, edit, delete). 

Mostly the tool is very straight forward but I'm looking to see if anyone else has encountered two items that are irking me that exist as features of the Engine.EditUserDialog() method.

 

When editing an existing user via TS's existing method, you can change the password & privileges without headaches.  However when using the raw API neither of these simple chores seems trivial.

 

(1) When I "get" User.Password, the string is (naturally) scrambled to prevent casual snooping.  In my dialog box I display it as *** anyway, so no harm done. However, TS doesn't seem to know whether the string it is being fed on the "set" side of the equation is already scrambled, and based on my testing, seems to be scrambling it twice if no edits are being made to that field.  Is there some way of  setting User.Password that will _not_ force a 'scramble'?  (in event that I want to set the password to be the value it already was?)

  

Normally I would simply omit the 'set' action if I didn't want to change the value. But due to other circumstances (see below), I don't have that luxury this time.

 

(2) in the API, User.Privileges is a read-only property even for administrators.  Is there a clean work around for this for when an administrator wants to upgrade/downgrade a user's access?  It seems to me that the only feasible thing to do is copy the info out of the old user object, destroy it, and fabricate the new user object with the correct privilege container.  Adjusting the UserGroupList assignments is easy enough, but there is no way to tweak the privileges of an existing user...

 

Curious!

Cheers,
Elaine R.
www.bloomy.com
Message 1 of 12
(6,022 Views)
Solution
Accepted by topic author EMR

Hi Elaine,

 

I think you just need to change the Members for a particular group.

Say you have set a New User Joe Brown as a Technician but later you have to change him to be an Operator.

All you do is remove him from a GroupUser Technician Members and add him to the GroupUser Operator Members. You dont need to resubmit the password.

 

Get a reference to Engine.UserGroup( "Technician" )

with this reference  get an array of the User.Members

Find where the user is in the array and delete that element

close the User.Members reference

Get a reference to Engine.UserGroup( "Operator" )

with this reference  get an array of the User.Members

Add Joe Brown to the Members Array.

close the User.Members reference

 

Joe Brown will  now be an Operator and you dont have to change his details.

 

I noticed that using the User Manager to view the changes I could see that Joe Brown had changed groups and was deleted from one group but wasn't shown in the new group.saving the user changes and logging out and logging in again the changes where now seen.

So maybe you need to Validate that user in the new group.

 

See if this helps

Regards

Ray Farmer

 

 

 

 

 

Message Edited by Ray Farmer on 02-13-2009 09:37 PM
Regards
Ray Farmer
Message 2 of 12
(6,014 Views)

Hi Ray -

 

Thanks for the sanity-check, I figured if anyone'd looked into it before, it'd be you 😉

 

Just changing the Members of a particular GroupList element _does_ seem to be the answer for the permissions/tweaks I wanted in my tool.  I was going the extra step and trying to copy the privilege container over out of general fussiness, but it doesn't seem necessary!  I suppose it would be a bit messier if a user had custom privileges set that had to be searched for/carried through as well, but thankfully my customer isn't doing that. 

 

It's interesting that you were having problems seeing the user changes. I was just doing the classic incChangeCount, and save APIs and the screen seemed to refresh just fine after I cleared the 'do you want to reload file' dialog. Perhaps we're on different versions. I'll keep an eye out for that phenomena.

 

Sadly I still need the ability to conditionally change passwords as a separate task, so I'll continue to work around that minor annoyance, but yes, half the problem is simplified nicely. 

 

Cheers,
Elaine R.
www.bloomy.com
0 Kudos
Message 3 of 12
(5,996 Views)

Hi Elaine,

 

Reading your response I realized I wasn't doing the incChangeCount. Smiley Sad

 

Regards

Ray 

 

Regards
Ray Farmer
0 Kudos
Message 4 of 12
(5,994 Views)

Hi Elaine,

 

Why do you need to copy a user?  You can check to see if a user has entered the same password as they already have by using the ValidatePassword method on that user.  You can also check to see if the encrypted version of the password hasn't changed and just not set the password if that is the case.  I know you said that you couldn't do that, but why is that?

Eric B.
National Instruments
0 Kudos
Message 5 of 12
(5,981 Views)

Hi Eric -

 

It looks as though I was making my life unnecessarily complicated by trying to work with the read-only User.Privilege property.  If editing the UserGroupList is all it takes to adjust a user's abilities, then creating/destroying the user object is no longer required.  This means I can now do a string compare on the existing password and choose whether or not to write it.

 

In general however, I'm curious to know why NI opted to do the 'scramble' on writing User.Password, rather than on reading User.Password.  That would solve the 'don't scramble an already scrambled password' problem.  Was it just an extra measure of safety for the system? Or does the validation method only work on scrambled strings? I'm just curious. So long as when the property is retrieved it is not readable, I would imagine it there would be benefits to having the option to set the buffer without having it auto scramble.

Cheers,
Elaine R.
www.bloomy.com
0 Kudos
Message 6 of 12
(5,976 Views)

Use the PropertyObject API. I tried a statement step with the following and it set the password without scrambling:

 

RunState.Engine.GetUser("User").AsPropertyObject().SetValString("Password", 0, "Test")

Message 7 of 12
(5,974 Views)

That would do it.  Thankyou James.  I was so caught up on User.Password that I didn't think to try the generic class approach.

 

 

Cheers,
Elaine R.
www.bloomy.com
0 Kudos
Message 8 of 12
(5,956 Views)

I've got a similar issue in that I want to add a newly created user to a group - I tried what Ray said above, but can't get it to work (apparently the reference to the new user is the wrong type when I try to add it to the group).  I've attached the VI that I'm using - anyone got any ideas why the method with the red border isn't happy with the newValue that I'm passing in?





Copyright © 2004-2023 Christopher G. Relf. Some Rights Reserved. This posting is licensed under a Creative Commons Attribution 2.5 License.
0 Kudos
Message 9 of 12
(5,340 Views)

hi crelf -

 

if you dig through the documentation on this one you'll find that members of groups are actually PropertyObjects of Strings (not users, which you'd expect).  The string is simply the user's name, but I think it needs to be a unique/new propertyobject (or a clone) you can't just feed in user.name.aspropertyobject().... or you'll get some nasty error about the object already having a parent...

 

 

so the order of operation is

(1) get usergroup("Operator")

(2) get members object

(3) make a brand new property object of type string.  

            i.e newstring = Engine.NewPropertyObject(PropValTyle_String, false, "", 0)

(4) set string's value to user name... 

(5) finally do members.SetPropertyObjectByOffset(...) the way you're currently trying.

 

It's a bit of a trick!  never-the-less creating a brand new property object of type string is a useful trick to know because it's also useful with programatically setting up executions and such...

 

I hope this helps!

 

--Elaine R.

Cheers,
Elaine R.
www.bloomy.com
Message 10 of 12
(5,318 Views)