Professional Documents
Culture Documents
Center
25-May-15
Log In
Products
Buy
SUPPORT CENTER
Support
My Account
Tickets
Examples
About Us
Localization
How to separate data between employees and managers of different departments using
security permissions
Tags: .NET, Frameworks (XAF & XPO), eXpressApp Framework
FAQ
Training Events
ID:
E4045
Mo dified O n :
10/9/2013 1:33:16 PM
Tech n o lo gy:
.NET
Scenario
This example demonstrates how to use the new security system to implement the subject:
- Users (Joe, John) can view and edit their own tasks, but cannot delete them or create new ones. They also have readonly access to tasks,
employees and other data of their own department.
- Managers (Sam, Mary) can fully manage (CRUD) their own department, its employees and tasks. However, they cannot access data from
other departments.
- Administrators (Admin) can do everything within the application.
All users have empty passwords by default. You can see how it works in action at http://www.screencast.com/t/TBKEiCEfxc (or you can run
functional tests in the MainDemo.EasyTests folder).
Platfo rm:
Framew o rks (XAF & XPO )
Pro du ct:
eXp ressAp p Framew o rk
Downloads
Examp le
Examp le Ru n n er
Steps to implement
1. Permissions at the type and object level (with a criteria) are configured in the MainDemo.Module/DatabaseUpdate/Updater file.
Take special note that for building a complex criteria against associated objects, the JoinOperand together with the built-in CurrentUserId and
IsCurrentUserInRole criteria functions.
For greater convenience, strongly typed criteria for permissions are accompanied with their string representation.
2. The SecuredObjectSpaceProvider is used in the CreateDefaultObjectSpaceProvider method of the XafApplication descendants located in
the WinForms and ASP.NET projects.
3. The Department, Employee and EmployeeTask classes are implemented in the MainDemo.Module/BusinessObjects folder.
To quickly understand relationships between involved business classes, their class diagram is attached.
IMPORTANT NOTES
1. Be aware of the issue described in the Security - The "Entering state 'GetObjectsNonReenterant'" error may occur while saving data if a
permission criteria involves a collection property thread.
2. The State of the New Security System
Updater.cs
C#
Leave a Comment
using
using
using
using
using
using
using
using
System;
DevExpress.ExpressApp;
DevExpress.Data.Filtering;
DevExpress.ExpressApp.Security;
MainDemo.Module.BusinessObjects;
DevExpress.ExpressApp.SystemModule;
DevExpress.Persistent.Base.General;
DevExpress.ExpressApp.Security.Strategy;
namespace MainDemo.Module.DatabaseUpdate {
public class Updater : DevExpress.ExpressApp.Updating.ModuleUpdater {
public Updater(IObjectSpace objectSpace, Version currentDBVersion) : base(objectSpace, currentDBVersion) { }
public override void UpdateDatabaseAfterUpdateSchema() {
base.UpdateDatabaseAfterUpdateSchema();
//Create departments.
Department devDepartment = ObjectSpace.FindObject<Department>(CriteriaOperator.Parse("Title == 'R&D'"));
if(devDepartment == null) {
devDepartment = ObjectSpace.CreateObject<Department>();
devDepartment.Title = "R&D";
devDepartment.Office = "1";
devDepartment.Save();
}
Department supDepartment = ObjectSpace.FindObject<Department>(CriteriaOperator.Parse("Title == 'Technical Support'"));
if(supDepartment == null) {
supDepartment = ObjectSpace.CreateObject<Department>();
supDepartment.Title = "Technical Support";
supDepartment.Office = "2";
supDepartment.Save();
}
Department mngDepartment = ObjectSpace.FindObject<Department>(CriteriaOperator.Parse("Title == 'Management'"));
if(mngDepartment == null) {
mngDepartment = ObjectSpace.CreateObject<Department>();
mngDepartment.Title = "Management";
mngDepartment.Office = "3";
mngDepartment.Save();
}
//Create employees.
//Admin is a god that can do everything.
Employee administrator = ObjectSpace.FindObject<Employee>(CriteriaOperator.Parse("UserName == 'Admin'"));
if(administrator == null) {
administrator = ObjectSpace.CreateObject<Employee>();
administrator.UserName = "Admin";
administrator.FirstName = "Admin";
administrator.LastName = "Admin";
administrator.Department = mngDepartment;
administrator.IsActive = true;
administrator.SetPassword("");
administrator.Roles.Add(GetAdministratorRole());
administrator.Save();
https://www.devexpress.com/Support/Center/Example/Details/E4045
1/4
E4045 - How to separate data between employees and managers of different departments using security permissions | DevExpress Support Center
25-May-15
}
//Sam is a manager and he can do everything with his own department
Employee managerSam = ObjectSpace.FindObject<Employee>(CriteriaOperator.Parse("UserName == 'Sam'"));
if(managerSam == null) {
managerSam = ObjectSpace.CreateObject<Employee>();
managerSam.UserName = "Sam";
managerSam.FirstName = "Sam";
managerSam.LastName = "Jackson";
managerSam.IsActive = true;
managerSam.SetPassword("");
managerSam.Department = devDepartment;
managerSam.Roles.Add(GetManagerRole());
managerSam.Save();
}
//John is an ordinary user within the Sam's department.
Employee userJohn = ObjectSpace.FindObject<Employee>(CriteriaOperator.Parse("UserName == 'John'"));
if(userJohn == null) {
userJohn = ObjectSpace.CreateObject<Employee>();
userJohn.UserName = "John";
userJohn.FirstName = "John";
userJohn.LastName = "Doe";
userJohn.IsActive = true;
userJohn.SetPassword("");
userJohn.Department = devDepartment;
userJohn.Roles.Add(GetUserRole());
userJohn.Save();
}
//Mary is a manager of another department.
Employee managerMary = ObjectSpace.FindObject<Employee>(CriteriaOperator.Parse("UserName == 'Mary'"));
if(managerMary == null) {
managerMary = ObjectSpace.CreateObject<Employee>();
managerMary.UserName = "Mary";
managerMary.FirstName = "Mary";
managerMary.LastName = "Tellinson";
managerMary.IsActive = true;
managerMary.SetPassword("");
managerMary.Department = supDepartment;
managerMary.Roles.Add(GetManagerRole());
managerMary.Save();
}
//Joe is an ordinary user within the Mary's department.
Employee userJoe = ObjectSpace.FindObject<Employee>(CriteriaOperator.Parse("UserName == 'Joe'"));
if(userJoe == null) {
userJoe = ObjectSpace.CreateObject<Employee>();
userJoe.UserName = "Joe";
userJoe.FirstName = "Joe";
userJoe.LastName = "Pitt";
userJoe.IsActive = true;
userJoe.SetPassword("");
userJoe.Department = supDepartment;
userJoe.Roles.Add(GetUserRole());
userJoe.Save();
}
//Create tasks for employees.
if(ObjectSpace.FindObject<EmployeeTask>(CriteriaOperator.Parse("Subject == 'Do homework'")) == null) {
EmployeeTask task = ObjectSpace.CreateObject<EmployeeTask>();
task.Subject = "Do homework";
task.AssignedTo = managerSam;
task.DueDate = DateTime.Now;
task.Status = TaskStatus.NotStarted;
task.Description = "This is a task for Sam";
task.Save();
}
if(ObjectSpace.FindObject<EmployeeTask>(CriteriaOperator.Parse("Subject == 'Prepare coffee for everyone'")) == null) {
EmployeeTask task = ObjectSpace.CreateObject<EmployeeTask>();
task.Subject = "Prepare coffee for everyone";
task.AssignedTo = userJohn;
task.DueDate = DateTime.Now;
task.Status = TaskStatus.InProgress;
task.Description = "This is a task for John";
task.Save();
}
if(ObjectSpace.FindObject<EmployeeTask>(CriteriaOperator.Parse("Subject == 'Read latest news'")) == null) {
EmployeeTask task = ObjectSpace.CreateObject<EmployeeTask>();
task.Subject = "Read latest news";
task.AssignedTo = managerMary;
task.DueDate = DateTime.Now;
task.Status = TaskStatus.Completed;
task.Description = "This is a task for Mary";
task.Save();
}
if(ObjectSpace.FindObject<EmployeeTask>(CriteriaOperator.Parse("Subject == 'Book tickets'")) == null) {
EmployeeTask task = ObjectSpace.CreateObject<EmployeeTask>();
task.Subject = "Book tickets";
task.AssignedTo = userJoe;
task.DueDate = DateTime.Now;
task.Status = TaskStatus.Deferred;
task.Description = "This is a task for Joe";
task.Save();
}
ObjectSpace.CommitChanges();
}
//[<Employee>][Oid = CurrentUserId()].Single(Department.Oid)
JoinOperand joinEmployeesToAccessOwnDepartmemnt = new JoinOperand("Employee", new OperandProperty("Oid") == new FunctionOperator(CurrentUserIdOperator.OperatorName
//Administrators can do everything within the application.
private SecuritySystemRole GetAdministratorRole() {
SecuritySystemRole administratorRole = ObjectSpace.FindObject<SecuritySystemRole>(new BinaryOperator("Name", "Administrators"));
if(administratorRole == null) {
administratorRole = ObjectSpace.CreateObject<SecuritySystemRole>();
administratorRole.Name = "Administrators";
//Can access everything.
administratorRole.IsAdministrative = true;
}
return administratorRole;
}
//Users can do everything with their own tasks and can also view data of their own department.
private SecuritySystemRole GetUserRole() {
SecuritySystemRole userRole = ObjectSpace.FindObject<SecuritySystemRole>(new BinaryOperator("Name", "Users"));
if(userRole == null) {
userRole = ObjectSpace.CreateObject<SecuritySystemRole>();
userRole.Name = "Users";
//Cannot navigate to employees.
SecuritySystemTypePermissionObject userPermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();
userPermissions.TargetType = typeof(Employee);
https://www.devexpress.com/Support/Center/Example/Details/E4045
2/4
E4045 - How to separate data between employees and managers of different departments using security permissions | DevExpress Support Center
25-May-15
userPermissions.AllowNavigate = false;
userRole.TypePermissions.Add(userPermissions);
//Can view employees only from own department.
SecuritySystemObjectPermissionsObject canViewEmployeesFromOwnDepartmentPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject>
canViewEmployeesFromOwnDepartmentPermission.Criteria = "Department.Oid = [<Employee>][Oid = CurrentUserId()].Single(Department.Oid)";
canViewEmployeesFromOwnDepartmentPermission.Criteria = new BinaryOperator(new OperandProperty("Department.Oid"), joinEmployeesToAccessOwnDepartmemnt
canViewEmployeesFromOwnDepartmentPermission.AllowNavigate = true;
canViewEmployeesFromOwnDepartmentPermission.AllowRead = true;
userPermissions.ObjectPermissions.Add(canViewEmployeesFromOwnDepartmentPermission);
//Can change a couple properties of own user.
SecuritySystemMemberPermissionsObject canEditOwnUserPermission = ObjectSpace.CreateObject<SecuritySystemMemberPermissionsObject>();
canEditOwnUserPermission.Members = "ChangePasswordOnFirstLogon; StoredPassword; FirstName; LastName";
canEditOwnUserPermission.Criteria = "Oid=CurrentUserId()";
canEditOwnUserPermission.Criteria = (new OperandProperty("Oid") == new FunctionOperator(CurrentUserIdOperator.OperatorName)).ToString();
canEditOwnUserPermission.AllowWrite = true;
userPermissions.MemberPermissions.Add(canEditOwnUserPermission);
//Cannot access roles.
SecuritySystemTypePermissionObject rolePermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();
rolePermissions.TargetType = typeof(SecuritySystemRole);
userRole.TypePermissions.Add(rolePermissions);
//Can navigate to tasks, but cannot create them.
SecuritySystemTypePermissionObject employeeTaskPermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();
employeeTaskPermissions.TargetType = typeof(EmployeeTask);
employeeTaskPermissions.AllowNavigate = true;
employeeTaskPermissions.AllowCreate = false;
userRole.TypePermissions.Add(employeeTaskPermissions);
//Can view and edit own tasks, but cannot delete them.
SecuritySystemObjectPermissionsObject canManageOwnTasksObjectPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject>();
canManageOwnTasksObjectPermission.Criteria = "AssignedTo.Oid=CurrentUserId()";
canManageOwnTasksObjectPermission.Criteria = (new OperandProperty("AssignedTo.Oid") == new FunctionOperator(CurrentUserIdOperator.OperatorName)).ToString
canManageOwnTasksObjectPermission.AllowNavigate = true;
canManageOwnTasksObjectPermission.AllowRead = true;
canManageOwnTasksObjectPermission.AllowWrite = true;
canManageOwnTasksObjectPermission.AllowDelete = false;
canManageOwnTasksObjectPermission.Save();
employeeTaskPermissions.ObjectPermissions.Add(canManageOwnTasksObjectPermission);
//Can view, but cannot edit tasks from other users within own department.
SecuritySystemObjectPermissionsObject canSeeTasksOnlyFromOwnDepartmentObjectPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject
canSeeTasksOnlyFromOwnDepartmentObjectPermission.Criteria = "AssignedTo.Department.Oid=[<Employee>][Oid=CurrentUserId()].Single(Department.Oid)";
canSeeTasksOnlyFromOwnDepartmentObjectPermission.Criteria = new BinaryOperator(new OperandProperty("AssignedTo.Department.Oid"), joinEmployeesToAccessOwnDepa
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowNavigate = true;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowRead = true;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowWrite = false;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowDelete = false;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.Save();
employeeTaskPermissions.ObjectPermissions.Add(canSeeTasksOnlyFromOwnDepartmentObjectPermission);
//Cannot navigate to departments.
SecuritySystemTypePermissionObject departmentPermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();
departmentPermissions.TargetType = typeof(Department);
userRole.TypePermissions.Add(departmentPermissions);
//Can read and navigate to own department.
SecuritySystemObjectPermissionsObject canSeeOwnDepartmentObjectPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject>();
canSeeOwnDepartmentObjectPermission.Criteria = "Oid=[<Employee>][Oid=CurrentUserId()].Single(Department.Oid)";
canSeeOwnDepartmentObjectPermission.Criteria = new BinaryOperator(new OperandProperty("Oid"), joinEmployeesToAccessOwnDepartmemnt, BinaryOperatorType
canSeeOwnDepartmentObjectPermission.AllowNavigate = true;
canSeeOwnDepartmentObjectPermission.AllowRead = true;
canSeeOwnDepartmentObjectPermission.Save();
departmentPermissions.ObjectPermissions.Add(canSeeOwnDepartmentObjectPermission);
}
return userRole;
}
//Managers can manage their own department, its Employees, their tasks, etc. However, they cannot access data from other departments.
private SecuritySystemRole GetManagerRole() {
SecuritySystemRole managerRole = ObjectSpace.FindObject<SecuritySystemRole>(new BinaryOperator("Name", "Managers"));
if(managerRole == null) {
managerRole = ObjectSpace.CreateObject<SecuritySystemRole>();
managerRole.Name = "Managers";
//Derives permissions from the Users role.
managerRole.ChildRoles.Add(GetUserRole());
SecuritySystemTypePermissionObject departmentPermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();
departmentPermissions.TargetType = typeof(Department);
//Can navigate to departments.
departmentPermissions.AllowNavigate = true;
managerRole.TypePermissions.Add(departmentPermissions);
//Can do everything with own department.
SecuritySystemObjectPermissionsObject canManageOwnDepartmentObjectPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject>();
canManageOwnDepartmentObjectPermission.Criteria = "Oid=[<Employee>][Oid=CurrentUserId()].Single(Department.Oid)";
canManageOwnDepartmentObjectPermission.Criteria = new BinaryOperator(new OperandProperty("Oid"), joinEmployeesToAccessOwnDepartmemnt, BinaryOperatorType
canManageOwnDepartmentObjectPermission.AllowNavigate = true;
canManageOwnDepartmentObjectPermission.AllowRead = true;
canManageOwnDepartmentObjectPermission.AllowWrite = true;
canManageOwnDepartmentObjectPermission.AllowDelete = true;
canManageOwnDepartmentObjectPermission.Save();
departmentPermissions.ObjectPermissions.Add(canManageOwnDepartmentObjectPermission);
https://www.devexpress.com/Support/Center/Example/Details/E4045
3/4
E4045 - How to separate data between employees and managers of different departments using security permissions | DevExpress Support Center
25-May-15
canSeeTasksOnlyFromOwnDepartmentObjectPermission.Criteria = "AssignedTo.Department.Oid=[<Employee>][Oid=CurrentUserId()].Single(Department.Oid)";
canSeeTasksOnlyFromOwnDepartmentObjectPermission.Criteria = new BinaryOperator(new OperandProperty("AssignedTo.Department.Oid"), joinEmployeesToAccessOwnDepa
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowNavigate = true;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowRead = true;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowWrite = true;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.AllowDelete = true;
canSeeTasksOnlyFromOwnDepartmentObjectPermission.Save();
employeeTaskPermissions.ObjectPermissions.Add(canSeeTasksOnlyFromOwnDepartmentObjectPermission);
}
return managerRole;
}
}
}
DEVEXPRESS
About Us
News
Our Awards
Upcoming Events
User Comments
Case Studies
Reviews and Publications
Licensing
Purchasing
MVP Program
Contact Us
Logos
.NET CONTROLS
WinForms
ASP.NET
MVC
WPF
Silverlight
Windows 8 XAML
CROSS PLATFORM
Reporting
Document Automation
MOBILE
DevExtreme Mobile
HTML5 JS WIDGETS
DevExtreme Web
ENTERPRISE TOOLS
Report Server
Analytics Dashboard
iOS 7
DataExplorer
FRAMEWORKS
eXpressApp Framework
CODE-DEBUG-REFACTOR
CodeRush for Visual Studio
SUPPORT
Search the Knowledge Base
My Questions
Code Examples
Getting Started
Demos
Documentation
Blogs
Training
Webinars
Current Version/Build
Version History
FOLLOW US
If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383
https://www.devexpress.com/Support/Center/Example/Details/E4045
4/4