You are on page 1of 4

E4045 - How to separate data between employees and managers of different departments using security permissions | DevExpress Support

Center

25-May-15
Log In

Products

Free Trials & Demos

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

Submit a Support Ticket

Type search string and press Enter

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

Show all comments

Updater.cs

C#

Leave a Comment

v2013 vol 1.4 - v2014 vol 2.7


Open in popup window

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);

SecuritySystemTypePermissionObject employeePermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();


employeePermissions.TargetType = typeof(Employee);
//Can navigate to employees and create them.
employeePermissions.AllowNavigate = true;
employeePermissions.AllowCreate = true;
managerRole.TypePermissions.Add(employeePermissions);
//Can also do everything with employees from own department
SecuritySystemObjectPermissionsObject canManageEmployeesFromOwnDepartmentObjectPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject
//canManageEmployeesFromOwnDepartmentObjectPermission.Criteria = "Department.Oid=[<Employee>][Oid=CurrentUserId()].Single(Department.Oid)";
canManageEmployeesFromOwnDepartmentObjectPermission.Criteria = new BinaryOperator(new OperandProperty("Department.Oid"), joinEmployeesToAccessOwnDepartmemnt
canManageEmployeesFromOwnDepartmentObjectPermission.AllowWrite = true;
canManageEmployeesFromOwnDepartmentObjectPermission.AllowDelete = true;
canManageEmployeesFromOwnDepartmentObjectPermission.AllowNavigate = true;
canManageEmployeesFromOwnDepartmentObjectPermission.AllowRead = true;
canManageEmployeesFromOwnDepartmentObjectPermission.Save();
employeePermissions.ObjectPermissions.Add(canManageEmployeesFromOwnDepartmentObjectPermission);
SecuritySystemTypePermissionObject employeeTaskPermissions = ObjectSpace.CreateObject<SecuritySystemTypePermissionObject>();
employeeTaskPermissions.TargetType = typeof(EmployeeTask);
//Can navigate to tasks and create them.
employeeTaskPermissions.AllowNavigate = true;
employeeTaskPermissions.AllowCreate = true;
managerRole.TypePermissions.Add(employeeTaskPermissions);
//Can do everything with tasks from own department.
SecuritySystemObjectPermissionsObject canSeeTasksOnlyFromOwnDepartmentObjectPermission = ObjectSpace.CreateObject<SecuritySystemObjectPermissionsObject

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

FUNCTIONAL WEB TESTING


TestCafe
DELPHI C++BUILDER
VCL

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

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business


Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance
HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether
using WPF, Silverlight, ASP.NET, WinForms, HTML5 or Windows 8, DevExpress tools help you
build and deliver your best in the shortest time possible.

Your Privacy - Legal Statements

https://www.devexpress.com/Support/Center/Example/Details/E4045

Copyright 1998-2014 Developer Express Inc.


All trademarks or registered trademarks are property of their respective owners

4/4