Skip to content

49 improve authorization of create actions#48

Merged
dawidsawczuk merged 4 commits into
mainfrom
55-improve-authorization-of-create-actions
Apr 27, 2026
Merged

49 improve authorization of create actions#48
dawidsawczuk merged 4 commits into
mainfrom
55-improve-authorization-of-create-actions

Conversation

@dawidsawczuk
Copy link
Copy Markdown
Contributor

@dawidsawczuk dawidsawczuk commented Mar 4, 2026

Pull Request

Description

This PR introduces authorize_with_transaction for controller create flows that need post insert authorization checks.

Final behavior in this PR:

  • authorize_with_transaction returns only {:ok, value} or {:error, reason}
  • Unauthorized post-create checks are returned as {:error, conn} (after calling unauthorized handler)
  • Optional :on_unauthorized handler can override handle_unauthorized/2 for this flow

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring
  • Test improvements
  • CI/CD improvements

Related Issues

Closes #49.

Changes Made

  • Added authorize_with_transaction/2,3 callback API and default implementation in Permit.Phoenix.Controller (Ecto enabled path).
  • Added transactional post create authorization verification with rollback on unauthorized records.
  • Added optional :action override support for authorization context.
  • Added optional :on_unauthorized option to customize unauthorized handling for this flow.
  • Simplified return contract from {:ok, _} | {:error, _} | {:unauthorized, conn} to {:ok, _} | {:error, _}.
  • Updated docs/examples and callback specs to reflect the simplified return contract.
  • Updated test support controller matching to distinguish:
    • {:error, %Ecto.Changeset{}} (validation)
    • {:error, conn} (unauthorized)
  • Added integration tests covering success, validation failure, unauthorized rollback, action override, and custom unauthorized handling.
  • Added test helper DB sequence adjustment to avoid PK collisions in insertion-heavy tests.

Testing

Test Environment

  • Elixir version: 1.18.4
  • OTP version: 28
  • Phoenix version: 1.8.1
  • LiveView version: 1.1.17
  • Database (if applicable): PostgreSQL

Test Cases

  • All existing tests pass
  • New tests added for new functionality at appropriate levels
  • Manual testing performed
  • Controller integration tests (if applicable)
  • LiveView integration tests (if applicable)
  • Router integration tests (if applicable)

Test Commands Run

# List the commands you ran to test
mix test
MIX_ENV=test mix credo
MIX_ENV=test mix dialyzer

Documentation

  • Updated README.md (if applicable)
  • Updated documentation comments (with examples for new features)
  • Updated CHANGELOG.md (if applicable)
  • Updated controller/LiveView usage examples (if applicable)

Code Quality

  • Code follows the existing style conventions
  • Self-review of the code has been performed
  • Code has been commented, particularly in hard-to-understand areas
  • No new linting warnings introduced
  • No new Dialyzer warnings introduced
  • Follows Phoenix and LiveView conventions

Phoenix/LiveView Specific

  • Controller changes properly handle conn state
  • LiveView changes properly handle socket state
  • Router integration works correctly
  • Error handling follows Phoenix patterns
  • Authorization flows work as expected

Backward Compatibility

  • This change is backward compatible
  • This change includes breaking changes (please describe below)
  • Migration guide provided for breaking changes

Breaking Changes

Performance Impact

  • No performance impact
  • Performance improvement
  • Potential performance regression (please describe)

Performance Notes

Security Considerations

  • No security impact
  • Security improvement
  • Potential security impact (please describe)

Additional Notes

Screenshots/Examples

def create(conn, %{"item" => params}) do
  case authorize_with_transaction(
         conn,
         fn -> Repo.insert(Item.changeset(%Item{}, params)) end,
         on_unauthorized: fn _action, conn ->
           conn
           |> put_flash(:error, "Custom denied.")
           |> redirect(to: "/custom_denied")
           |> halt()
         end
       ) do
    {:ok, item} -> text(conn, "created item #{item.id}")
    {:error, %Ecto.Changeset{} = changeset} -> render(conn, :new, changeset: changeset)
    {:error, conn} -> conn
  end
end

Checklist

  • I have read the Contributing Guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Reviewer Notes


@dawidsawczuk dawidsawczuk marked this pull request as ready for review March 6, 2026 13:31
Comment thread lib/permit_phoenix/controller.ex
@vincentvanbush vincentvanbush changed the title 55 improve authorization of create actions 49 improve authorization of create actions Mar 10, 2026
@dawidsawczuk dawidsawczuk merged commit 458077e into main Apr 27, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Improve authorization of create actions

3 participants