Repository navigation
v0.2.0
CHANGELOG - v0.2.0
🎉 New Features
Verb-Specific Permission Methods
Use direct, more readable methods to configure permissions:
// New API - cleaner and more direct
AllowRead("Admin", "Support");
AllowCreate("Admin");
AllowUpdate("Admin");
AllowDelete("Admin");
Simplified Anonymous Access
AllowAnonymousRead(); // Anyone can read
AllowCreate("Admin"); // Only Admin can create
Block Methods - Explicit Denial
Block actions you don't want to allow:
AllowRead("Support", "Admin");
BlockCreate(); // Nobody can create
BlockUpdate(); // Nobody can update
BlockDelete(); // Nobody can delete
ForAllFields - Explicit Field Control
AllowRead("Admin").ForAllFields(); // Admin sees everything
AllowRead("Support").ForFields(p => p.Id, p => p.Name); // Support sees only ID and Name
Complete Soft Delete
Configure logical deletion with flag and timestamp:
// Flag only
AllowDelete("Admin").DeleteWithColumn(p => p.Deleted);
// Flag + UTC timestamp
AllowDelete("Admin").DeleteWithColumn(p => p.Deleted, p => p.DeletedAt, useUtc: true);
// Flag + local timestamp
AllowDelete("Admin").DeleteWithColumn(p => p.Deleted, p => p.DeletedAt, useUtc: false);
Soft delete automatically:
- Excludes deleted records from read queries
- Returns error when trying to delete already-deleted entities
- Sets timestamp when deleting
- Mandatory Configuration of All CRUD Actions
Before: You could configure only some actions.
Now: You MUST configure all 4 actions (Create, Read, Update, Delete).
// ❌ This now throws InvalidOperationException
public class ProductPolicy : CrudPolicy
{
public ProductPolicy()
{
AllowRead("Admin");
// Missing Create, Update, Delete!
}
}
// ✅ Correct
public class ProductPolicy : CrudPolicy
{
public ProductPolicy()
{
AllowRead("Admin");
AllowCreate("Admin");
AllowUpdate("Admin");
AllowDelete("Admin");
}
}
// ✅ Or explicitly block
public class ReadOnlyPolicy : CrudPolicy
{
public ReadOnlyPolicy()
{
AllowRead("Admin");
BlockCreate();
BlockUpdate();
BlockDelete();
}
}
- Old API Marked as Obsolete
The following methods are deprecated (still work but generate warnings):
//
Allow(CrudAction.Read).ForRoles("Admin");
AllowAnonymous(CrudAction.Create);
// ✅ Use this instead
AllowRead("Admin");
AllowAnonymousCreate();
🔄 Quick Migration Guide
Complete Example
Before (v0.0.x):
public class ProductPolicy : CrudPolicy
{
public ProductPolicy()
{
Allow(CrudAction.Read).ForRoles("Support").ForFields(p => p.Id, p => p.Name);
Allow(CrudAction.Read).ForRoles("Admin");
Allow(CrudAction.Create).ForRoles("Admin", "Support");
Allow(CrudAction.Update).ForRoles("Admin");
Allow(CrudAction.Delete).ForRoles("Admin");
}
}
After (v0.2.0):
public class ProductPolicy : CrudPolicy
{
public ProductPolicy()
{
AllowRead("Support").ForFields(p => p.Id, p => p.Name);
AllowRead("Admin").ForAllFields();
AllowCreate("Admin", "Support").ForAllFields();
AllowUpdate("Admin");
AllowDelete("Admin");
}
}
📋 Migration Checklist
- All policies configure the 4 CRUD actions (or use Block*)
- Replace Allow(CrudAction.X) with AllowX()
- Replace AllowAnonymous(CrudAction.X) with AllowAnonymousX()
- Add .ForAllFields() where there was full field access
- Test that everything compiles without warnings
- Run tests
🔍 Quick Reference
New Permission Methods
- AllowRead(params string[] roles)
- AllowCreate(params string[] roles)
- AllowUpdate(params string[] roles)
- AllowDelete(params string[] roles)
New Anonymous Methods
- AllowAnonymousRead()
- AllowAnonymousCreate()
- AllowAnonymousUpdate()
- AllowAnonymousDelete()
New Block Methods
- BlockRead()
- BlockCreate()
- BlockUpdate()
- BlockDelete()
Chainable Methods
- .ForFields(params Expression<Func<TEntity, object>>[] fields) - Specific fields
- .ForAllFields() - All fields (Read/Create only)
- .DeleteWithColumn(...) - Soft delete (Delete only)
💡 Why These Changes?
- Security: Mandatory validation ensures you don't forget to configure an action
- Readability: Specific methods are clearer than generic enums
- Explicit > Implicit: .ForAllFields() makes it clear when you want full access
- Flexibility: Block* methods allow read-only policies in a clear way
- Type Safety: Passing roles directly eliminates the need for .ForRoles() chaining
📚 Documentation Updates
Check out the updated wiki pages:
- Configuration-Builder-Services - Updated with new API examples
- Delete - New soft delete documentation
- Migration-Guide - Detailed migration instructions
- Real-World-Case - Updated end-to-end example
🐛 Bug Fixes
- Fixed field projection masking for Create operations
- Improved error messages for missing action configurations
- Better validation of soft delete column expressions