I approached it differently. In my DB table for users I added a column for AlternateApprover and foa given user the Administrator can assign their alternate. Then if the main user is "out of the office" the alternate can view and take action on the workflow that normally went to the main user. The actions of the alternate are logged as their own so that you can see who really did what. With Sarbanes-Oxley I am pretty sure you would not want to hide that data and make it look like the main user did something when in fact someone else did it for him.
Joe
Unfortunately almost all the code and database for the project is written and grossly changing it not an option, however adding to it is an available option.
Right now, I am looking at using a second BO identity and assigning it all the roles of the delegator. That identity becomes available to the delegate when they log in (actually a list of delegator identities that they may use). All logged actions are then logged as the delgate/delegator combination.
The question in my mind is whether to use inheritence from the normal application identity, WODBIdentity, or to simply subclass the Identity object. I am thinking the first as a Decorator Pattern and the latter as polymorphism.
However, what I was mostly wondering was if there was inherently some in the CSLA framework which addressed this issue already?
First, I'll answer the "easy" question. There isn't anything within CSLA to support this. CSLA will work with the standard .NET IPrincipal/IIdentity model of security, but that's all it will do. Since delegation isn't built into that, you're on your own.
As for how to implement delegation, I'll tell you what I usually do, and you can decide whether it's too intrusive of a change to make.
I typically store the delegation information in a separate table. This table can get as specific as you need it to - for one project, I had to get down to specific data in the database that could be delegated. In any event, this table would store the date range, the source user, the delegated user, and what functionality was to be delegated. Depending on how the delegation functionality needs to be done, you might need more than one table - I did for the project I just mentioned - but that's usually pretty rare. I didn't change anything else in the database.
Then I would create my custom IIdentity object to load both the user's roles and the roles delegated to the user. I keep the two lists separate, so that it's possible to tell whether the rights were intrinsic or delegated. This can be useful if it's important to know within the application whether the rights that are being exercised are delegated - maybe you need to show something on the UI to reflect that.
Anyway, the "IsInRole" code checks both lists, and since it's a string value, I can basically pass whatever I want. Since the database stores who made the change to the database and when, I could use the delegation table to quickly determine whether the change was authorized or not, and who delegated the authority to make the change.
Given this model, I don't see a need to create a second Identity object, or even to subclass the existing one. The modifications to your existing Identity object should be rather minimal. What may be a larger change is if you need to change all the "IsInRole" code calls, but you should be able to get at those fairly quickly with a search-and-replace. In any case, all the changes are basically additive to the system, and if you never need/use them, no one will ever notice the difference.
HTH
- Scott
Thanks for the compliment!
I guess I'm a little confused. It sounds like you're saying that once I delegate my rights to someone else, I can't perform those rights anymore? Or are you saying that your system shouldn't allow both me and those I've delegated rights to access to the same workflows at the same time?
If it's the first one - well, that sounds a little odd to me, but what the heck do I know? If it's the second one, that doesn't strike me as an implementation detail for the delegation system. That sounds more like a check-out/check-in type of thing, which would be implemented separately from user-security access.
I can't speak to using delegation for testing, though at first blush I'd scratch my head a little on that. NUnit tests shouldn't care a whit about user access - those are run using test fixtures that you write. User security shouldn't enter into that equation, unless you're testing the security objects. And I know almost nothing about UI testing frameworks, so I can't speak knowledgably about that.
Obviously, you know the system better than I do, and if you can adapt something to fit what you need, more power to you!
Copyright (c) Marimer LLC