Step 3. Creating Security Business Objects

You can use either Entity Framework or classic MM .NET Entity objects to enable security in your WPF applications. Follow these steps to create the necessary business objects classes.

  1. Create a User business object (singular, not plural) along with a UserEntity class from the MM .NET Users table using the Business Layer Generator. When generating the business object you can choose to generate stored procedures or simply use dynamic SQL statements for inserting, updating, and deleting data.

    You can also choose to use Entity Framework entity objects or MM .NET classic entity objects. If using Entity Framework, add a new UserEntity to the entity data model from the Users table.

  2. Create a UserRole business object (singular, not plural) along with a UserRoleEntity class from the MM .NET UserRole table using the Business Layer Generator. When generating the business object you can choose to generate stored procedures or simply use dynamic SQL statements for inserting, updating, and deleting data.

    You can also choose to use Entity Framework entity objects or MM .NET classic entity objects. If using Entity Framework, add a new UserRoleEntity to the entity data model from the UserRole table.

    If using Entity Framework, in the UserRole.Partial source code file, replace the class definition with the following in C#:

    	/// <summary>
       /// Summary description for UserRole.
       /// </summary>
       public partial class UserRole
       {
          /// <summary>
          /// Hook method automatically executed from the mmBusinessObject constructor
          /// </summary>
          protected override void HookConstructor()
          {
             // Place code here to be executed when the business object instantiates
          }
    
          /// <summary>
          /// Gets the specified UserRole entity by user and role PK
          /// </summary>
          /// <param name="userPK">User PK</param>
          /// <param name="rolePK">Role PK</param>
          /// <returns>UserRole entity</returns>
          public UserRoleEntity GetUserRoleByUserAndRole(int userPK, int rolePK)
          {
             var query = from ur in this.ObjectContext.UserRoleEntities
                      where ur.UserFK == userPK && ur.RoleFK == rolePK
                      select ur;
    
             return this.GetEntity(query);
          }
    
          /// <summary>
          /// Gets all roles for the specified user
          /// </summary>
          /// <param name="userPK"></param>
          /// <returns>User roles</returns>
          public mmBindingList<UserRoleEntity> GetUserRoles(int userPK)
          {
             var query = from ur in this.ObjectContext.UserRoleEntities
                      where ur.UserFK == userPK
                      select ur;
    
             return this.GetEntityList(query);
          }
       }

    And in VB .NET:

    Partial Public Class UserRole
    
       ''' <summary>
       ''' Hook method automatically executed from the mmBusinessObject constructor
       ''' </summary>
       ''' <remarks></remarks>
       Protected Overrides Sub HookConstructor()
          '' Place code here to be executed when the business object instantiates
       End Sub
    
       ''' <summary>
       ''' Gets the specified UserRole entity by user and role PK
       ''' </summary>
       ''' <param name="userPK">User PK</param>
       ''' <param name="RolePK">Role PK</param>
       ''' <returns>UserRole entity</returns>
       Public Function GetUserRoleByUserAndRole(ByVal userPK As Integer, ByVal rolePK As Integer) As UserRoleEntity
    
          Dim query As IQueryable(Of UserRoleEntity) = From ur In Me.ObjectContext.UserRoleEntities
           Where ur.UserFK = userPK And ur.RoleFK = rolePK
          Select ur
    
          Return Me.GetEntity(query)
    
       End Function
    
       ''' <summary>
       ''' Gets all roles for the specified user
       ''' </summary>
       ''' <param name="userPK"></param>
       ''' <returns>User roles</returns>
       Public Function GetUserRoles(ByVal userPK As Integer) As mmBindingList(Of UserRoleEntity)
    
          Dim query As IQueryable(Of UserRoleEntity) = From ur In Me.ObjectContext.UserRoleEntities
             Where ur.UserFK = userPK
             Select ur
    
          Return Me.GetEntityList(query)
    
       End Function
    
    End Class

  3. Create a Role business object (singular, not plural) along with a RoleEntity class from the MM .NET Roles table using the Business Layer Generator. When generating the business object you can choose to generate stored procedures or simply use dynamic SQL statements for inserting, updating, and deleting data.

    You can also choose to use Entity Framework entity objects or MM .NET classic entity objects. If using Entity Framework, add a new RoleEntity to the entity data model from the Roles table.

    If using Entity Framework, in the Role.Partial source code file, replace the class definition with the following in C#:

    	/// <summary>
    	/// Summary description for Role.
    	/// </summary>
    	public partial class Role
    	{
    		/// <summary>
    		/// UserRole business controller
    		/// </summary>
    		protected UserRole userRole;
    
    		/// <summary>
    		/// Hook method automatically executed from the mmBusinessObject constructor
    		/// </summary>
    		protected override void HookConstructor()
    		{
    			// Place code here to be executed when the business object instantiates
    			this.userRole = new UserRole();
    			this.RegisterChildBizObj(this.userRole);
    		}
    
    		/// <summary>
    		/// Adds the specified user to the specified role
    		/// </summary>
    		/// <param name="userPK"></param>
    		/// <param name="rolePK"></param>
    		public virtual void AddUserToRole(int userPK, int rolePK)
    		{
    			UserRoleEntity userRoleEntity = this.userRole.NewEntity();
    			userRoleEntity.UserFK = userPK;
    			userRoleEntity.RoleFK = rolePK;
    			this.userRole.SaveEntity(userRoleEntity);
    		}
    
    		/// <summary>
    		/// Removes the specified user from the specified role
    		/// </summary>
    		/// <param name="userPK"></param>
    		/// <param name="rolePK"></param>
    		public virtual void RemoveUserFromRole(int userPK, int rolePK)
    		{
    			UserRoleEntity userRoleEntity = this.userRole.GetUserRoleByUserAndRole(userPK, rolePK);
    			this.userRole.DeleteEntity(userRoleEntity);
    		}
    
    		/// <summary>
    		/// Deletes all roles for the specified user
    		/// </summary>
    		/// <param name="userPK"></param>
    		public virtual void DeleteUserRoles(int userPK)
    		{
    			mmBindingList<UserRoleEntity> userRoles = this.userRole.GetUserRoles(userPK);
    			this.userRole.DeleteAll();
    		}
    
    		/// <summary>
    		/// Get all roles for which the specified user is a member
    		/// </summary>
    		/// <param name="userPK"></param>
    		/// <returns></returns>
    		public mmBindingList<RoleEntity> GetUserRoles(int userPK)
    		{
    			var query = from r in this.ObjectContext.RoleEntities
    						from ur in r.UserRoles
    						where ur.UserFK == userPK
    						select r;
    					
    			return this.GetEntityList(query);
    		}
    
    		/// <summary>
    		/// Get all roles for which the specified user is not a member
    		/// </summary>
    		/// <param name="userPK"></param>
    		/// <returns></returns>
    		public mmBindingList<RoleEntity> GetUserNonMemberRoles(int userPK)
    		{
    			var query = this.ObjectContext.RoleEntities.Except(from r in this.ObjectContext.RoleEntities
    															   from ur in r.UserRoles
    															   where ur.UserFK == userPK
    															   select r);
    
    			return this.GetEntityList(query);
    		}
    	}

    And in VB .NET:

    Partial Public Class Role
    
       ''' <summary>
       ''' UserRole business controller
       ''' </summary>
       Protected userRole As UserRole
    
       ''' <summary>
       ''' Hook method automatically executed from the mmBusinessObject constructor
       ''' </summary>
       Protected Overrides Sub HookConstructor()
    
          '' Place code here to be executed when the business object instantiates
          Me.userRole = New UserRole()
          Me.RegisterChildBizObj(Me.userRole)
    
       End Sub
    
    
       ''' <summary>
       ''' Adds the specified user to the specified role
       ''' </summary>
       ''' <param name="userPK"></param>
       ''' <param name="rolePK"></param>
       Public Overridable Sub AddUserToRole(ByVal userPK As Integer, ByVal rolePK As Integer)
    
          Dim userRoleEntity As UserRoleEntity = Me.userRole.NewEntity()
          userRoleEntity.UserFK = userPK
          userRoleEntity.RoleFK = rolePK
          Me.userRole.SaveEntity(userRoleEntity)
    
       End Sub
    
       ''' <summary>
       ''' Removes the specified user from the specified role
       ''' </summary>
       ''' <param name="userPK"></param>
       ''' <param name="rolePK"></param>
       Public Overridable Sub RemoveUserFromRole(ByVal userPK As Integer, ByVal rolePK As Integer)
    
          Dim userRoleEntity As UserRoleEntity = Me.userRole.GetUserRoleByUserAndRole(userPK, rolePK)
          Me.userRole.DeleteEntity(userRoleEntity)
    
       End Sub
    
       ''' <summary>
       ''' Deletes all roles for the specified user
       ''' </summary>
       ''' <param name="userPK"></param>
       Public Overridable Sub DeleteUserRoles(ByVal userPK As Integer)
    
          Dim userRoles As mmBindingList(Of UserRoleEntity) = Me.userRole.GetUserRoles(userPK)
          Me.userRole.DeleteAll()
    
       End Sub
    
       ''' <summary>
       ''' Get all roles for which the specified user is a member
       ''' </summary>
       ''' <param name="userPK"></param>
       ''' <returns></returns>
       Public Function GetUserRoles(ByVal userPK As Integer) As mmBindingList(Of RoleEntity)
    
          Dim query As IQueryable(Of RoleEntity) = From r In Me.ObjectContext.RoleEntities
             From ur In r.UserRoles
             Where ur.UserFK = userPK
             Select r
    
          Return Me.GetEntityList(query)
    
       End Function
    
       ''' <summary>
       ''' Get all roles for which the specified user is not a member
       ''' </summary>
       ''' <param name="userPK"></param>
       ''' <returns></returns>
       Public Function GetUserNonMemberRoles(ByVal userPK As Integer) As mmBindingList(Of RoleEntity)
    
          Dim query As IQueryable(Of RoleEntity) = Me.ObjectContext.RoleEntities.Except(From r In Me.ObjectContext.RoleEntities
           From ur In r.UserRoles
           Where ur.UserFK = userPK
           Select r)
    
          Return Me.GetEntityList(query)
    
       End Function
    
    End Class

  4. Create a RoleSecurity business object (singular, not plural) along with a RoleSecurityEntity class from the MM .NET RoleSecurity table using the Business Layer Generator. When generating the business object you can choose to generate stored procedures or simply use dynamic SQL statements for inserting, updating, and deleting data.

    You can also choose to use Entity Framework entity objects or MM .NET classic entity objects. If using Entity Framework, add a new RoleSecurityEntity to the entity data model from the RoleSecurity table.

    If using Entity Framework, in the RoleSecurity.Partial source code file, add the following namespace references to the top of the class definition:

    using OakLeaf.MM.Main.Security;
    using OakLeaf.MM.Main;

    And in VB .NET:

    Imports OakLeaf.MM.Main.Security
    Imports OakLeaf.MM.Main

    Next, replace the class definition with the following in C#:

    	/// <summary>
       /// Summary description for RoleSecurity.
       /// </summary>
       public partial class RoleSecurity
       {
          /// <summary>
          /// Hook method automatically executed from the mmBusinessObject constructor
          /// </summary>
          protected override void HookConstructor()
          {
             // Place code here to be executed when the business object instantiates
             this.ImmediateDelete = false;
          }
    
          /// <summary>
          /// Returns all role security for the specified role
          /// </summary>
          /// <param name="rolePK"></param>
          /// <returns></returns>
          public mmBindingList<RoleSecurityEntity> GetRoleSecurityForRole(int rolePK)
          {
             var query = from rs in this.ObjectContext.RoleSecurityEntities
                      where rs.RoleFK == rolePK
                      select rs;
    
             return this.GetEntityList(query);
          }
    
          /// <summary>
          /// Sets the security access level for the specified role and
          /// security PK within the cached entity list
          /// </summary>
          /// <param name="rolePK">Role PK</param>
          /// <param name="securityPK">Security PK</param>
          /// <param name="accessLevel">Access Level</param>
          public virtual void SetRoleSecurityCached(int rolePK, Guid securityPK, short? accessLevel)
          {
             // Convert the access level
             mmSecurityAccessLevel level = mmAppBase.SecurityMgr.ConvertAccessLevel(accessLevel);
    
             // See if a security record already exists for the specified role/security PK
             var query = from rs in this.EntityList
                      where rs.RoleFK == rolePK && rs.SecurityFK == securityPK
                      select rs;
    
             RoleSecurityEntity roleSecurityEntity = query.SingleOrDefault();
    
             if (roleSecurityEntity != null)
             {
                // Security record already exits. Check if the specified 
                // access level is the default access level
                if (level == mmAppBase.DefaultSecurityAccessLevel)
                {
                   // Delete the record since it's the same as the default
                   this.DeleteEntity(roleSecurityEntity);
                }
                else
                {
                   // It isn't the default access level, so change the access level
                   if (level != mmAppBase.SecurityMgr.ConvertAccessLevel(roleSecurityEntity.AccessLevel))
                   {
                      roleSecurityEntity.AccessLevel = accessLevel;
                   }
                }
             }
             else
             {
                // A security record does NOT already exist. If it's not the 
                // default access level, create a new record. 
                if (level != mmAppBase.DefaultSecurityAccessLevel)
                {
                   roleSecurityEntity = this.NewEntity();
                   roleSecurityEntity.RoleFK = rolePK;
                   roleSecurityEntity.SecurityFK = securityPK;
                   roleSecurityEntity.AccessLevel = accessLevel;
                }
             }
          }
       }

    And in VB .NET:

    Partial Public Class RoleSecurity
    
       ''' <summary>
       ''' Hook method automatically executed from the mmBusinessObject constructor
       ''' </summary>
       ''' <remarks></remarks>
       Protected Overrides Sub HookConstructor()
          '' Place code here to be executed when the business object instantiates
          Me.ImmediateDelete = False
       End Sub
    
       ''' <summary>
       ''' Returns all role security for the specified role
       ''' </summary>
       ''' <param name="rolePK"></param>
       ''' <returns></returns>
       Public Function GetRoleSecurityForRole(ByVal rolePK As Integer) As mmBindingList(Of RoleSecurityEntity)
    
          Dim query As IQueryable(Of RoleSecurityEntity) = From rs In Me.ObjectContext.RoleSecurityEntities
           Where rs.RoleFK = rolePK
           Select rs
    
          Return Me.GetEntityList(query)
    
       End Function
    
       ''' <summary>
       ''' Sets the security access level for the specified role and
       ''' security PK within the cached entity list
       ''' </summary>
       ''' <param name="rolePK">Role PK</param>
       ''' <param name="securityPK">Security PK</param>
       ''' <param name="accessLevel">Access Level</param>
       Public Sub SetRoleSecurityCached(ByVal rolePK As Integer, ByVal securityPK As Guid, ByVal accessLevel As Nullable(Of Short))
    
          ' Convert the access level
          Dim level As mmSecurityAccessLevel = mmAppBase.SecurityMgr.ConvertAccessLevel(accessLevel)
    
          ' See if a security record already exists for the specified role/security PK
          Dim query As IEnumerable(Of RoleSecurityEntity) = From rs In Me.EntityList
              Where rs.RoleFK = rolePK And rs.SecurityFK = securityPK
              Select rs
    
          Dim roleSecurityEntity As RoleSecurityEntity = query.SingleOrDefault()
    
          If Not roleSecurityEntity Is Nothing Then
    
             ' Security record already exits. Check if the specified 
             ' access level is the default access level
             If level = mmAppBase.DefaultSecurityAccessLevel Then
    
                ' Delete the record since it's the same as the default
                Me.DeleteEntity(roleSecurityEntity)
    
             Else
    
                ' It isn't the default access level, so change the access level
                If level <> mmAppBase.SecurityMgr.ConvertAccessLevel(roleSecurityEntity.AccessLevel) Then
    
                   roleSecurityEntity.AccessLevel = accessLevel
    
                End If
    
             End If
    
          Else
    
             ' A security record does NOT already exist. If it's not the 
             ' default access level, create a new record. 
             If level <> mmAppBase.DefaultSecurityAccessLevel Then
    
                roleSecurityEntity = Me.NewEntity()
                roleSecurityEntity.RoleFK = rolePK
                roleSecurityEntity.SecurityFK = securityPK
                roleSecurityEntity.AccessLevel = accessLevel
    
             End If
          End If
    
       End Sub
    
    End Class


  5. Create a Security business object (singular, not plural) along with a SecurityEntity class from the MM .NET Security table using the Business Layer Generator. When generating the business object you can choose to generate stored procedures or simply use dynamic SQL statements for inserting, updating, and deleting data.

    You can also choose to use Entity Framework entity objects or MM .NET classic entity objects. If using Entity Framework, add a new SecurityEntity to the entity data model from the Security table.

    If using Entity Framework, in the Security.Partial source code file, replace the class definition with the following in C#:

    	/// <summary>
       /// Summary description for Security.
       /// </summary>
       public partial class Security
       {
          /// <summary>
          /// Hook method automatically executed from the mmBusinessObject constructor
          /// </summary>
          protected override void HookConstructor()
          {
             // Place code here to be executed when the business object instantiates
          }
    
          /// <summary>
          /// Returns
          /// </summary>
          /// <param name="securityPK"></param>
          /// <returns></returns>
          public string GetSecurityObjectDescription(Guid securityPK)
          {
             var query = from s in this.ObjectContext.SecurityEntities
                      where s.SecurityPK == securityPK
                      select s;
    
             SecurityEntity securityEntity = this.GetEntity(query);
             if (securityEntity == null)
             {
                throw new Exception("No record in Security table for specified security GUID");
             }
             return securityEntity.Description;
          }
       }

    And in VB .NET:

    Partial Public Class Security
    
       ''' <summary>
       ''' Hook method automatically executed from the mmBusinessObject constructor
       ''' </summary>
       ''' <remarks></remarks>
       Protected Overrides Sub HookConstructor()
          '' Place code here to be executed when the business object instantiates
       End Sub
    
       ''' <summary>
       ''' Returns
       ''' </summary>
       ''' <param name="securityPK"></param>
       ''' <returns></returns>
       Public Function GetSecurityObjectDescription(ByVal securityPK As Guid) As String
    
          Dim query As IQueryable(Of SecurityEntity) = From s In Me.ObjectContext.SecurityEntities
             Where s.SecurityPK = securityPK
             Select s
    
          Dim securityEntity As SecurityEntity = Me.GetEntity(query)
    
          If securityEntity Is Nothing Then
             Throw New Exception("No record in Security table for specified security GUID")
          End If
    
          Return securityEntity.Description
    
       End Function
    
    End Class

  6. Create a UserSecurity business object (singular, not plural) along with a UserSecurityEntity class from the MM .NET UserSecurity table using the Business Layer Generator. When generating the business object you can choose to generate stored procedures or simply use dynamic SQL statements for inserting, updating, and deleting data.

    You can also choose to use Entity Framework entity objects or MM .NET classic entity objects. If using Entity Framework, add a new UserSecurityEntity to the entity data model from the UserSecurity table.

    If using Entity Framework, in the UserSecurity.Partial source code file, add the following namespace references to the top of the class definition:

    using OakLeaf.MM.Main.Security;
    using OakLeaf.MM.Main;

    And in VB .NET:

    Imports OakLeaf.MM.Main.Security
    Imports OakLeaf.MM.Main

    Next, replace the class definition with the following in C#:

       /// <summary>
       /// Summary description for UserSecurity.
       /// </summary>
       public partial class UserSecurity
       {
          /// <summary>
          /// Hook method automatically executed from the mmBusinessObject constructor
          /// </summary>
          protected override void HookConstructor()
          {
             // Place code here to be executed when the business object instantiates
          }
    
          /// <summary>
          /// Sets the security access level for the specified user and
          /// security PK within the cached entity list
          /// </summary>
          /// <param name="userPK">User PK</param>
          /// <param name="securityPK">Security PK</param>
          /// <param name="accessLevel">Access Level</param>
          public virtual void SetUserSecurityCached(int userPK, Guid securityPK, short accessLevel)
          {
             // Convert the new access level
             mmSecurityAccessLevel newLevel = mmAppBase.SecurityMgr.ConvertAccessLevel(accessLevel);
    
             // Get the current actual access level (taking role membership into consideration)
             mmSecurityAccessLevel currentLevel = mmAppBase.SecurityMgr.GetAccessLevel(userPK, securityPK);
    
             // If they're different, make a change
             if (newLevel != currentLevel)
             {
                var query = from us in this.EntityList
                         where us.UserFK == userPK && us.SecurityFK == securityPK
                         select us;
    
                UserSecurityEntity userSecurityEntity = query.SingleOrDefault();
    
                if (userSecurityEntity != null)
                {
                   // Set the new access level on the existing record
                   userSecurityEntity.AccessLevel = accessLevel;
                }
                else
                {
                   // A security record does NOT already exist, so create a new record. 
                   userSecurityEntity = this.NewEntity();
                   userSecurityEntity.UserFK = userPK;
                   userSecurityEntity.SecurityFK = securityPK;
                   userSecurityEntity.AccessLevel = accessLevel;
                }
             }
          }
       }

    And in VB .NET:

    Partial Public Class UserSecurity
        ''' <summary>
        ''' Hook method automatically executed from the mmBusinessObject constructor
        ''' </summary>
        ''' <remarks></remarks>
        Protected Overrides Sub HookConstructor()
            '' Place code here to be executed when the business object instantiates
       End Sub
    
       ''' <summary>
       ''' Sets the security access level for the specified user and
       ''' security PK within the cached entity list
       ''' </summary>
       ''' <param name="userPK">User PK</param>
       ''' <param name="securityPK">Security PK</param>
       ''' <param name="accessLevel">Access Level</param>
       Public Overridable Sub SetUserSecurityCached(ByVal userPK As Integer, ByVal securityPK As Guid, ByVal accessLevel As Short)
    
          ' Convert the new access level
          Dim newLevel As mmSecurityAccessLevel = mmAppBase.SecurityMgr.ConvertAccessLevel(accessLevel)
    
          ' Get the current actual access level (taking role membership into consideration)
          Dim currentLevel As mmSecurityAccessLevel = mmAppBase.SecurityMgr.GetAccessLevel(userPK, securityPK)
    
          ' If they're different, make a change
          If newLevel <> currentLevel Then
    
             Dim query As IEnumerable(Of UserSecurityEntity) = From us In Me.EntityList
               Where us.UserFK = userPK And us.SecurityFK = securityPK
               Select us
    
             Dim userSecurityEntity As UserSecurityEntity = query.SingleOrDefault()
    
             If Not userSecurityEntity Is Nothing Then
    
                ' Set the new access level on the existing record
                userSecurityEntity.AccessLevel = accessLevel
    
             Else
    
                ' A security record does NOT already exist, so create a new record. 
                userSecurityEntity = Me.NewEntity()
                userSecurityEntity.UserFK = userPK
                userSecurityEntity.SecurityFK = securityPK
                userSecurityEntity.AccessLevel = accessLevel
    
             End If
    
          End If
    
       End Sub
    
    End Class

  7. Create a new class named SecurityManager. Add the following assembly references:

    using System.Collections.Generic;
    using System.Linq;
    
    using OakLeaf.MM.Main.Security;
    using OakLeaf.MM.Main.Collections;
    using OakLeaf.MM.Main;

    And in VB .NET:

    Imports System.Collections.Generic
    Imports System.Linq
    
    Imports OakLeaf.MM.Main.Security
    Imports OakLeaf.MM.Main.Collections
    Imports OakLeaf.MM.Main

    Replace the class definition with the following:

    	/// <summary>
       /// Security Manager
       /// </summary>
       public class SecurityManager
       {
          protected Role Role;
          protected RoleSecurity RoleSecurity;
    
          /// <summary>
          /// Default access level for secure controls. The value of this
          /// property is copied from mmAppBase in the constructor of 
          /// this class
          /// </summary>
          public mmSecurityAccessLevel DefaultSecurityAccessLevel
          {
             get { return this._defaultSecurityAccessLevel; }
             set { this._defaultSecurityAccessLevel = value; }
          }
          private mmSecurityAccessLevel _defaultSecurityAccessLevel;
    
          /// <summary>
          /// Constructor
          /// </summary>
          public SecurityManager()
          {
             // Get the default security access level
             this.DefaultSecurityAccessLevel =
                mmAppBase.DefaultSecurityAccessLevel;
    
             this.Role = new Role();
             this.RoleSecurity = new RoleSecurity();
    
          }
    
          /// <summary>
          /// Returns the access level for the specified user, security id, 
          /// User security, and role Security
          /// </summary>
          /// <param name="userPK">User PK</param>
          /// <param name="securityID">Security ID</param>
    	/// <param name="userSecurityList">User Security list</param>
    	/// <param name="roleSecurityList">Role Security list</param>
          /// <param name="filterRoleSecurity">Specifies if role security info is filtered
          /// to the specified user</param>
          /// <returns></returns>
          public virtual mmSecurityAccessLevel GetUserAccessLevel(int userPK, Guid securityID,
             mmBindingList<UserSecurityEntity> userSecurityList,
             mmBindingList<RoleSecurityEntity> roleSecurityList,
             bool filterRoleSecurity)
          {
             // Create a new list that only contains Role security information pertinent
             // to the specified user
             if (filterRoleSecurity)
             {
                // Create a new list that only contains the role security
                // information that applies to the specified user
                mmBindingList<RoleSecurityEntity> roleSecurity = new mmBindingList<RoleSecurityEntity>();
    
                // Get all roles for the specified user
                mmBindingList<RoleEntity> userRoles = this.Role.GetUserRoles(userPK);
    
                // Search for each role in the UserRoles list
                List<RoleSecurityEntity> tempRoleSecurity;
    
                foreach (RoleEntity role in userRoles)
                {
                   var query = from rs in roleSecurityList
                            where rs.RoleFK == role.RolePK
                            select rs;
    
                   tempRoleSecurity = query.ToList();
                   //tempRoleSecurity = RoleSecurity.GetRoleSecurityForRole(role.RolePK);
                   foreach (RoleSecurityEntity rsEntity in tempRoleSecurity)
                   {
                      roleSecurity.Add(rsEntity);
                   }
                }
                return this.GetAccessLevel(userPK, securityID, userSecurityList, roleSecurity);
             }
    
             return this.GetAccessLevel(userPK, securityID, userSecurityList, roleSecurityList);
          }
    
          /// <summary>
          /// Returns the access level for the specified user and security ID
          /// </summary>
          /// <param name="userPK">User PK</param>
          /// <param name="securityID">Security ID</param>
    	/// <param name="userSecurityList">User Security list</param>
    	/// <param name="roleSecurityList">Role Security list</param>
          /// <returns>Security access level</returns>
          public virtual mmSecurityAccessLevel GetAccessLevel(int userPK, Guid securityID,
             mmBindingList<UserSecurityEntity> userSecurityList, mmBindingList<RoleSecurityEntity> roleSecurityList)
          {
             // Set the access level to the default
             mmSecurityAccessLevel level = this.DefaultSecurityAccessLevel;
    
             // First check if there is a setting at the user level for this ID,
             // since a user-level setting supercedes any role-level setting
             if (userSecurityList != null && userSecurityList.Count > 0)
             {
                var query = from us in userSecurityList
                         where us.UserFK == userPK && us.SecurityFK == securityID
                         select us;
    
                UserSecurityEntity userSecurityEntity = query.SingleOrDefault();
                if (userSecurityEntity != null)
                {
                   return this.ConvertAccessLevel(userSecurityEntity.AccessLevel);
                }
             }
    
             // Check for a role-level security setting
             if (roleSecurityList != null && roleSecurityList.Count > 0)
             {
    
                mmBindingList<RoleSecurityEntity> roleSecurity;
    
                if (mmAppBase.UseMostPrivilegedRoleAccess)
                {
                   var query = from rs in roleSecurityList
                            where rs.SecurityFK == securityID
                            orderby rs.AccessLevel descending
                            select rs;
                   roleSecurity = new mmBindingList<RoleSecurityEntity>(query.ToList());
                }
                else
                {
                   var query = from rs in roleSecurityList
                            where rs.SecurityFK == securityID
                            orderby rs.AccessLevel
                            select rs;
                   roleSecurity = new mmBindingList<RoleSecurityEntity>(query.ToList());
                }
    
                // If any information found, use the first row
                if (roleSecurity.Count > 0)
                {
                   level = this.ConvertAccessLevel(roleSecurity[0].AccessLevel);
                }
             }
    
             // Determine if there are any user roles with a default access level that
             // supersedes specified role access levels
             int AccessLevel = this.ConvertAccessLevel(level);
             mmBindingList<RoleEntity> userRoles = this.Role.GetUserRoles(userPK);
    
             if (mmAppBase.UseMostPrivilegedRoleAccess)
             {
                if (AccessLevel < this.ConvertAccessLevel(mmAppBase.DefaultSecurityAccessLevel))
                {
                   level = this.GetUserRoleDefaultAccess(securityID, roleSecurityList,
                      userRoles, level);
                }
             }
             else
             {
                if (AccessLevel > this.ConvertAccessLevel(mmAppBase.DefaultSecurityAccessLevel))
                {
                   level = this.GetUserRoleDefaultAccess(securityID, roleSecurityList,
                      userRoles, level);
                }
             }
             return level;
          }
    
    	/// <summary>
    	/// Get the access level for the specified role
    	/// </summary>
    	/// <param name="rolePK">Role PK</param>
    	/// <param name="controlID">Security Control ID</param>
    	/// <param name="roleSecurityList">Role Security list</param>
    	/// <returns>Access level for the specififed role</returns>
          public mmSecurityAccessLevel GetRoleAccessLevel(int rolePK, Guid controlID, mmBindingList<RoleSecurityEntity> roleSecurityList)
          {
             mmSecurityAccessLevel accessLevel = mmAppBase.DefaultSecurityAccessLevel;
             if (roleSecurityList != null && roleSecurityList.Count != 0)
             {
                var query = from rs in roleSecurityList
                         where rs.RoleFK == rolePK && rs.SecurityFK == controlID
                         select rs;
    
    
                List<RoleSecurityEntity> roleSecurity = query.ToList();
    
                if (roleSecurity.Count > 0)
                {
                   // Convert the database setting to the corresponding access level
                   accessLevel =
                      mmAppBase.SecurityMgr.ConvertAccessLevel(roleSecurity[0].AccessLevel);
    
                }
             }
             return accessLevel;
          }
    
          /// <summary>
          /// Determines if the user has unspecified role access for the specified security ID.
          /// If not, this method returns the current access level. If so, this method returns
          /// the application default access level
          /// </summary>
          /// <param name="securityID">Security ID</param>
          /// <param name="roleSecurityList">Role Security list</param>
          /// <param name="userRoleList">User Roles list</param>
          /// <param name="level">Current Access Level</param>
          /// <returns>Access Level</returns>
          protected mmSecurityAccessLevel GetUserRoleDefaultAccess(Guid securityID, mmBindingList<RoleSecurityEntity> roleSecurityList,
              mmBindingList<RoleEntity> userRoleList, mmSecurityAccessLevel level)
          {
             mmSecurityAccessLevel AccessLevel = level;
    
             // Determine if user has unspecified role access (uses the app default setting)
             // for the specified security ID
             foreach (RoleEntity roleEntity in userRoleList)
             {
                var query = from rs in roleSecurityList
                         where rs.SecurityFK == securityID && rs.RoleFK == roleEntity.RolePK
                         select rs;
    
                List<RoleSecurityEntity> roleSecurity = query.ToList();
    
                if (roleSecurity == null || roleSecurity.Count == 0)
                {
                   AccessLevel = mmAppBase.DefaultSecurityAccessLevel;
                   break;
                }
             }
             return AccessLevel;
          }
    
          /// <summary>
          /// Converts the numeric access level stored in the data base
          /// to the corresponding mmSecurityAccessLevel enumeration value
          /// </summary>
          /// <param name="setting"></param>
          /// <returns></returns>
          public virtual mmSecurityAccessLevel ConvertAccessLevel(int? setting)
          {
             switch (setting)
             {
                case (0):
                   return mmSecurityAccessLevel.None;
                case (1):
                   return mmSecurityAccessLevel.ReadOnly;
                case (2):
                   return mmSecurityAccessLevel.Full;
                default:
                   return mmSecurityAccessLevel.Unknown;
             }
          }
    
          /// <summary>
          /// Converts the specified access level into a corresponding integer value
          /// </summary>
          /// <param name="setting">Security access level</param>
          /// <returns>Integer access level</returns>
          public virtual int ConvertAccessLevel(mmSecurityAccessLevel setting)
          {
             int level = -1;
    
             switch (setting)
             {
                case (mmSecurityAccessLevel.None):
                   level = 0;
                   break;
                case (mmSecurityAccessLevel.ReadOnly):
                   level = 1;
                   break;
                case (mmSecurityAccessLevel.Full):
                   level = 2;
                   break;
             }
             return level;
          }
       }

    And in VB .NET:

    Public Class SecurityManager
    
       Protected Role As Role
       Protected RoleSecurity As RoleSecurity
    
       ''' <summary>
       ''' Default access level for secure controls. The value of Me
       ''' property is copied from mmAppBase in the constructor of 
       ''' Me class
       ''' </summary>
    
       Private _defaultSecurityAccessLevel As mmSecurityAccessLevel
       Public Property DefaultSecurityAccessLevel() As mmSecurityAccessLevel
          Get
             Return _defaultSecurityAccessLevel
          End Get
          Set(ByVal value As mmSecurityAccessLevel)
             _defaultSecurityAccessLevel = value
          End Set
       End Property
    
       ''' <summary>
       ''' Constructor
       ''' </summary>
       Public Sub SecurityManager()
    
          ' Get the default security access level
          Me.DefaultSecurityAccessLevel = mmAppBase.DefaultSecurityAccessLevel
          Me.Role = New Role()
          Me.RoleSecurity = New RoleSecurity()
    
       End Sub
    
       ''' <summary>
       ''' Returns the access level for the specified user, security id, 
       ''' User security, and role Security
       ''' </summary>
       ''' <param name="userPK">User PK</param>
       ''' <param name="securityID">Security ID</param>
       ''' <param name="userSecurityList">User Security list</param>
       ''' <param name="roleSecurityList">Role Security list</param>
       ''' <param name="filterRoleSecurity">Specifies if role security info is filtered
       ''' to the specified user</param>
       ''' <returns></returns>
       Public Overridable Function GetUserAccessLevel(ByVal userPK As Integer, ByVal securityID As Guid,
         ByVal userSecurityList As mmBindingList(Of UserSecurityEntity),
         ByVal roleSecurityList As mmBindingList(Of RoleSecurityEntity),
         ByVal filterRoleSecurity As Boolean) As mmSecurityAccessLevel
    
          ' Create a new list that only contains Role security information pertinent
          ' to the specified user
          If (filterRoleSecurity) Then
    
             ' Create a new list that only contains the role security
             ' information that applies to the specified user
             Dim roleSecurity As mmBindingList(Of RoleSecurityEntity) = New mmBindingList(Of RoleSecurityEntity)()
    
             ' Get all roles for the specified user
             Dim userRoles As mmBindingList(Of RoleEntity) = Me.Role.GetUserRoles(userPK)
    
             ' Search for each role in the UserRoles list
             Dim tempRoleSecurity As List(Of RoleSecurityEntity)
    
             For Each role As RoleEntity In userRoles
    
                Dim query As IEnumerable(Of RoleSecurityEntity) = From rs In roleSecurityList
                 Where rs.RoleFK = role.RolePK
                Select rs
    
                tempRoleSecurity = query.ToList()
    
                For Each rsEntity As RoleSecurityEntity In tempRoleSecurity
                   RoleSecurity.Add(rsEntity)
                Next
    
             Next
    
             Return Me.GetAccessLevel(userPK, securityID, userSecurityList, RoleSecurity)
    
          End If
    
          Return Me.GetAccessLevel(userPK, securityID, userSecurityList, roleSecurityList)
    
       End Function
    
       ''' <summary>
       ''' Returns the access level for the specified user and security ID
       ''' </summary>
       ''' <param name="userPK">User PK</param>
       ''' <param name="securityID">Security ID</param>
       ''' <param name="userSecurityList">User Security list</param>
       ''' <param name="roleSecurityList">Role Security list</param>
       ''' <returns>Security access level</returns>
       Public Overridable Function GetAccessLevel(ByVal userPK As Integer, ByVal securityID As Guid,
         ByVal userSecurityList As mmBindingList(Of UserSecurityEntity),
         ByVal roleSecurityList As mmBindingList(Of RoleSecurityEntity)) As mmSecurityAccessLevel
    
          ' Set the access level to the default
          Dim level As mmSecurityAccessLevel = Me.DefaultSecurityAccessLevel
    
          ' First check if there is a setting at the user level for Me ID,
          ' since a user-level setting supercedes any role-level setting
          If Not userSecurityList Is Nothing And userSecurityList.Count > 0 Then
    
             Dim query As IEnumerable(Of UserSecurityEntity) = From us In userSecurityList
                Where us.UserFK = userPK And us.SecurityFK = securityID
                Select us
    
             Dim userSecurityEntity As UserSecurityEntity = query.SingleOrDefault()
             If Not UserSecurityEntity Is Nothing Then
                Return Me.ConvertAccessLevel(UserSecurityEntity.AccessLevel)
             End If
    
          End If
    
          ' Check for a role-level security setting
          If Not roleSecurityList Is Nothing And roleSecurityList.Count > 0 Then
    
          End If
    
          Dim roleSecurity As mmBindingList(Of RoleSecurityEntity)
    
          If mmAppBase.UseMostPrivilegedRoleAccess Then
    
             Dim query As IEnumerable(Of RoleSecurityEntity) = From rs In roleSecurityList
               Where rs.SecurityFK = securityID
               Order By rs.AccessLevel Descending
              Select rs
    
             roleSecurity = New mmBindingList(Of RoleSecurityEntity)(query.ToList())
    
          Else
    
             Dim query As IEnumerable(Of RoleSecurityEntity) = From rs In roleSecurityList
              Where rs.SecurityFK = securityID
              Order By rs.AccessLevel
              Select rs
    
             roleSecurity = New mmBindingList(Of RoleSecurityEntity)(query.ToList())
    
          End If
    
          ' If any information found, use the first row
          If roleSecurity.Count > 0 Then
             level = Me.ConvertAccessLevel(roleSecurity(0).AccessLevel)
          End If
    
          ' Determine if there are any user roles with a default access level that
          ' supersedes specified role access levels
          Dim AccessLevel As Integer = Me.ConvertAccessLevel(level)
          Dim userRoles As mmBindingList(Of RoleEntity) = Me.Role.GetUserRoles(userPK)
    
          If mmAppBase.UseMostPrivilegedRoleAccess Then
    
             If (AccessLevel < Me.ConvertAccessLevel(mmAppBase.DefaultSecurityAccessLevel)) Then
    
                level = Me.GetUserRoleDefaultAccess(securityID, roleSecurityList,
                 userRoles, level)
    
             Else
                If (AccessLevel > Me.ConvertAccessLevel(mmAppBase.DefaultSecurityAccessLevel)) Then
    
                   level = Me.GetUserRoleDefaultAccess(securityID, roleSecurityList,
                    userRoles, level)
                End If
             End If
             Return level
          End If
       End Function
    
       ''' <summary>
       ''' Get the access level for the specified role
       ''' </summary>
       ''' <param name="rolePK">Role PK</param>
       ''' <param name="controlID">Security Control ID</param>
       ''' <param name="roleSecurityList">Role Security list</param>
       ''' <returns>Access level for the specififed role</returns>
       Public Function GetRoleAccessLevel(ByVal rolePK As Integer, ByVal controlID As Guid, ByVal roleSecurityList As mmBindingList(Of RoleSecurityEntity)) As mmSecurityAccessLevel
    
          Dim accessLevel As mmSecurityAccessLevel = mmAppBase.DefaultSecurityAccessLevel
          If Not roleSecurityList Is Nothing And roleSecurityList.Count <> 0 Then
    
             Dim query As IEnumerable(Of RoleSecurityEntity) = From rs In roleSecurityList
                Where rs.RoleFK = rolePK And rs.SecurityFK = controlID
                Select rs
    
             Dim roleSecurity As List(Of RoleSecurityEntity) = query.ToList()
    
             If roleSecurity.Count > 0 Then
    
                ' Convert the database setting to the corresponding access level
                accessLevel = mmAppBase.SecurityMgr.ConvertAccessLevel(roleSecurityList(0).AccessLevel)
    
             End If
          End If
          Return accessLevel
    
       End Function
    
    	''' <summary>
    	''' Determines if the user has unspecified role access for the specified security ID.
    	''' If not, Me method returns the current access level. If so, Me method returns
    	''' the application default access level
    	''' </summary>
    	''' <param name="securityID">Security ID</param>
    	''' <param name="roleSecurityList">Role Security list</param>
    	''' <param name="userRoleList">User Roles list</param>
    	''' <param name="level">Current Access Level</param>
    	''' <returns>Access Level</returns>
    	Protected Function GetUserRoleDefaultAccess(ByVal securityID As Guid,
    		 ByVal roleSecurityList As mmBindingList(Of RoleSecurityEntity),
    		 ByVal userRoleList As mmBindingList(Of RoleEntity),
    		 ByVal level As mmSecurityAccessLevel) As mmSecurityAccessLevel
    
    		Dim AccessLevel As mmSecurityAccessLevel = level
    
    		' Determine if user has unspecified role access (uses the app default setting)
    		' for the specified security ID
    		Dim re As RoleEntity
    
    		For Each roleEntity As RoleEntity In userRoleList
    
    			re = roleEntity
    
    			Dim query As IEnumerable(Of RoleSecurityEntity) = From rs In roleSecurityList
    			 Where rs.SecurityFK = securityID And rs.RoleFK = re.RolePK
    			 Select rs
    
    			Dim roleSecurity As List(Of RoleSecurityEntity) = query.ToList()
    
    			If roleSecurity Is Nothing Or roleSecurity.Count = 0 Then
    				AccessLevel = mmAppBase.DefaultSecurityAccessLevel
    				Exit For
    			End If
    
    		Next
    
    		Return AccessLevel
    
    	End Function
    
       ''' <summary>
       ''' Converts the numeric access level stored in the data base
       ''' to the corresponding mmSecurityAccessLevel enumeration value
       ''' </summary>
       ''' <param name="setting"></param>
       ''' <returns></returns>
       Public Overridable Function ConvertAccessLevel(ByVal setting As Nullable(Of Integer)) As mmSecurityAccessLevel
    
          Select Case setting
    
             Case (0)
                Return mmSecurityAccessLevel.None
             Case (1)
                Return mmSecurityAccessLevel.ReadOnly
             Case (2)
                Return mmSecurityAccessLevel.Full
             Case Else
                Return mmSecurityAccessLevel.Unknown
          End Select
    
       End Function
    
       ''' <summary>
       ''' Converts the specified access level into a corresponding integer value
       ''' </summary>
       ''' <param name="setting">Security access level</param>
       ''' <returns>Integer access level</returns>
       Public Overridable Function ConvertAccessLevel(ByVal setting As mmSecurityAccessLevel) As Integer
    
          Dim level As Integer = -1
    
          Select Case setting
    
             Case (mmSecurityAccessLevel.None)
                level = 0
                Exit Select
             Case (mmSecurityAccessLevel.ReadOnly)
                level = 1
                Exit Select
             Case (mmSecurityAccessLevel.Full)
                level = 2
                Exit Select
    
          End Select
    
          Return level
    
       End Function
    
    End Class



© (c) 2026 Oak Leaf Enterprises, Inc., 1996-2026 • Updated: 06/28/12
Comment or report problem with topic