{
  "filename": "Controllers/OrdersController.cs",
  "rule": "- name: resource-authorization-before-save\n  where: \"Controllers/OrdersController.cs\"\n  ensure: >-\n    If resource authorization fails, Cancel must return Forbid before changing the order or calling SaveChangesAsync.",
  "corrected": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFrameworkCore;\n\n[Authorize]\npublic class OrdersController(AppDbContext db, IAuthorizationService authorization) : ControllerBase {\n    [HttpPost(\"orders/{id}/cancel\")]\n    public async Task<IActionResult> Cancel(Guid id, CancellationToken cancellationToken) {\n        var order = await db.Orders.SingleOrDefaultAsync(x => x.Id == id, cancellationToken);\n        if (order is null) return NotFound();\n        var allowed = await authorization.AuthorizeAsync(User, order, \"CancelOrder\");\n        if (!allowed.Succeeded) return Forbid();\n        if (order.Status != \"pending\") return Conflict();\n        order.Status = \"cancelled\";\n        await db.SaveChangesAsync(cancellationToken);\n        return NoContent();\n    }\n}\n",
  "broken": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFrameworkCore;\n\n[Authorize]\npublic class OrdersController(AppDbContext db, IAuthorizationService authorization) : ControllerBase {\n    [HttpPost(\"orders/{id}/cancel\")]\n    public async Task<IActionResult> Cancel(Guid id, CancellationToken cancellationToken) {\n        var order = await db.Orders.SingleOrDefaultAsync(x => x.Id == id, cancellationToken);\n        if (order is null) return NotFound();\n        var allowed = await authorization.AuthorizeAsync(User, order, \"CancelOrder\");\n        if (order.Status != \"pending\") return Conflict();\n        order.Status = \"cancelled\";\n        await db.SaveChangesAsync(cancellationToken);\n        return NoContent();\n    }\n}\n",
  "regression": [
    "        if (!allowed.Succeeded) return Forbid();\n",
    ""
  ],
  "test_scenarios": [
    [
      "Owned pending order",
      "Policy succeeds then save"
    ],
    [
      "Authenticated unauthorized owner",
      "Forbid, no setter/save"
    ],
    [
      "Missing order",
      "NotFound"
    ],
    [
      "Nonpending state",
      "Conflict after authorization"
    ]
  ],
  "test_source": null,
  "test_command": "dotnet test --filter OrdersControllerAuthorizationTests"
}