Multiple Users

Multiple Users

Old forum URL: forums.lhotka.net/forums/t/3683.aspx


culprit posted on Wednesday, October 10, 2007

Does anyone have a suggestion on how I might log in two users at once. The application should allow the following login scenarios:

1. Clerk only

2. Manager only

3. Clerk and Manager

In scenario three we would probably default to using the clerk's permissions but might combine the two. I would preload all the permission groups on login so would not need access to these again but would want access to the user(s) and their id(s) in the database so that they can be attached to edits throughout the BOs.

Also, on this same line where would I store the current user's ID in the csla.applicationcontext so that I could write this in the data routines in the BOs?

Thanks, Rob

ajj3085 replied on Wednesday, October 10, 2007

Have the application run as two distinct users at once?  I think that'd be very difficult.  If that's not what you mean though, you could have a role Clerk and another role Manager.  A user then could belong to either or both roles.  Your code would only check for which ever role would be appopriate.

culprit replied on Wednesday, October 10, 2007

Well, I don't think I necessarily need two distinct users. Maybe there is some place within the applicationcontext I could just store the IDs for the two users and this would allow the application to store these IDs with every edit. I would then use roles to handle permissions for the user(s).

Do you have any suggestions where I might store this data?

ajj3085 replied on Wednesday, October 10, 2007

Probably in the application context, or a custom principal if you're not going to use Windows authentication.

I'm curious though.. whats wrong with having one user belong to two roles?

culprit replied on Wednesday, October 10, 2007

For permission issues I think I will use multiple roles but I just wanted a way so that when I modified records I could insert both the manager and clerk IDs. I guess I could do this in a global shared object but thought it would be cleaner to do this in the same space as was storing the user.

If you were to store this in the application context how would you do this? Would you store this in the CSLA.ApplicationContext where the user is being stored?

Thanks,

Rob

ReadOnlyChild replied on Wednesday, October 10, 2007

..so, are the two users in front of the same computer at the same time ?

is this a requirement so the Edit be effective ?

because if the requirement not necessarily needs the two persons in the same place at the same time, then a more appropriate approach would be to make a "workflow" like implementation...

... pend the commit until the two approvals are successful / not rejected ...

culprit replied on Wednesday, October 10, 2007

No, the two users do not have to be in front of the computer at the same time. But in this particular business it is quite common for a manager to sign in and then let the clerk do everything but for legal reasons we need to save any record changed with both the clerk's id and the manager's id.

We actually have several variations using workflow. For instance in some settings the system may require the manager to sign off on the record before it is finalized or printed. Another scenario allows only a clerk to be signed in but absolutely requires the manager to sign off (biometric, login, etc...) before it is finalized or printed. The workflow for this application can get complex I am just pulling out this one scenario where both individuals are logged in and the record would be saved with both IDs attached (clerk and manager).

I think I could do this by storing the IDs for the users in a global shared class but thought I might be able to place this in the CSLA.ApplicationContext since to me that seemed to make more sense.

Thanks, Rob

tmg4340 replied on Thursday, October 11, 2007

OK - I guess I'm confused here.  You're asking about a situation where both users are logged in to the same application at the same time (which is, honestly, a head-scratcher to me), but you're also saying it's quite common for the manager to log in, but let the clerk do all the work?  Where do you get the clerk's ID?

Honestly, this seems like a situation ripe for some formalized delegation within the application.  If the manager has the rights to do certain tasks, but wants to let others do it, that concept really should be baked into the application.  Then the clerk can log in, but when they do tasks that have been delegated to them by their manager, the manager's ID can be retrieved from the database and stored along with the clerk's.

I realize this isn't exactly a direct answer to your question, but I think it's a concept you might want to look into.  Unless your delegation rules are extremely complex, it's not hard to set up within the database and application.  Delegation is usually set up and left alone, so it's not like it's a huge impact on the user's daily process.  Plus, it allows for better visibility of who's doing what, and for whom - something that seems to be fairly important for your project.

ReadOnlyChild replied on Thursday, October 11, 2007

great suggestion tmg....  a module where the manager would go on [example] vacation so he had to assign thru the delegation part of the application, someone to take care of his direct reports during his absence...

and the system would have to inspect if the action is done "on behalf of" and store the appropriate info...

