Any and all comments about this are appreciated.
Disclaimer - I am not responsible for anything that happens from following these steps. I have tested them to the point that I have seen them do what I claim them do in a small test case. I do not know if or what they do beyond my claims.
These steps include a database and core file changes, if you are not sure what you are doing, don't.
I apologize for the problems with visibility in my images - turning them into JPG's made them even harder to see than normal. I have my IDE colors set up so it doesn't strain my eyes staring at it for a long time, so it's heavy in dark colors. The images are also here for support, all the text you need to see is in plain text and C&P'able.
Why I did this: I need the ability to deny specific users access to some pages. Making new roles for each of these people is not an acceptable solution. Less time will be spent re-applying these changes for each upgrade than any type of 'new role denial' system. This has been done mostly for me. I know there is interest in the ability to deny user/role access in DNN. This is my solution to it. I consider it a fairly elegant hack; Minimalist in it's application.
With that outta the way, let's change things!
I figured I should do a nice concise wite up of how to add Role and User Level deny access in a hack job way.
I also wanted to do this because there are a couple ways this can be set up with only minimal changes.
They are as follows:
1) Role & User Deny - User Deny > User View > Role Deny > Role View
2) Role & User Deny - User Deny and Role Deny > User View and Role View
3) User Deny - User Deny > User View > Role View with Role Deny Disabled
It is possible to do just Role Deny, but I'm not going to include it because MY main point of getting this was User level deny. There is, apparently, a need for DNN install to have a Registered User see things that a Subscriber does not, so I have enabled the ability to deny a role so Subscribers won't see things that a Registered User does since you cannot remove Registered User from an account.
OK, let's get started.
Things you will need
Visual Studio 2005 (ignoring 2k8 since it's in beta and I don't have it)
Source Code to DotNetNuke 4.6.2
A way to access the Database DNN installs to.(I have SQL Server Management Studio)
In VS you will want to open the following files, depending on what changes you want to make (All file paths are given as they are in Visual Studio Solution Explorer)
For All options
http://localhost/DotNetNuke_2/App_GlobalResources//GlobalResources.resx
DotNetNuke.Library\Components\Tabs\Navigation.vb
Option 1 and 2)
DotNetNuke.Library\Components\Controls\DataGrids\PermissionsGrid\TabPermissionsGrid.vb
Option 3)
DotNetNuke.Library\Components\Controls\DataGrids\PermissionsGrid\PermissionsGrid.vb
In your DB manager open the table Permissions, and or a window to run an INSERT statement
MAKING CHANGES - We start updating the system
Now we are going to actually make changes to our Database, resource file, and code; in that order.
DATABASE
We need to add a row to the Permission table. The contents of this row will be
"# SYSTEM_TAB -1 DENY Deny Tab" (minus the quotes)
Where # is an auto-generated ID
You can manually add that, or use
INSERT INTO [DotNetNuke_Tesy].[dbo].[Permission]
([PermissionCode]
,[ModuleDefID]
,[PermissionKey]
,[PermissionName])
VALUES
('SYSTEM_TAB'
,-1
,'DENY'
,'Deny Tab')
to insert it.
If you refresh the view of the table (or open it) it should look something like .
RESOURCE FILE
A simple insert of a text block into one of the Resource files. This is mostly a cosmetic action. As everything will still function if you do not. The difference is some text on the settings page, as shown here:
To make the edit:
In GlobalResources.resx
At Line 208 Insert
<data name="Deny Tab.Permission" xml:space="preserve">
<value>Deny Page</value>
</data>
This will then be lines 208, 209 and 210. The previous line 208 will be line 211.
If you do not have on, or don't have, line numbers, search for <data name="Edit Tab.Permission" xml:space="preserve"> which will be line 205.
That's the resource file Edit. You can see what my file look like... sorta; My resx files kinda suck visually.
Please forgive my color scheme, I don't go into resx files often. :)
CODE FILES
I'm going to go over the code file changes 1 option at a time. This will cause some information to be duplicated as I'm going to treat each option as if the other options aren't here, so it will be easy to follow the steps to get what you want done.
I'm assuming you have line numbers. Any other way of referencing is cumbersome. If you need to see the function names or surrounding text to search for, I will have screen shots
Option 1: Role and User Deny - User Deny Overrides User View Overrides Role Deny Overrides Role View
TabPermissionsGrid.vb
Line 243
CHANGE FROM
permission = true
TO
permission = Not (objPerm.PermissionKey = "DENY")
As these images illustrate
Navigation.vb
Function IsTabShown
We are going to be adding code here so Go down to the function.
We want to insert our code between the If statement and Return True, at line 284
Dim objTabPermissionController As New Security.Permissions.TabPermissionController
Dim objUserInfo As UserInfo = UserController.GetCurrentUserInfo()
If objUserInfo.UserID = 1 Then 'Host always has access
Return True
End If
If objTabPermissionController.GetTabPermissions(objTab.TabPermissions, "DENY").Contains(";[" + objUserInfo.UserID.ToString() + "];") Then
Return False
End If
If objTabPermissionController.GetTabPermissions(objTab.TabPermissions, "VIEW").Contains(";[" + objUserInfo.UserID.ToString() + "];") Then
Return True 'User Level View overrides Role Deny
End If
For Each str As String In objTabPermissionController.GetTabPermissions(objTab.TabPermissions, "DENY").Split(New Char() {CChar(";")})
For Each sRole As String In objUserInfo.Roles
If str = sRole Then
Return False 'No more checking, a user role is denied
End If
Next
Next
We can see the changes here
to
Those are all the changes to get Option 1 working so that User Deny Overrides User View Overrides Role Deny Overrides Role View.
Option 2: Role and User Deny - User Deny and Role Deny Override User View and Role View
TabPermissionsGrid.vb
Line 243
CHANGE FROM
permission = true
TO
permission = Not (objPerm.PermissionKey = "DENY")
As these images illustrate
Navigation.vb
Function IsTabShown
We are going to be adding code here so Go down to the function.
We want to insert our code between the If statement and Return True, at line 284
Dim objTabPermissionController As New Security.Permissions.TabPermissionController
Dim objUserInfo As UserInfo = UserController.GetCurrentUserInfo()
If objUserInfo.UserID = 1 Then 'Host always has access
Return True
End If
For Each str As String In objTabPermissionController.GetTabPermissions(objTab.TabPermissions, "DENY").Split(New Char() {CChar(";")})
If str = "[" + objUserInfo.UserID.ToString() + "]" Then
Return False 'No more checking, current user is denied
End If
For Each sRole As String In objUserInfo.Roles
If str = sRole Then
Return False 'No more checking, a user role is denied
End If
Next
Next
We can see the changes here
to
Those are all the changes to get Option 2 working.
You may note that these two are VERY similar, which is correct.
The only difference is the removal of a small chunk of code in the For Each loop
The box'd code checks to see if the user has view permission, and if they do, having gotten past the user deny check, it returns true so they don't get denied by any Deny Roles.
Option 3 - User Deny - Role Deny Disabled - User Deny Overrides Role View and User View
PermissionsGrid.vb
Line 505 - INSERT
If objPermission.PermissionKey = "DENY" Then
Continue For
End If
This makes the block of code in SetUpRolesGrid go from
to
Navigation.vb
Function IsTabShown
We are going to be adding code here so Go down to the function.
We want to insert our code between the If statement and Return True, at line 284
Dim objTabPermissionController As New Security.Permissions.TabPermissionController
Dim objUserInfo As UserInfo = UserController.GetCurrentUserInfo()
If objUserInfo.UserID = 1 Then 'Host always has access
Return True
End If
For Each str As String In objTabPermissionController.GetTabPermissions(objTab.TabPermissions, "DENY").Split(New Char() {CChar(";")})
If str = "[" + objUserInfo.UserID.ToString() + "]" Then
Return False 'No more checking, current user is denied
End If
Next
We can see the changes here
to
That is Option 3.
I have tested and all three of these work. If they don't work for you, please let me know and I will check the steps here to make sure I don't have a typo somewhere.
Just a reminder in addition to the Comments at the top - Making these chagnes is done at your own risk. I take NO responsibilties for any thing that happens from using these on your systems.