I am currently writing a ASP.Net web application that has a section for out IT department to manage users. One of the things it will do is give a checkbox list of the active directory security groups and email groups a user can be a member of. I was easily able to work out the code needed to add a user to a group when the use is first created. Now I am trying to figure out an efficient way to update the groups when a user changes, for instance the user is part of 5 groups and IT updates them to add a new group and remove them from 2 existing groups.

I have thought about just doing a blanket remove from all the groups then go back and add them back to the selected ones. I have also thought of querying to get a list of all the groups they are in now, doing a compare to a list of the selected groups, calculating out which ones where removed and which where added then doing the appropriate calls. Both these methods do not seem very efficient and potentially process intensive.

What is the more common ways a skilled/experienced developer deals with this kind of situation?

  • Are you using a database? If not, why not? Operations of this kind are the bread and butter of databases. – Robert Harvey Feb 22 '17 at 22:58
  • @RobertHarvey In this case I am not using a DB as this is Active Directory I am interacting with but I can see this coming up with a MS SQL back end as I have to start assign internal roles for the application I am building but I was thinking that would be a different question as it would require a different solution process. – Matthew Verstraete Feb 23 '17 at 13:24
  • The stated question is update server side lists. The stated question does not state update Active Directory. Answers are only as good as the question. – paparazzo Feb 23 '17 at 23:11
  • @Paparazzi Sorry yes the TITLE said server side lists but the question did state active directory, I have updated the title – Matthew Verstraete Feb 24 '17 at 13:29

If it is a List on the server side then not going to make a lot of difference.

Contains is O(n)
Remove is O(n)

Add is O(1) or O(n)
But is if the List does not need to be increase then O(1) and since you just removed it then the List does not need to be increased.

A skilled developer would design business objects that save / produce changes only. You have a scenario where changes from one user could be overwritten by another.


Is performance really an issue? Seems to me that the more important NFR is transaction integrity.

If you gather a list (i.e. make a clone of it in a c# data structure) and then do the update afterward, there is a chance that the system of record will change before the update is complete, in which case your list will be out of date, and you may have improper results. For example, your program might undo somebody else's changes if they just made a change to a group that you are working on, and your snapshot came from before their commit. Bottom line you want to keep your time window between read and commit very small.

To me, the simpler thing would be

for each permission that is checked
    grab a reference to the group (e.g. a `DirectoryEntry` instance)
    if the user isn't in there, add it
for each permission that is not checked
    grab a reference to the group (e.g. a `DirectoryEntry` instance)
    if the user is in there, remove it

When done

Grab a fresh list
Compare to the desired results
Display an error if there is any mismatch
  • If there are say 100 groups would this not be a lot of calls into AD causing a long wait? AD is not very responsive as it is. – Matthew Verstraete Feb 23 '17 at 22:24

Let's take a step back here. You are adding and removing users from what seems like, at most, a handful of groups. Given your example, I can't imagine it would be very "process intensive" to calculate the 3 changes you propose. (If the checked groups list is only 4 items long and the existing list is 5 items long, I wouldn't even worry about iterating over them a couple times to calculate a couple change lists. Heck, even if each list was 100 items a piece, I doubt you would notice a difference unless you are using some awful access algorithm. On top of that, most of the built-in LINQ methods and built-in collections will handle all this just fine.) As always, don't assume what will be "too process intensive". Measure it.

The thing that will probably hurt you more would be making a lot of external calls to Active Directory (just a guess, test to be sure). So if you are really worried about it, minimize those calls. I would much rather make the 3 calls to make the changes than wipe the slate clean then add back 4 groups.

On top of that, deleting a whole slew of records just to add them back can create a headache for audit trails, etc. (It may not matter with AD, but in general it's probably not a good idea.) Imagine trying to figure out when a user was removed from a group. I mean really removed, not just that someone played with the edit groups page.

Also, consider this. Since AD is probably used to control access to a lot of things, there are many applications using it while you are. What could happen to those apps if a user suddenly loses access? What if those apps cache permissions and they happen to hit AD between when you wipe out the groups and re-add them? Also, imagine the fun of trying to do root cause analysis on an intermittent bug in a totally unrelated app when Sarah in accounting on occasion can't do her job because she lost AD access at the wrong time (and by the time you get to it everything will look fine and be unreproducable).

The point is, wiping it all clean then starting over is probably a lazy way of doing it. Unless you have a measurable justification for doing it and are ok with the risks, just write the few extra lines of code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.