ReadOnlyChild replied on Thursday, October 11, 2007

great suggestion tmg....

like have a module to specify who will be responsible for a manager's tasks for a period of time, say the manager goes on vacation, so he needs to appoint someone to take care of his workflows during his absence,

and the application would have to know if actions are being done "on behalf of" and store the appropriate info...

tmg4340 replied on Thursday, October 11, 2007

ReadOnlyChild:

like have a module to specify who will be responsible for a manager's tasks for a period of time, say the manager goes on vacation, so he needs to appoint someone to take care of his workflows during his absence,

and the application would have to know if actions are being done "on behalf of" and store the appropriate info...

That's the idea - you allow an individual to grant their access rights to other individual(s) as necessary.  You can do it for a period of time, split rights among multiple people... however you need to set it up.

In our example here, when the clerk logs in, the sytem collects two sets of roles: those directly assigned to the clerk, and those (s)he inherits through delegation.  This allows the application to easily tell whether the action is allowed through direct rights or delegated rights.  Optionally, the delegated role list also provides who delegated the role to the clerk.  In .NET, this would ideally all be contained in custom Principal/Identity objects.

Then the application can either send the manager's ID along with the clerk's, or send the action to the database and let it collect the ID.  I personally would collect the list of delegators in the application - being able to display who the clerk is doing the work for is probably helpful, and on the chance that two people delegate the same authority to the clerk, the clerk would need to select for whom this action applies.

Again, a lot depends on how complex your delegation needs to be.  We set up a system at my last job that had a fairly complex level of delegation, with multiple levels, inheritance of delegation rights, date ranges, and the ability to delegate rights down beyond the "can you perform this action" to "what objects can you perform this action on?"  The whole thing took us about two weeks to code and test.  We were lucky in that we did it up-front, but retro-fitting that kind of thing wouldn't necessarily be a huge PITA.

culprit replied on Thursday, October 11, 2007

I think I understand. I am new to .Net and don't think I understand how to program this delegate you are referring to.

Also, you said you would store the User and IDs for display throughout the program which is what I wish to do. Would I somehow store them in the User space,

Csla.ApplicationContext.User? If so, could you give me an example of how to do this?

I appreciate your help. Rob.

tmg4340 replied on Friday, October 12, 2007

I'm not talking about a .NET delegate, nor is this a .NET-specific concept.  I'm talking about the delegation of responsibilities within your application.  The idea is that your managers can grant the rights they have in the application to other people.  This allows your clerk, for example, to log into the system using their ID, but be able to do the manager's tasks, since the manager would have delegated them to the clerk.  It also closes a fairly big hole in the security of your application (allowing a user to use the system under someone else's ID), allows your managers to more tightly control which of their tasks their subordinates can do for them, and allows for you to more easily track who is doing what.

It would require an additional table (or multiple tables, depending on the level of complexity) in your database, as well as some code changes/additions in your application.  Unfortunately, I can't give any real concrete examples, as I don't really know your requirements.  But I can lay out how I'd probably do it.

What I would probably do is to wrap the functionality within custom Principal and Identity objects (and if you don't have them, you'll need them.)  These objects would feed directly into ApplicationContext.User, and thus would be readily available to you.  They would store the list of roles the user directly has, as well as a second list of roles that have been granted to them by other users (along with the ID of the person(s) who granted each role.)  Then, your "IsInRole" implementation would check both lists to determine whether the user can do the specified action.

You'll also probably want a method to determine whether a role has been delegated by someone, as well as a method to return the ID of the delegator (or list of ID's, if the same role has been delegated to the user by multiple people.)  That way, you can easily populate your BO with the appropriate Manager ID if you need it, and provide the list of managers to choose from if the user needs to select which manager they are doing work for.  Using these methods would require a downcast of ApplicationContext.User to your custom Principal object, but there's not a lot of choice there, and that's not the end of the world.

Beyond that, you'll need a module within your application that allows users to delegate their rights to other users.  You don't necessarily have to restrict it to manager/clerk - realistically, anyone can delegate their rights to anyone else.  This allows for flexibility when people are sick, go on vacation, etc.  Again, a lot depends on the level of complexity in your application's security model, and the needs of your users.

Copyright (c) Marimer LLC