i am using devise for my rails 3 app, when i click forgot password, enter the email and click submit, i get the error
undefined method `successfully_sent?' for #<Devise::PasswordsController:0xac17e74>
i have uncommented the line config.mailer = "Devise::Mailer" in devise.rb in initializers
also i have put
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
in development.rb
please help!
I got the same error when I updated the version of the Dvise from 1.4.8 to 1.5.2.
After down graded to 1.4.8, the forgot password function goes well.
Related
I am very confused with how to provide the default_url_options. I am getting this error
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
I am using spreecommerce which uses devise for authentication. This error is occurring durring password reset on my development environment. I have not tested it in a production environment yet.
I am using this in my environments/development
config.default_url_options = { host: 'localhost:3000' }
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
in my rails console when I do Rails.application.routes.default_url_options I get {:host => Rails.application.config.domain}. The same thing happends when I do Rails.applicaiton.default_url_options
None of the solutions I have found have worked.
TL;DR In my case Spree::Store.current vanished - I had to recreate it.
I tried set default_url_options for routes and into environments. But with no luck.
So I got into spree_auth_devise-3.1.0 gem source code:
#confirmation_url = spree.spree_user_confirmation_url(:confirmation_token => token, :host => Spree::Store.current.url)
So for the host, it's using Spree::Store. Then I went into console and got that my Spree::Store.current is empty:
(byebug) Spree::Store.current.url
nil
So simply creating a store with dummy data resolved my problem.
store = Spree::Store.new
store.name = 'test'
store.url = 'http://localhost:3000'
store.code = 'spree'
store.default = true
store.save
I have the following code in my requests spec:
describe 'Poll' do
subject { page }
context 'as system admin' do
let(:user) { Fabricate(:system_admin) }
before { login user}
it 'is accessible' do
visit '/admin/poll'
current_path.should == '/admin/poll'
end
describe 'sending poll' do
it 'sends to all users' do
save_and_open_page
end
end
end
end
The login user doesn't seem to work even if the method seems to be working fine. I tried using login user inside the it 'is accessible' do block and that specs works fine if I do it that way. If I remove it from there and put it in a before block like above. The user doesn't stay signed in. I put in a save_and_open_page to debug and I get this notification in the page:
Your account was not activated yet. If a reset password link was sent to you, use that link to change your password.
I'm using Devise, RSpec, Capybara and Rails 3. I've also set user to confirm! in my Fabrication file. Below is how it looks:
Fabricator(:system_admin) do
first_name { sequence(:first_name) { |n| "Person#{n}"} }
last_name { sequence(:last_name) {|n| "#{n}" } }
email { sequence(:email) { |n| "person_#{n}#example.com"} }
password "foobar"
password_confirmation "foobar"
company_name { sequence(:company_name) { |n| "google#{n}" } }
role "system_admin"
after_create do |user|
user.confirm!
user.create_company
end
end
Question: What could be the problem? How come the user isn't staying logged in and why do I get that message saying that I should activate my account? Isn't user.confirm! enough?
could this be the problem?
Fabricate(:system_admin) != Fabricator(:system_admin)
So if you debug your save_and_open_page and it tells you that the account is not activated it seemes your fabricate is not working properly. have you tried and debug that?
what does your save_and_open_page do? does it try to use the user for something? because I have experienced when defined with a let, if not touched the variable(user in this case) then it does no exist on that context. besides. whats the error when you run the specs like this on it "is acessible"? just says there is no user logged in?
so you can either stub your methods for login(for example if you have method called current_user that gives you the logged in user or something) or instead of using let, instiate like:
user = Fabricate(:system_admin)
but hey there is a lot of good advices here:
http://betterspecs.org/
it seems like your blocks context and describe are too complex. I am also not following this guidelines 100% but I think I should and you too would benefit from this.
let me know if you found out another reason why its not working!
I think before(:each) should resolve the problem
Add this Devise method:
confirmed_at { Time.now }
So your after_create method should looks like:
after_create do |user|
user.confirm!
user.confirmed_at { Time.now }
user.create_company
end
I've seen this issue several places, but none of the solutions seem to work.
I have a Rails 3.1 app with the latest versions of guard, spork, factory girl, rspec, and devise.
Whenever I try to create a user factory (the user model is a devise model) then I get this error:
Could not find a valid mapping for #<User...model attributes...>
I'm not sure what the problem is.
I ran rake db:test:prepare. I followed the instructions in this stackoverflow question: "Could not find a valid mapping for #<User ...>" only on second and successive tests
ALso, I attempted the solution in this answer from google groups:
https://groups.google.com/forum/?fromgroups#!topic/plataformatec-devise/StpbEsDCec0[1-25]
And, here's all the relevant code:
Guardfile
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
require 'capybara/rspec'
guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
watch('config/application.rb')
watch('config/environment.rb')
watch('config/environments/test.rb')
watch(%r{^config/initializers/.+\.rb$})
watch('Gemfile')
watch('Gemfile.lock')
watch('spec/spec_helper.rb') { :rspec }
watch('test/test_helper.rb') { :test_unit }
watch(%r{features/support/}) { :cucumber }
end
guard 'rspec', :version => 2, :cli => '--drb' do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
# Rails example
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara request specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end
</code>
This is in my spec/factories.rb
FactoryGirl.define do
load "#{Rails.root}/app/models/user.rb"
factory :user, class: User do |user|
email 'owner#example.com'
password '12345678'
password_confirmation '12345678'
companyid 'example_company'
end
end
This is my spec/controllers/api_controller_spec.rb
require 'spec_helper'
describe ApiController do
it 'verifies company_id through POST to api/company_id' do
load "#{Rails.root}/app/models/user.rb"
debugger
user = FactoryGirl.create(:user)
post(:get_company_id, {:company_id => 'example_company'})
response.body.should include('true')
end
end
And I have this at the end of my config/application.rb
ActionDispatch::Callbacks.after do
# Reload the factories
return unless (Rails.env.development? || Rails.env.test?)
unless FactoryGirl.factories.blank? # first init will load factories, this should only run on subsequent reloads
FactoryGirl.factories.clear
FactoryGirl.find_definitions
end
end
I'm really desperate for an answer here because otherwise I won't be able to test my User model (which is the most important model I have).
Feel free to comment and ask any questions.
EDIT: code looked funny in places, so I edited it for clarity
UPDATE:
So I tried simplifying everything to get to the core of the problem, and I'm pretty sure that devise and factory girl don't "like" each other. I'm still getting the exact same error whenever I try and create a user factory.
This is my new setup (I reverted to a previous git commit and I no longer have guard or spork).
My factories.rb is exactly the same as Michael Durant's except I have an extra line:
companyid 'example'
That's just a requirement for my app.
My spec_helper.rb requires rubygems and capybara/rspec and that's it.
And this is my spec/models/user_spec.rb
require 'spec_helper'
describe 'User associations' do
it 'tests creation of user' do
debugger
user = FactoryGirl.create(:user)
User.count.should be(1)
end
end
Also, this is interesting: When I hit that debugger statement and type in
eval User
It shows the mapping of a valid User.
UPDATE:
So, it's not factory girl that's the problem. It's devise.
This is the new api_controller_spec.rb file and it comes up with the same error of not having a valid mapping of the user.
require 'spec_helper'
describe ApiController do
it 'verifies company_id through POST to api/company_id' do
load "#{Rails.root}/app/models/user.rb"
debugger
user = User.new
user.email = 'owner#example.com'
user.password = '12345678'
user.password_confirmation = '12345678'
user.company_id = 'company'
user.save
post(:get_company_id, {:company_id => 'example_company'})
response.body.should include('true')
end
end
THere isn't a problem with any other environment as I can create users fine through the console, while a local server is running, or when the code is pushed up to Heroku. It might be rspec or something else, but I'm just not sure at this point.
I would recommend you simplify things to find the issue. Currently I feel you have too much going on / too many variable factors.
I would recommend the following:
1 Make a new branch. I assume you are using git, if not use it (git init) and make a fork.
2 Remove all the spork and guard stuff. They are helpful in speeding up your tests and running tests in a CI (Continuous Integration), but they are certainly not 'needed' and removing them will help uncover what the real problems are.
3 Set up your user factory correctly. We use this:
FactoryGirl.define do
sequence :email do |n|
"email#{n}#factory.com"
end
factory :user do
email
first_name { 'First' }
last_name { 'Last' }
password { "password" }
password_confirmation { "password" }
association :area
role { 'super_user' }
end
end
4 Set up your spec_help correctly.
We use these requires in our spec_helper.rb:
require 'rubygems'
require 'capybara/rspec'
5 Try to get one user test to pass using spec/models/user_spec.rb, something like:
require 'spec_helper'
describe 'User associations' do
subject { User.new }
it { should validate_presence_of :area }
...
So, the answer had nothing to do with guard, spork, rspec, or factory_girl.
The problem was that I had my devise_for :users routes commented out since I've been doing a huge overhaul of my rails app.
It's always something stupidly simple >.<
We have a problem in our RoR app. We are using a facebook authentication with omniauth, and searching the user friends with Koala. But lately, when we try to show a friend photo, we got this error:
Koala::Facebook::APIError in Homes#show
Showing /home/daniel/Homes/app/views/shared/_event.html.erb where line #19 raised:
OAuthException: Error validating access token: Session has expired at unix time 1328727600. The current unix time is 1328802133.
Extracted source (around line #19):
16: <img src="../assets/friends-icon.png" alt="User profile apicture" height="33" width="43">
17: <% if current_user %>
18: <% event.friends_in_event(#person).each do |f| %>
19: <%= link_to(image_tag(f.fb_picture, :size => "43x33"), person_path(f.id)) %>
20: <% end %>
21: <% end %>
22: </div>
The authentication works good, but facebook has already deprecated the offline_access option, that was working good, but now, we have this issue.
is It any way to extends the access_token?, or are there another solution?.
This is our omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FB_KEY'], ENV['FB_SECRET'],
{ :scope => 'email,offline_access,user_photos,publish_stream',
:client_options => { :ssl => { :ca_path => "/etc/ssl/certs" } } }
end
And our koala.rb
Koala.http_service.http_options = {
:ssl => { :ca_path => "/etc/ssl/certs" }
}
Thanks in advance.
There are 2 solutions to this problem:
Extend the user's access token:
As per this article on the Facebook docs, you may request a 60-day extension on a user's access token. However, if the user does not return within that period, this method won't help you.
You can find a PHP code snippet to do this at this StackOverflow question.
To do this, send a post to this API endpoint: https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=EXISTING_ACCESS_TOKEN
Catch the OAuthException and request a new access token:
Facebook provides a PHP code snippet outlining this solution on their dev blog.
Basically, you follow these steps:
Make a call to the graph with the user's current access_token.
If the call succeeds, the access_token is fine. If it throws an OAuthException, redirect the user to https://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=CALLBACK_URL
The user will be sent to that URL and then redirected to your CALLBACK_URL with a code in the parameters.
Send a post to the following URL with the code to obtain a new access_token: https://graph.facebook.com/oauth/access_token?client_id=APP_ID&redirect_uri=CALLBACK_URL&client_secret=APP_SECRET&code=CODE&display=popup
Read the post on their dev blog for more information.
Edit (adding example Ruby on Rails code):
Add the following to the top of your ApplicationController:
rescue_from Koala::Facebook::APIError, :with => :handle_fb_exception
Add the following protected method to your ApplicationController:
def handle_fb_exception exception
if exception.fb_error_type.eql? 'OAuthException'
logger.debug "[OAuthException] Either the user's access token has expired, they've logged out of Facebook, deauthorized the app, or changed their password"
oauth = Koala::Facebook::OAuth.new
# If there is a code in the url, attempt to request a new access token with it
if params.has_key? 'code'
code = params['code']
logger.debug "We have the following code in the url: #{code}"
logger.debug "Attempting to fetch a new access token..."
token_hash = oauth.get_access_token_info code
logger.debug "Obtained the following hash for the new access token:"
logger.debug token_hash.to_yaml
redirect_to root_path
else # Since there is no code in the url, redirect the user to the Facebook auth page for the app
oauth_url = oauth.url_for_oauth_code :permissions => 'email'
logger.debug "No code was present; redirecting to the following url to obtain one: #{oauth_url}"
redirect_to oauth_url
end
else
logger.debug "Since the error type is not an 'OAuthException', this is likely a bug in the Koala gem; reraising the exception..."
raise exception
end
end
The Koala calls were all taken from the following 2 tutorials:
https://github.com/arsduo/koala/wiki/OAuth
https://github.com/arsduo/koala/wiki/Koala-on-Rails
For those of you who don't have time to make this change, I found that you can disable this migration in Settings -> Advanced. The name of the option is "Remove offline_access permission:"
My problem is on facebook callback url. I am using fbgraph gem on Rails 3.0.
I ask for extended permissions on my tab application. So in the callback I wait code parameter and access_token.
I extract this code from fbgraph official GIT repository.
def authorize
begin
#auth.client.authorization_code = params[:code]
#In access_token line should return me access__token but throw a error message (see below)
access_token = #auth.client.access_token! # => Rack::OAuth2::AccessToken
#facebook_user = FbGraph::User.me(access_token).fetch # => FbGraph::User
#MORE CODE WITHOUT IMPORTANCE
redirect_to :controller => "dashboard", :action => "index"
rescue Exception => e
logger.info(e.message)
end
end
Throw this error message:
Rack::OAuth::Client::Error # => #status = 400, Message => Missing redirect uri
Please I need help quickly. Excuse me and thanks in advance
I'm using the fb_graph gem which is similar. In order to get the access_token you also need to supply the callback URI - this is the fb_graph version:
client.redirect_uri = "http://your.callback.uri"
client.authorization_code = params[:code]
access_token = client.access_token!
Update:
Looking at the fbgraph gem documentation I think you need to replace these two lines:
#auth.client.authorization_code = params[:code]
access_token = #auth.client.access_token!
With this:
access_token = #auth.client.authorization.process_callback(params[:code], :redirect_uri => callback_url)
To be honest I looked at using the fbgraph gem but the documentation was so bad that I switched to fb_graph instead which is similar and actually has some useful examples in the documentation.