ActionController::InvalidAuthenticityToken in ActiveAdmin::Devise::SessionsController#create - authentication

I'm using Ruby on Rails 5 Api app with modification to enable Active Admin.
Everything was fine until now. I don't remember doing any changes in the app, but now, if I delete cookies and etc on the browser, I can't login to the active admin app and this error is what I get:
I tried to add in application controller both
protect_from_forgery :with => :exception
and
protect_from_forgery :with => :null_session
but none have worked.
This is my application controller:
class ApplicationController < ActionController::Base
# protect_from_forgery :with => :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
attributes = [:name]
devise_parameter_sanitizer.permit(:sign_up, keys: attributes)
end
end
I don't know what causing it and how to solve it.
Thanks beforehand.

Now it's working. After I restart my computer and added the line:
protect_from_forgery prepend: true, with: :exception
instead in the application controller, it worked.

It happens to me a lot when I switch from a branch to another without restarting my server.
Restarting the rails server works for me each time :)

In my context, I have a custom admin page and to solve I put a authenticity_token hidden field. Like below:
form method: :post, action: admin_templates_save_template_path do |f|
f.label "label", for: :base_proposal_url
f.input id: :base_proposal_url, name: :base_proposal_url
### field to handle authenticity token
f.input type: :hidden, name: :authenticity_token
f.button "Save", type: :submit
end

Related

Ruby on Rails - CanCan user is nil during destroy action

I'm getting cancan with devise wired into my first Ruby on Rails app. I have some of it working, but I hit a problem my newbie brain cannot seem to understand.
I'm trying to delete a project model. The cancan ability.initialize call is not working because the user is passed as nil even though I am logged in and other calls successfully authorize
In my show view, I have this link:
<%= link_to "Purge this project", #project, method: :delete, data: {confirm: "There is no way to get it back. Are you sure you want to permanently remove this project?"} %>
I think my controller is wired up correctly, other actions are properly authorized
class ProjectsController < ApplicationController
load_and_authorize_resource
...
def destroy
puts "***********removing: " + params.inspect
#project.destroy
...
end
My cancan initialize does this:
def initialize(user)
user ||= User.new # guest user
puts "******** Evaluating cancan permissions for: " + user.inspect
...
When I click the delete link above, this gets puts'ed to the console (notice how user.id is nil, this is caused because i setup the guest if user is nil)
******** Evaluating cancan permissions for: #<User id: nil, email: ""...
Started DELETE "/projects/16" for 127.0.0.1 at 2013-04-04 10:48:23 -0400
Processing by ProjectsController#destroy as HTML
Parameters: {"id"=>"16"}
WARNING: Can't verify CSRF token authenticity
PROBLEM: Why is the user nil??? Is it related to the CSRF token issue? Is there something special about http method=delete that I'm missing? How can I stop the dumb, it hurts?
The preceding "show" action yielded this expected puts (concluding stuff should be wired up sufficiently):
******** Evaluating cancan permissions for: #<User id: 2, email: "doug...
Thanks!
self answer warning! So, I guess delete actions need to happen within a form post in order for the identity and CSRF stuff to be handled correctly?!?
Replacing my link with a form made things work again:
<%= form_for #project, :method => :delete do %>
<%= submit_tag "Purge this project", confirm: "Are you sure you want to permanently remove this project?" %>
<% end %>

Cant delete object after installing devise & cancan

I installed Devise and Cancan. My user has role super_admin with options shown below:
def initialize(user)
user ||= User.new # guest user
can :manage, :all
end
all works well except deleting elements. When I'm trying to delete object:
<%= link_to 'Destroy', place, :method => :delete, :data => { :confirm => 'Are you sure?' } %>
it keeps logging me out and redirecting to sign_in page
My class looks like that:
class PlacesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
Ok, I figured it out.
My layout file did not have authenticity_token tag
<%= csrf_meta_tag %>
so POST and DELETE requests couldn't have been authenticated.

Rails 3 - authenticate and :before_filter

I am a newbie in Rails. I try to build a simple authenticate system, to application_controller I put following lines:
def check_session
if session[:user]
if session[:expiry_time] < 10.minutes.ago
reset_session
flash[:warning] = 'You was logout.'
redirect_to root_url
else
session[:expiry_time] = Time.now
end
else
#... authenticate
session[:expiry_time] = Time.now
flash[:warning] = 'You was logout.'
redirect_to root_url
end
end
My problem is in one action - in this action I check, if the user is log in or not. And if the user is log in, so I will render one template, and if not, so I will render the second one. It looks like:
<% unless session[:user].nil? %>
<%= render :template => 'template_for_login_user' %>
<% else %>
<%= render :template => 'template_for_not_login_user' %>
<% end %>
And here is the problem - this doesn't works me. At least... well - if I am not log in, so will be render the template template_for_not_login_user and if I am, so template_for_login_user. This is right.
But if I am log in and I am on the template_for_login_user, but I am 15min idle => the session will be expired => I should be redirect to login form. But here is the problem - I am 15 minutes idle and I refresh this page, so I am still on the action template_for_login_user - and this is the problem...
I would like to ask you - can you help me please, where could be a problem? What I'm doing wrong?
In your ApplicationController, did you add a line like this :
before_filter :check_session
if some controller action don't need the user to be authenticated, you can add this:
skip_before_filter :check_session, :only=> [:index, :search, etc..]
in this example, this would skip your before_filter :check_session on action : index and search. This way you have a global behavior that always check the session for a user logged on. But you can skip this in particular controller where some actions don't need the user to be authenticated

