Simple policy checks based with relationships

Hello, friends!

So on the website documentation, we have an example of a simple policy check:
  # we're inside of a module here
  def match?(%MyApp.User{age: age} = _actor, %{resource: MyApp.Beer} = _context, _opts) do
    age >= 21
  end


All well and good, but in a more real world example we'd probably have:

- Roles for Users
- Many permissions for those roles
- Potentially many permissions for users

So let's say we have something like the following:

A User resource:

defmodule MyApp.Accounts.User do
  @moduledoc """
  Close to a real world example of a basic users, but 
  obviously there's a lot more stuff here. 
  Shortened for the sake of brevity.
  """
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [AshAuthentication]

  postgres do
    table "app_users"
    repo MyApp.Repo
  end

  attributes do
    uuid_primary_key :id
    attribute :first_name, :ci_string, allow_nil?: false
    attribute :last_name, :ci_string, allow_nil?: false
    attribute :email, :ci_string, allow_nil?: false, sensitive?: true
    attribute :hashed_password, :string, allow_nil?: false, sensitive?: true
    
    create_timestamp(:created_at)
    update_timestamp(:updated_at)
  end

  relationships do
    has_one :role, MyApp.Accounts.Role
    many_to_many :permissions, MyApp.Accounts.User do
      through MyApp.Accounts.UserPermission
      source_attribute_on_join_resource :user_id
      destination_attribute_on_join_resource :permission_id
    end
  end

And you want to check both the role, the permissions a role has and user permissions.

My question would be how do we go about doing the simple policy checks when we have a role-permission setup like this? Because the check itself isn't complex, it's more of a "how do we get there" question.
Was this page helpful?