Custom strategy for warden not getting called - devise

I am trying to use a different warden strategy to authenticate my action cable end points.
But the strategy is not getting called. I tried to place warden.authenticate!(:action_cable_auth) in a controller to test but none of the debug statements are getting printed on console.
Below are the relevant part of the code.
config/initializers/warden.rb
Warden::Strategies.add(:action_cable_auth) do
def valid?
#check if its a websocket request & for action cable?
#Rails.logger.error request.inspect
p 'checking if strategy is valid?'
true
end
def authenticate!
p 'unauthenticate the user'
fail!('user not active')
end
end
in my controller
warden.authenticate!(:action_cable_auth)

Assuming that you are setting your initializer in the proper place, please recall that if your session is already instantiated somewhere else (for example if you authenticate the user at the point your action is being called, then your strategy will never be called.
This is basically how warden works: if some valid? strategy returns a success! then no other will be called as soon as any authenticate! method in the list of strategies is successful.
Please also be sure that if you want your strategy up the list of strategies to check you may need to also shift it up on the list, such as:
manager.default_strategies(scope: :user).unshift(:action_cable_auth)
Where the manager is your Warden::Manager instance. The scope may also be optional (this is an example where the user scope is used alongside Devise), but you may check your instance .default_strategies to figure out where it is and where you want it.

Related

Using variable values within different scenarios in a feature, capybara

I have a feature with 4 scenarios. I would like to use the value of 1 variable I set in scenario 1 across different steps and in Scenario 2.
I use $ but this is not set. I am assuming $ value remains the same across a feature
When(/^the user goes to manageusers, picks one of the secondary users$/) do
click_link "Admin"
click_link "Manage Users"
emailofuser=ENV["email"].to_s
atpos = emailofuser.index('#')
emailofuser = emailofuser[0,atpos]
page.body.to_s.scan(/<td>(.*?)#ABC.com<\/td>/).flatten().each do |w|
if "#{w}" != emailofuser
$secondaryUserEmail = "#{w}" + "#ABC.com"
break
end
end
end
When(/^the secondary user logs in with password "([^"]*)"$/) do |arg|
if getURL != URI.parse(current_url)
visit getURL
end
find(:xpath,"//input[#id='user_email']").set($secondaryUserEmail )
fill_in "user_password", :with => arg
click_button "Sign in"
end
In the Above Step, the steps are in 1 scenario in a feature file and I also have the same step secondary user in Scenario 2 within a feature. the variable $secondaryuserEmail some times does not get set and login as a secondary user fails.
Whats the best way for me to declare variables that I can access across steps within a scenario and across scenarios within a feature.
You should find out why $secondaryuserEmail does not get set. That sounds like a bug somewhere in the app you're testing. If it's not a bug, you should try to handle the exception.
To your original question, it might be a good idea to set variables in helper methods, then call these methods to access them using instance variables. Most people generally recommend against sharing variables across scenarios but I've used helper methods in order to store variables throughout my specs that normally go unchanged.

Storing Rails controller callback data in session

The idea is:
Perform some time consuming action in background.
Have the results from that action be propagated back to the controller using a callback.
Store the result in an in memory session store.
Have the result in session be used and available from that point onward.
Controller receives the results in the callback:
# controller callback, saves result to session
# this method is executed as expected
# session id matches the one from other controller actions
def on_counter_value_calculated(context, new_value)
#counter = new_value
session[:counter] = #counter
end
However, stored session is lost in subsequent calls:
# although the same session is targeted (same id)
# the saved value is not the same
def index
#counter = session[:counter] || 0
end
I've created a small Rails project that demonstrates the issue:
https://github.com/elvanja/controller_callbak_store_in_session
Any input appreciated.
Checked Rails code, and if I understand correctly, session in fact comes from request:
# actionpack-3.2.11/lib/action_controller/metal.rb:132
delegate :session, :to => "#_request"
It seems session is valid only within request cycle context and although it can be accessed, the changes are not saved, as demonstrated by the project.
Hence, this will not work. As suggested # Ruby on Rails Google Group and Ruby Rogues, the best way to deal with this is to use Sidekiq, DelayedJob, Resque or similar frameworks.
EDIT: Access `session` within rails controller thread is actually the reason (background processing in the example is done in a separate thread).

Active Admin calling original and overriden create action

I am seeing some odd behaviour when trying to override the create action on an Active Admin resource. My reason for overriding the action is that I want to alter the request params slightly first.
ActiveAdmin.register User do
controller do
def create
format_params
create!
end
def update
format_params
update!
end
def format_params
params[:user] = ...
end
end
end
What I am seeing is that a create action is being invoked twice - but only on the second time is it my overridden version. By that point, the new record is already created, albeit incorrectly, and the second invoking (which is the overridden version) looks like a duplicate resource.
If I empty the custom #create action and leave only a logging statement, I can see that a record is still being created prior to it being invoked, almost as if there is some sort of before_ callback, although I can't find any such thing in the code.
Even more odd - everything works fine on the overridden #update method - the params are altered and the original #update! method delegated to correctly.
I am using Active Admin 0.5.1 on Rails 3.2.13
Cheers

Stub method called from constructor when using Fabrication

I've got the following model
class User < ActiveRecord::Base
before_create :set_some_values
private
def set_some_values
#do something
end
end
In specs I'm using Fabrication gem to create objects but I can't find a way to stub the set_some_values method. I tried
User.any_instance.stub!(:set_some_values).and_return(nil)
but Fabrication seems to ignore this. Is it possible to do?
This is why I don't like ActiveRecord callbacks -- because if you want to have nothing to do with a callback (because, say, you're making a call to an external service inside the callback) you still have to be concerned about stubbing it out. Yes you could stub out methods inside the callback, but it's the same problem, and actually it's a bit worse because now you are concerned about something inside a method you want nothing to do with.
As usual there are multiple options here.
One option which I've used a lot in the past is, add a condition to your callback that turns it off by default. So your Post class could look like:
class Post
before_save :sync_with_store, :if => :syncing_with_store?
def syncing_with_store?; #syncing_with_store; end
attr_writer :syncing_with_store
def sync_with_store
# make an HTTP request or something
end
end
Now wherever you really want to call the callback (perhaps in your controller or wherever), you can set post.syncing_with_store = true before you call post.save.
The downside to this approach is, it's something that you (and other devs working with you) have to keep in mind, and it's not really obvious that you have to do this. On the other hand, if you forget to do this, nothing bad happens.
Another option is to use a fake class. Say you have a Post that pushes its data to an external data store on save. You could extract the code that does the pushing to a separate class (e.g. Pusher) which would be accessible at Post.pusher_service. By default, though, this would be set to a fake Pusher class that responds to the same interface but does nothing. So like:
class Post
class << self
attr_accessor :pusher_service
end
self.pusher_service = FakePostPusher
before_save :sync_with_store
def sync_with_store
self.class.pusher_service.run(self)
end
end
class FakePostPusher
def self.run(post)
new(post).run
end
def initialize(post)
#post = post
end
def run
# do nothing
end
end
class PostPusher < FakePostPusher
def run
# actually make the HTTP request or whatever
end
end
In your production environment file, you'd set Post.pusher_service = Pusher. In individual tests or test cases, you'd make a subclass of Post -- let(:klass) { Class.new(Post) } -- and set klass.pusher_service = Pusher (that way you don't permanently set it and affect future tests).
The third approach, which I have been experimenting with, is this: simply don't use ActiveRecord callbacks. This is something I picked up from Gary Bernhardt's screencasts (which, by the way, are pretty amazing). Instead, define a service class that wraps the act of creating a post. Something like:
class PostCreator
def self.run(attrs={})
new(attrs).run
end
def initialize(attrs={})
#post = Post.new(attrs)
end
def run
if #post.save
make_http_request
return true
else
return false
end
end
def make_http_request
# ...
end
end
This way PostCreator.run(attrs) is the de facto way of creating a post instead of going through Post. Now to test saves within Post, there's no need to stub out callbacks. If you want to test the PostCreator process, there's no magic going on, you can easily stub out whichever methods you want or test them independently. (You could argue that stubbing out methods here is the same as stubbing out AR callbacks, but I think it's more explicit what's going on.) Obviously this only handles post creation, but you could do the same for post updating too.
Anyway, different ideas, pick your poison.
The #set_some_values method here is called when you call #save on the record. So it has nothing to do with the constructor and therefore you don't need to stub User.any_instance -- just make your record and then do a partial stub, as in:
record.stub(:set_some_values)
record.save

Rails3: Make update/create fail from model?

There's got to be an easy way to do this, but I cannot find an answer...
When some creates or updates a WorkRequest in my app, I do other processing, including creating a Workflow object. I do some checking to make sure, for example, there isn't more than one Workflow already created for this WorkRequest. If there is, I want the update/create to fail with an error message. I just can't see how to do this. I tried returing false from my before_update callback method, but this did not work.
Do I raise an error and rescue it in my controller? What is the right way to do this in Rails 3?
Any help would be much appreciated.
This is why you have validations. You can implement an own validation like this:
class ...
validate :my_validation
def my_validation
if workflows > 1
errors.add(:workflow, "cannot be more than one" )
end
end
end