I have an .aspx form with 20 fields that must be disable based on a users role and a status of a order record. Currently the application has 5 roles and 3 status, so I have 300 different possible conditions that I have to account for.
My first thought is to store each permutation in a table, then set the fields when the page loads by looping through the fields. Is there a better way? Please note, I am using .Net 2.0 and NOT MVC.
I'd probably store the details of each field, and then the roles and status that can edit them, and do it that way.
What are the rules for the system? Basically, are there really 300 possible conditions? Or is that really certain fields are only editable for certain status, and then only certain roles can edit those fields? Or is it that certain fields are available for certain roles as well?
If it's more of the former I'd probably have something like this:
Three primary tables (makes it easy to extend if you add a field, role or status):
Then two link tables:
Then for any given order and user you can then find which Fields are editable for the order's current status, and the users role, and as you work through the fields set the access rights appropriately - however you set the controls - either dynamically generating them based on the collection you get back, or statically on the page.
If you have an issue where the Role can override the Status, you could also store a boolean in the Field/Role table, indicating whether the Field should be avaiable regardless of status.
Like another responder, we also use a Business Object framework called CSLA. CSLA implements field-level security checks by requiring class developers to do security checks in the property get/set calls. A typical property implementation looks like this:
Private mFirstName As String = ""
Public Property FirstName() As String
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Get
CanReadProperty("FirstName", True)
Return mFirstName
End Get
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Set(ByVal value As String)
CanWriteProperty("FirstName", True)
If value Is Nothing Then value = ""
If Not mFirstName.Equals(value) Then
mFirstName = value
PropertyHasChanged("FirstName")
End If
End Set
End Property
Notice the calls to CanReadProperty
and CanWriteProperty
. The second parameter specifies that the method should throw an exception if the user is not authorized to perform the specific read/write operation.
The implementation of the CanReadProperty
and CanWriteProperty
are provided by the framework's base class but should be reproducible without adopting the entire CSLA framework. The implementations check an AuthorizationRules
data structure which defines who is allowed/denied Read/Write access based on roles. Often, the AuthorizationRules
structure is populated during object creation.
Exposing the same CanReadProperty
and CanWriteProperty
methods to your presentation-tier allows you to enable/disable UI elements based on the current user's access rights. For example:
FirstNameTextBox.ReadOnly = Not CanWriteProperty("FirstName", false)
Hopefully this information will provide you with a good starting point for developing your own implementation. If you're interested in learning more about CSLA then check out Expert C# 2008 Business Objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With