Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 25 Nov 02:46
· 13 commits to main since this release
b9e05d2

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

⚠️ Breaking Changes

  1. 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();
}
}

  1. Old API Marked as Obsolete

The following methods are deprecated (still work but generate warnings):

// ⚠️ Deprecated
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?

  1. Security: Mandatory validation ensures you don't forget to configure an action
  2. Readability: Specific methods are clearer than generic enums
  3. Explicit > Implicit: .ForAllFields() makes it clear when you want full access
  4. Flexibility: Block* methods allow read-only policies in a clear way
  5. 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