Dan F.
Dan F.

Reputation: 345

Pundit headless policy for nested resource

How can I authorize an action from a controller without a model based on another model object?

Let's say I have a model called Server and I have a nested controller called config_files_controller which doesn't have a corresponding model.

I want to be able to authorize the actions from the config_files_controller based on a Server object and current user and the policies defined for Server.

In routes.rb I have:

resources :servers do
  resources :config_files do
    collection do
      get 'load_file'
    end
  end
end

The config_files_controller.rb looks something like this:

class ConfigFilesController < ApplicationController
  before_filter :authenticate_user!
  before_filter :load_server

  def index
    # displays file names
  end

  def load_file
    # gets file content
  end

  private

  def load_server
    @server = Server.find(params[:server_id])
    authorize :config_file, "#{action_name}?"
  end
end

In configuration_file_policy.rb I would like to have something like this:

class ConfigurationFilePolicy < Struct.new(:user, :configuration_file, :server)
  def index?
    ServerPolicy.new(user, server).show?
  end

  def load_file?
    ServerPolicy.new(user, server).update?
  end
end

I'm probably missing something or I'm just not seeing the obvious solution. Any suggestion would be appreciated!

Thanks!

Upvotes: 1

Views: 487

Answers (1)

mgrim
mgrim

Reputation: 1302

Your controller sets @server object, and Server seems to be a model. Hence it should be sufficient to authorize that. (No need for ConfigurationFilePolicy.)

config_files_controller.rb

...

def index
  authorize @server, :show?
  # displays file names
  ...
end

def load_file
  authorize @server, :update?
  # gets file content
  ...
end

https://github.com/elabs/pundit#policies

Upvotes: 2

Related Questions