This is a XAF Framework module that generates C# code from your security permissions, roles, and related objects. This enables a code-first approach to managing XAF security, making it easy to migrate permissions between environments and maintain them in source control.
You are developing an XAF application and you want to be able to define roles and permissions using the standard XAF Role editor UI, and then generate C# code that represents those roles and permissions. This code can then be included in your code base, allowing you to:
- Recreate permissions on new debug instances - Useful when you frequently delete and recreate your development database
- Deploy to production - Apply the same roles and permissions to production or staging environments
- Unit testing - Create consistent permission setups for automated tests
- Version control - Track permission changes using standard source control diff tools
- Copy between instances - You can do the opposite: after fine-tuning permissions on a production instance, export the changes back to the code base.
- Full Permission Support - Generates code for Type Permissions, Object Permissions, Member Permissions, Navigation Permissions, and Denied Action Permissions
- Export & Apply - Export permissions from role UI to code, then apply code-defined permissions to any environment (replacing existing permissions)
- Version Control Friendly - Track permission changes using standard source control diff tools
- Multi-Platform - Supports both EF Core and XPO database providers
- UI Framework Agnostic - Works with both Blazor, Desktop and WinForms XAF applications
Install the NuGet package that matches your DevExpress XAF version:
For DevExpress 25.2.x:
dotnet add package Hakakou.Xaf.PermissionCodeGenerator-dx25-2For DevExpress 25.1.x:
dotnet add package Hakakou.Xaf.PermissionCodeGenerator-dx25-1For DevExpress 24.2.x:
dotnet add package Hakakou.Xaf.PermissionCodeGenerator-dx24-2For DevExpress 24.1.x:
dotnet add package Hakakou.Xaf.PermissionCodeGenerator-dx24-1For DevExpress 23.2.x:
dotnet add package Hakakou.Xaf.PermissionCodeGenerator-dx23-2For DevExpress 23.1.x:
dotnet add package Hakakou.Xaf.PermissionCodeGenerator-dx23-1Add the module to your XAF Module project's Module.cs file:
using Hakakou.Xaf.PermissionCodeGenerator;
public sealed class YourApplicationModule : ModuleBase
{
public YourApplicationModule()
{
// ... existing code ...
RequiredModuleTypes.Add(typeof(PermissionCodeGeneratorModule));
}
}- Run your application and login as an Administrator (user must have
IsAdministrativeset totrue) - Go to the Role page. You'll see two new toolbar buttons: "Permission Generator" and "Permission Apply"
- Configure your roles and permissions using the standard XAF Role editor UI
- Click "Permission Generator" to open a view with the generated C# code
- Copy the generated code to the clipboard
- Create a file named
UpdatePermissionsClass.csin yourDatabaseUpdatefolder - Paste the generated code into the file (or replace it all in any next iterations you do)
Assume you delete the database, or want to deploy the roles on a production instance.
Login as Administrator on the target environment and click the "Permission Apply" button.
Add the following to your DatabaseUpdate/Updater.cs file:
using Hakakou.Xaf.PermissionCodeGenerator;
public override void UpdateDatabaseAfterUpdateSchema()
{
base.UpdateDatabaseAfterUpdateSchema();
#if DEBUG
// In Release mode, always update permissions. In Debug, only for a new install.
if (!ObjectSpace.GetObjectsQuery<PermissionPolicyRole>().Any())
#endif
{
new UpdatePermissionsClass().UpdatePermissions(ObjectSpace);
}
var defaultRole = ObjectSpace.FindRole<PermissionPolicyRole>("Default");
var adminRole = ObjectSpace.FindRole<PermissionPolicyRole>("Administrators");
#if !RELEASE
// You can comment the following code out.
// var defaultRole = CreateDefaultRole();
// var adminRole = CreateAdminRole();
// ObjectSpace.CommitChanges();
// Rest of the code to create first-time users.
#endif
// Rest of custom update code...
}Notes for the recommended code above
- In
DEBUGmode, permissions are only updated if there are no roles in the database. This is useful if you often delete the database while developing, or create temporary databases during unit testing. However roles and permissions you have modified will not be overwritten on subsequent runs (like when developing and testing roles) - In
RELEASEmode, permissions are always updated.
As an administrator on a deployed instance or production system, you might modify roles and permissions to quickly address a business need. Later, you might want to bring those changes back into your code base:
- On the production environment, after modifying roles, click "Permission Generator"
- Copy the generated code
- Replace the contents of your
UpdatePermissionsClass.csfile
This way, you can synchronize your code base with the changes made on the deployed instance.
Implement the following partial methods to add custom logic before or after the permission update:
public partial class UpdatePermissionsClass
{
partial void BeforeUpdate(IObjectSpace os)
{
// Custom logic before permissions are applied
}
partial void AfterUpdate(IObjectSpace os)
{
// Custom logic after permissions are applied
// For example, purge deleted permission records
var db = os.ServiceProvider.GetService<ExampleEFEFCoreDbContext>();
PermissionSettingHelpers.PurgeDeletedPermissionRecords(q =>
db.Database.ExecuteSqlRaw(q));
}
}In namespace Hakakou.Xaf.PermissionCodeGenerator.Extensions, the following extension methods are available for IObjectSpace:
| Method | Description |
|---|---|
FindRole<TRole>() |
Finds a role by its name |
EnsureRole<TRole>() |
Finds or creates a role with the specified name, permission policy, and administrative status |
DeleteAllPermissions() |
Removes all type, navigation, and action permissions from a role |
AddNavigationPermissionCheck() |
Adds a navigation permission to a role with validation against the application model |
EnsureMemberPermission() |
Ensures a member permission exists for a type permission; returns existing or creates new |
PurgeDeletedPermissionRecords() |
Purges soft-deleted permission records from the database |
You can find two example Blazor projects in the repository: ExampleEF.Blazor.Server and ExampleXPO.Blazor.Server, demonstrating the usage of the PermissionCodeGenerator module with Entity Framework Core and XPO respectively.
To run, the first time start with debugging enabled to have the ORM create the database and seed initial data. This also demonstrates the automatic application of permissions during database update (see the roles of the Products business object).
To login, use usernames Admin or User with an empty password.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Harry Kakoulidis