Ash FrameworkAF
Ash Framework8mo ago
41 replies
Ege

Policies: authorize if user is an admin of the requested resource's organization

I have a group resource with these relationships:
belongs_to :educator, User do
  source_attribute :educator_id
  destination_attribute :id
end

belongs_to :organization, Organization

And an organization resource with these:
belongs_to :parent_organization, Organization

has_many :child_organizations, Organization do
  source_attribute :id
  destination_attribute :parent_organization_id
end

And a user resource with this:
many_to_many :organizations, Organization do
  through OrganizationMember
  source_attribute_on_join_resource :user_id
  destination_attribute_on_join_resource :organization_id
end

And this read action:
read :groups_for_organization do
  argument :organization_id, :uuid, allow_nil?: false

  prepare fn query, _ ->
    Ash.Query.before_action(query, fn query ->
      organization_id = query.arguments.organization_id
      descendants = Organization.get_descendant_organizations!([organization_id])
      ids = [organization_id | Enum.map(descendants, & &1.id)]
      Ash.Query.filter(query, organization_id in ^ids)
    end)
  end

  pagination offset?: true, countable: true, default_limit: 1000
end

I'm trying to write a policy that applies to read actions like the above that only shows groups that:

a) the educator is the owner of
b) the educator is an admin inside the group that the organization belongs to

I got the first one working, but the second bit I don't know how to go about. Basically a policy that checks the group's organization_id and then checks the actor's organization_memberships, finds that org with that id and checks to see if the
role
attribute on it is
admin
.
policies do
  policy action_type(:read) do
    description "Can only view a dashboard group if owner/creator of the dashboard group or admin of organization"
    authorize_if relates_to_actor_via(:educator)
    authorize_if ???
  end
end
Was this page helpful?