This post is devoted to several improvements for the two key features of any serious line-of-business application - reporting and security. As you might expect from a mature application framework, DevExpress XAF ships with reusable ReportsV2 and Security modules designed to simplify the integration of the DevExpress Reporting Platform and role-based authorization features (actually much more than this!) for Windows, Web and Mobile platforms.
Let's take a look and see what's inside the upcoming major release for reports and security.
Grid Based Reporting in WinForms Applications
XAF now supports the built-in printing/export capabilities of the DevExpress Grid and thus allows you to create a report from any grid-based List View. The report's layout is autocreated (and is based on grid columns, appearance and filter settings) when you click the "New Report" command in the Export menu.
Technically, this is done by handling the ExportController.ExportActionItemsCreated event from the WinGridReportExportController and adding a New report item to the ExportController.ExportAction.
The New report item invokes the Report Designer. The current grid layout is automatically converted to a report layout. You can learn more about report generation rules in our Advanced Grid Printing and Exporting topic.
If you click Save, the report is saved to the application database, together with other user-defined reports.
Allow/Deny Modifier for Security Permissions (Beta)
With XAF's Security System, your application administrators can now allow access to all data within the application for a specific role and simultaneously deny access to a few data types or members. Alternatively, an end-user can deny access to all data for a role and only allow access to a strict list of objects or members. Both approaches make it easy to allow/deny data access across a broad range of use-case scenarios. To use this feature, choose Allow/Deny Permission Policy on the Choose Security page of the Solution Wizard.
As a result, special types of security users and roles will be used in your application - PermissionPolicyUser and PermissionPolicyRole. Entity Framework and XPO versions of these classes are declared in the Business Class Library. The primary difference with SecuritySystemUser and SecuritySystemRole classes (which were previously used by default and are now used for the Deny All policy) is that the role object exposes the PermissionPolicy property:
With this property, you can assign "deny all", "read only all" or "allow all" default permission policies for each role. This allows you to create very complex and flexible security configurations.
For each operation, you can explicitly specify the Allow or Deny modifier or leave it blank.
If the modifier is not specified, the permission is determined by the role's policy type. Note that policy has the lowest priority and is in play only when permissions are not explicitly specified.
Dynamic Permissions for Associated Objects
To allow users to modify objects used in associations (one-to-many and many-to-many), you should grant access to the properties on both sides of the association, because linking and unlinking operations always lead to the modification of both properties. XAF's Security System now simplifies this task by detecting associations and configuring required permissions automatically.
Required permissions are granted dynamically each time an associated object is requested when the ServerPermissionRequestProcessor.UseAutoAssociationPermission or ServerPermissionPolicyRequestProcessor.UseAutoAssociationPermission static field is set to true. The former field is considered for the Deny All policy, and the latter - for the Allow/Deny policy (see the Allow/Deny Modifier for Security Permissions section above). The SecuritySystem.IsGranted request for a member is processed as follows in this mode.
- The default security request is processed for a given member. If permission is granted, the result of this request is returned.
- If permission is not granted at the previous step and the current member is an association (see IMemberInfo.IsAssociation), the request is processed for the associated member. The result of this additional request is returned.
- If permission is not granted at the first step, and the current member is not an association, Security System checks if the member type is aggregated to another type. If owner type is found, a permission for the corresponding aggregated collection is requested and returned.
The SecuritySystem.IsGranted request for a type or object is processed as follows.
- The default security request is processed for the given type. If type permission is granted, the result is returned.
- If type permission is not granted at the previous step, Security System checks if the type is aggregated to another type. If the owner type is found, a permission for the corresponding aggregated collection is requested and returned.
- The requests for the Navigate operation are not processed using associations.
Simply stated, you configure permissions on one side of the one-to-many or many-to-many association, and the same configuration is automatically applied on the other side. If this does not fit your requirements, you can always configure permissions explicitly.