Accessing session parameters in Pundit policy
Asked Answered
M

1

11

It appears that Pundit policy does not access session parameters. As constructs does not reconize session as a valid variable or method. Is there any way to access session or other params?

class MyModelPolicy
  def create?
    @contructs = Construct.where(['id = ?', session[:construct_id]]).all
  end
end
Muscarine answered 3/12, 2013 at 21:51 Comment(2)
Where is this line in your code? A controller?Griqua
Sorry, missed your comment. The line would be in the ModelName_policy.rb.Muscarine
G
26

I'm a contributor to Pundit. Policies by default only has access to the current user and the record you're checking permissions for.

You can use the context pattern defined in the Pundit docs. Start with creating a user context class in your app/model directory accepting all the contextual parameters you need, in this case session.

class UserContext
  attr_reader :user, :session

  def initialize(user, session)
    @user = user
    @session = session
  end
end

Then you can override the user record used by pundit with an instance of your UserContext class.

class ApplicationController
  include Pundit

  def pundit_user
    UserContext.new(current_user, session)
  end
end

Finish by making your application policy accept the context. If you want to stay compliant with your old policies, delegate those methods to the context.

class ApplicationPolicy
  attr_reader :context, :user, :session

  def initialize(context, record)
    @context = context
    @record = record
  end

  delegate :user, to: :context
  delegate :session, to: :context

  ...

end

Now you can access session inside your policies.

Griffis answered 15/1, 2015 at 13:58 Comment(3)
What about providing additional context to scopes? def index; resources = ContextPolicy::Scope.new(current_user, context).resolve; end works but after_action :verify_policy_scoped, only: :index triggers Pundit::PolicyScopingNotPerformedError. Could I make it work within the Pundit mindset?Luciano
@Luciano If you use a wrapping class for your user (in this case user context), that context instance will be available inside your policy scope just as it is inside the authorisation methods.Griffis
You're missing the attr_reader for the record. +1 for the answerConcha

© 2022 - 2024 — McMap. All rights reserved.