Rails::Engine namespacing controller and models

I followed the following tutorial: http://www.themodestrubyist.com/2010/03/05/rails-3-plugins---part-2---writing-an-engine/
And it all works great. I namespaced the controller using
#app/controller/authr/accounts_controller.rb
module Authr
class AccountsController < ApplicationController
unloadable
def new
#account = Account.new
end
def create
#account = Account.new(params[:account])
if #account.save
redirect_to '/'
else
render :action => :new
end
end
end
end
And in the tutorial he didn't namespace the model. I want to namespace my model though so it doesn't collide with host apps. So i tried the following:
#app/models/authr/account.rb
module Authr
class Account < ActiveRecord::Base
attr_accessor :password
validates_confirmation_of :password
end
end
This is my view, with a simple form_for that should go to accounts_path
#app/views/authr/accounts/new.html.erb
<%= form_for(#account) do |f|%>
<p>
<%= f.label :uname, "Username"%>
<%= f.text_field :uname%>
</p>
<p>
<%= f.label :password, 'Password'%>
<%= f.password_field :password%>
</p>
<p>
<%= f.submit "Submit"%>
</p>
<% end %>
But when i use my namespaced model i get the following error:
undefined method `authr_accounts_path' for #<#<class:0x1038f54e0>:0x1038f3780>
The object created by the new method (#account = Account.new) results in this :
<Authr::Account id: nil, uname: nil, hashed_password: nil, remember_token: nil, remember_expiry: nil, created_at: nil, updated_at: nil>
Routes file: (This works when i dont namespace the model.)
Rails.application.routes.draw do |map|
resources :accounts, :only => [:new, :create],
:controller => "authr/accounts"
end
So this is a routing thing. When i dont namespace the model all works fine but when i namespace it it doesnt work. Then i tried the following:
#routes.rb
Rails.application.routes.draw do |map|
scope "authr", :module => :authr, :as => "authr" do
resources :accounts
end
end
Now i get the form without the routing error. But when i try to submit the form the object isn't saved.
Started POST "/authr/accounts" for 127.0.0.1 at Mon Mar 28 18:51:12 +0200 2011
Processing by Authr::AccountsController#create as HTML
Parameters: {"commit"=>"Submit", "authenticity_token"=>"cPH8ZmNmgoT84UMnYBoM38di+/OZQmuGQTrSv3HhFR4=", "utf8"=>"✓", "authr_account"=>{"uname"=>"usrrrrrrrrrrrrnmmmmeee", "password"=>"[FILTERED]"}}
SQL (48.0ms) BEGIN
SQL (0.5ms) SHOW TABLES
SQL (13.2ms) describe `accounts`
AREL (0.3ms) INSERT INTO `accounts` (`updated_at`, `created_at`, `remember_expiry`, `uname`, `remember_token`, `hashed_password`) VALUES ('2011-03-28 16:51:12', '2011-03-28 16:51:12', NULL, NULL, NULL, NULL)
SQL (0.4ms) COMMIT
Redirected to http://localhost:3000/
I know that i'm doing #account = Account.new(params[:account]) and if i change it to Account.new(params[:authr_account] that i should work but i want to user params[:account] that should work right? Because the controller is namespaced as well...
Then i found something about isolated_name space so i tried this:
#lib/authr/engine.rb
require "authr"
require "rails"
module Authr
class Engine < Rails::Engine
isolate_namespace Authr
# engine_name :authr #deprecated?
end
end
and i changed my routes to:
Rails.application.routes.draw do |map|
resources :accounts, :only => [:new, :create],
:controller => "authr/accounts"
end
But this gives me the following error:
/Library/Ruby/Gems/1.8/gems/authr3-0.1.0/lib/authr/engine.rb:6: undefined method `isolate_namespace' for Authr::Engine:Class (NoMethodError)
I tried everything and i looked at other gems and they have namespaced models. I am convinced that i need to namespace my models just to be sure that they don't conflict with the host application. I want to use restfullroutes but i don't know how i can fix this problem.
I am using:
Daniel-Zs-MacBook-Pro:gem_test Daniel$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
Daniel-Zs-MacBook-Pro:gem_test Daniel$ rails -v
Rails 3.0.3
Thanks for any advice / help
Possibly a typo?
scope "authr", :module => :authr, :as => "auth" do
change to
scope "authr", :module => :authr, :as => "authr" do #you are missing an r
If its just a typo in this post and you have it correct in the engine, then what do you get when you run "rake routes" from the parent application using that same scope in the engine?
Also, I think isolate_namespace is only in edge rails right now. 3.1 is slated to have alot of new engine goodies including this.

Ruby on Rails call an action I created

I have in my User view Index page a button_to tag as follows:
<%= button_to "Make Admin", :action => :make_admin :user => user %>
In the User controller i have:
def make_admin
#user = User.find(params[:id])
#changed_user.role = 3
#changed_user.save
end
I get a message about bad routing, but since I'm not interested in changing the view until after the action I don't know how to route this action. Where have i gone wrong?
You need to name the path in your routes:
# routes.rb
get 'your_path' => 'user#make_admin, :as => 'make_admin' # can use post too
# controller
def make_admin
# logic to make an admin
redirect_to(some_other_path, :notice => 'User was made an admin')
end
then, in your view,
button_to 'make admin', make_admin_path
You might also want to make the call remotely, but you'll need to post another question with more information in that sense