One feature that DNN provides that you don't have to worry about when writing Web applications is role based security. DNN allows a portal administrator to create specific roles, assign users to those roles and then provide access to certain pages or sections of pages to a specific role. As a developer of modules for DNN you can use the role based security to further enhance your development and streamline the development process. In this article we will discuss the role security and how to integrate it into module development.
First of all the roles for DNN are defined in a database table called Roles (makes sense). The table contains the following fields:
RoleID
PortalID
RoleName
Description
ServiceFee
BillingFrequency
TrialPeriod
TrialFequency
BillingPeriod
TrialFee
IsPublic
AutoAssignment
Each Portal can have it's own specific roles. A role can be a premium role where a portal administrator can charge a fee for being a member of the role, that is the reason for the Billing, and other obvious fields we can see there.
This Roles table then relates to both the UserRoles table and Portals table. The UserRoles table contains all the roles assigned for a particular user. If you open the table you will see the following fields:
UserRoleID
UserID
RoleID
ExpiryDate
IsTrialUsed
These tables are then queried by a couple stored procedures to obtain all particular roles for a certain user. In addition, there are stored procedures for obtaining all particular roles for a specific portal. The stored procedures that concern you as a DNN developer would be:
- GetPortalRoles: Returns all roles for a specified portal. Input to the stored procedure is PortalID, and output is all data from the Roles table for
the specified portal.
- GetRoleMembership: Inputs PortalID, optional RoleID, and optional UserID and returns all roles, and/or members of a specific role.
- GetRolesByUser: Accepts a UserID and PortalID and returns all the roles the user is assigned for a particular portal.
- AddUserRole: For adding a user to a specific role.
There are a couple update stored procedures, but we will not be covering them in this article.
Now that we covered the database structure of the roles, how do we apply that creating custom modules? In this first code block we have an example of a module that needs to take advantage of security roles of DNN. We have an edit module where we want to be able to have check boxes with all the roles in the portal so we make a call to GetPortalRoles(PortalID) to get all the roles in DNN for a specific portal. Then we check these roles against the roles we configured in the module, this is basically a semi-colon delimited string of the checked values of the DNN portal roles. We check the DNN roles against the roles from our edit settings by looping through the array:
'make a call the users class.
Dim objUser As New UsersDB
'now execute the stored procedures to get all the portal roles.
Dim EditArticleRoles As SqlDataReader = objUser.GetPortalRoles(PortalId)
' Clear existing items in checkboxlist
chkAuthArticleRoles.Items.Clear()
Dim aryAuthArticlesRoles As String()
'now populate the array with the delimited string that was previously
'stored in the module settings hash table value of "AuthArticleRoles".
aryAuthArticlesRoles = Split(CType(Settings("AuthArticlesRoles"), String), ";")
Dim allEditArticleItems As New System.Web.UI.WebControls.ListItem
allEditArticleItems.Text = "All Users"
allEditArticleItems.Value = glbRoleAllUsers
'check and see if all users are allowed to access the module, if so check the checkbox.
If InStr(1, Settings("AuthArticlesRoles"), glbRoleAllUsers & ";") <> 0 Then
allEditArticleItems.Selected = True
End If
chkAuthArticleRoles.Items.Add(allEditArticleItems)
Dim iArt As Integer
'now go through all the roles and check them against our array to see
'what roles should be selected for the module.
While EditArticleRoles.Read()
Dim itemArt As New System.Web.UI.WebControls.ListItem
itemArt.Text = CType(EditArticleRoles("RoleName"), String)
itemArt.Value = EditArticleRoles("RoleID").ToString()
For iArt = 0 To UBound(aryAuthArticlesRoles)
If aryAuthArticlesRoles(iArt) = itemArt.Value Then
itemArt.Selected = True
End If
Next
chkAuthArticleRoles.Items.Add(itemArt)
End While
Now that we have the roles defined we want to check and see if a user is in one of the roles that we specified in the edit module. So in the user control do the following; we get all the roles that the user has associate with them and check them against the roles we selected in the edit module. For this application we have roles that can add articles to the module:
Dim objSec2 As New UsersDB
Dim dr As String() = objSec2.GetRolesByUser(Context.User.Identity.Name, _
PortalId)
Dim i As Integer
For i = 0 To UBound(dr)
'check to see if the role is defined for edit access as
'we set previously in our edit module.
If InStr(Settings("AuthEditRoles"), CType(dr(i), String) & ";") And _
(CType(dr(i), String) <> "") Then
SiteEdit = True
End If
Next
The above method is one way to get all the roles for a specific user. The next method is making a call and checking to see if a user is in a particular role or roles:
Dim objSecurity As PortalSecurity
'here we pass our delimited string value to the method and it will
'return a true or false if the user is in the role or not.
If objSecurity.IsInRoles(CType(Settings("AuthArticlesRoles"), String)) Then
rowArticle.Visible = True
End If
In this next example, we have a transaction that occurs, if the transaction is successful, then we add a user to a specific role. This example is pulled from a PayPal IPN transaction. Once PayPal says the transaction was successful, we'll add the user to role that was specified in the edit module for this particular application:
If Trim(strPurchaseRoles) <> "" Then
'add user to role(s)
Dim objUser As New UsersDB
Dim aryPurchaseRoles As String()
aryPurchaseRoles = Split(CType(Settings("PurchaseRoles"), String), ";")
Dim i As Integer
For i = 0 To UBound(aryPurchaseRoles)
'add the user to each role specified in the settings hash value of PurchaseRoles.
objUser.AddUserRole(PortalID, aryPurchaseRoles(i), intUserID)
Next
End If