I have UserMailer class with next code:
User.rb:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
-----------------
class UserMailer < ActionMailer::Base
default :from => "denys.medynskyi#gmail.com"
def password_reset(user, password)
#user = user
#password = password
mail(:to => user.email,
:subject => 'Password Reset Notification')
end
def congrats_email(user)
mail(to: user.email, subject: "Welcome Message")
end
end
setup_mail.rb:
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => "denys.medynskyi",
:password => "********",
:authentication => "plain",
:enable_starttls_auto => true
}
and from devise.rb:
Devise.setup do |config|
# ==> Mailer Configuration
config.mailer_sender = "UserMailer"
end
and after forgot password submit I go to some page, but it deosn't show me any notice adn doesn't send email.
What I'm doing wrong ?
I'm not 100% sure this is the cause of any or all of your problems, but if you're trying to work with Devise, overriding some of the default mailer behavior but not all of it, you should inherit from Devise::Mailer rather than ActionMailer::Base.
So
class UserMailer < Devise::Mailer
Edit: The method that Devise calls in Devise::Mailer to render the password reset mail template is reset_password_instructions. So your method isn't even overwriting that. Also, the way Devise works, it's the resource that eventually calls the method that sends the instructions e-mail. The job of the reset_password_instructions method is just to generate the e-mail from the view template. So it looks to me like the code you've got above isn't really working with the normal Devise flow. What calls password_reset in your app?
Related
I have problem with authentication through devise + google. I have local application written in Ruby on Rails 3.2. I was following devise docs to make this authentication to works:
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
So here is my users omniauth controller located in app/controllers/users
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
#user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
My routes:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
in my devise.rb initializer:
require "omniauth-google-oauth2"
config.omniauth :google_oauth2, "ClientID", "SecretId", { access_type: "offline", approval_prompt: "" }
My user model:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
data = access_token.info
user = User.where(:email => data["email"]).first
unless user
user = User.create(email: data["email"], password: Devise.friendly_token[0,20])
end
user
end
I don't know why this is not working. Maybe I'm doing something wrong with generating oauth clientid in google?
I generate my google app clientid and secret like in the following tutorial:
http://richonrails.com/articles/google-authentication-in-ruby-on-rails
Edit: I forgot to show what error I have:
when i click my link:
<%= link_to "Login via Google account", user_omniauth_authorize_path(:google_oauth2), :class => "btn btn-inverse btn-large" %>
i have the following addres in browser :
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=487629202871.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fusers%2Fauth%2Fgoogle_oauth2%2Fcallback&state=68a65048cca9ccb61a31d2a048bf9ef03d25ebe4a11d77ca&access_type=offline&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile
and my error looks like this:
I am implementing devise "confirmable" method to confirm user by sending email for ruby on rails App.
My app "development.log" file shows that email has been sent but it does not reach on destination.
Following are my files containing code:-
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
attr_accessible :title, :body
def password_match?
self.errors[:password] << 'must be provided' if password.blank?
self.errors[:password] << 'and confirmation do not match' if password != password_confirmation
password == password_confirmation and !password.blank?
end
end
confirmations_controller.rb
class ConfirmationsController < Devise::ConfirmationsController
def show
#user = User.find_by_confirmation_token(params[:confirmation_token])
end
ef confirm_user
#user = User.find_by_confirmation_token(params[:user][:confirmation_token])
if #user.update_attributes(params[:user]) and #user.password_match?
#user = User.confirm_by_token(#user.confirmation_token)
set_flash_message :notice, :confirmed
sign_in_and_redirect("user", #user)
else
render :show
end
end
sign up page
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
development.rb
Gt::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {:address => "localhost", :port => 1025}
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:tls => true,
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:authentication => :login,
:user_name => "[username]",
:password => "[password]"
}
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
end
log output
Sent mail to xy#gmail.com (2027ms)
Date: Wed, 27 Mar 2013 23:29:12 +0530
From: please-change-me-at-config-initializers-devise#example.com
Reply-To: please-change-me-at-config-initializers-devise#example.com
To: xy#gmail.com
Message-ID: <515333707f095_3501ae36c81486e#Vinay-PC.mail>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<p>Welcome xy#gmail.com!</p>
<p>You can confirm your account email through the link below:</p>
Problem: email is sent as i can see from development log but it does not reach to given email id.I am on localhost.
Any help would be appriciated.
Regards,
Vieenay Siingh
you need to set up a default host and mailer setting in config/application.rb file.
I also had this problem but got it solved by doing the following trick.
The solution is to create an initialiser in config/initialisers/setup_mail.rb containing the following
if Rails.env != 'test'
email_settings = YAML::load(File.open("#{Rails.root.to_s}/config/email.yml"))
ActionMailer::Base.smtp_settings = email_settings[Rails.env] unless email_settings[Rails.env].nil?
end
then add config/email.yml containing the details of the dev and production email accounts
development:
:address: smtp.gmail.com
:port: 587
:authentication: plain
:user_name: xxx
:password: yyy
production:
:address: smtp.gmail.com
:port: 587
:authentication: plain
:user_name: xxx
:password: yyy
I have been pulling my hair out because of this.
My cucumber step clicks on a login for facebook. I have mocked omniauth by following the following article:
http://pivotallabs.com/users/mgehard/blog/articles/1595-testing-omniauth-based-login-via-cucumber
My omniauth_callbacks_controller.rb has the following code:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def my_logger
##my_logger = Logger.new("#{Rails.root}/log/my.log")
end
def facebook
#user = User.find_for_facebook_oauth(env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.facebook_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
I however, get the following error:
When I follow "facebook_login_button" # features/step_definitions/basic.rb:14
undefined method `extra' for #<Hash:0x007fda6d7cd950> (NoMethodError)
./app/models/user.rb:13:in `find_for_facebook_oauth'
./app/controllers/users/omniauth_callbacks_controller.rb:8:in `facebook'
(eval):2:in `click_link'
./features/step_definitions/basic.rb:15:in `/^(?:|I )follow "([^"]*)"$/'
features/homepage.feature:30:in `When I follow "facebook_login_button"'
Other articles I have read:
Devise 1.5 + Omniauth 1.0 + Facebook: undefined method `extra` - problem: this is mocking out omniauth using rspec I think - not sure if it can be applied for cucumber
https://github.com/intridea/omniauth/issues/558 --post by benjamintanweihao works - but its hacking the code to work differently with tests - the git branches suggested dont work either
EDIT: my model/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :lockable, :timeoutable, :confirmable and :activatable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
devise :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:email => data.email).first
user
else
User.create!(:email => data.email, :password => Devise.friendly_token[0,20])
end
end
end
This hapens due do this issue: https://github.com/intridea/omniauth/issues/558
It is not your fault, it is a small bug in omniauth.
you can use methods like access_token.extra in production and development mode, but in order to make it work in test mode you should change it to access_token["extra"]
I am trying to send mail using actionmailer on a Rails 3.0.1 application. Here is my setup
config/initializers/setup_mail.rb
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "saidyes.co.uk",
:user_name => "username",
:password => "password",
:authentication => "plain",
:enable_starttls_auto => true
}
ActionMailer::Base.default_url_options[:host] = "localhost:3000"
ActionMailer::Base.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development?
config/environments/development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
default :from => "info#saidyes.co.uk"
def self.registration_confirmation(user)
#user = user
attachments["rails.png"] = File.read("#{Rails.root}/public/images/rails.png")
mail(:to => "#{user.email}", :subject => "Welcome")
end
end
app/models/user.rb
require "#{Rails.root}/app/mailers/user_mailer"
after_create :send_welcome_email
private
def send_welcome_email
UserMailer.registration_confirmation(self).deliver
end
The first error i got was an uninitialized constant UserMailer in my Users model class. I fixed it by adding the require at the top of the User model definition. Now I get
undefined local variable or method `attachments' for UserMailer:Class
I must have configured actionmailer incorrectly or my rails app is not configured correctly to use mailer.
Anyway any advice or help would be appreciated.
Cheers
I think the simple problem you've encountered is that the mail methods should be defined on instances of your mailer class.
Namely it should be
class UserMailer < ActionMailer::Base
def registration_confirmation(user)
#user = user
attachments["rails.png"] = File.read("#{Rails.root}/public/images/rails.png")
mail(:to => "#{user.email}", :subject => "Welcome")
end
end
Note there is no self
Take a look at the helpful Rails Guide on the subject
As in your example you'll still call the method on the class
UserMailer.registration_confirmation(user).deliver
The class method does some magic to instantiate an instance, and ensure the correct template is rendered.
I have my Rails app setup with Devise, but it's still in the development stages. I also have a Thor task that creates the default Admin user.
Problem is Devise won't let that admin user login to the site until the account is confirmed. Is there any way I can disable the confirmable module for the creation of specific users, such as Admin?
My Thor task:
class Setup < Thor
desc "create_admin [EMAIL] [PASSWORD]", "Creates the administrative user."
def create_admin(email = "admin#bogus.com", password = "testpassword123")
require File.expand_path('config/environment.rb') # load Rails environment
admin = User.create(:email => email, :password => password, :password_confirmation => password)
admin.assign_role :admin
puts "Admin user (#{ email }) created."
end
end
Once your user is created you can call the devise provided confirm! method on it rather than updating the database directly. Eg.:
admin = User.create(:email => email, :password => password, :password_confirmation => password)
admin.assign_role :admin
admin.confirm!
This should work
admin = User.create(:email => email, :password => password, :password_confirmation => password)
So your confirmed_at is set, which is the field devise refers to when checking user confirmation.
EDIT
Forgive me if this seems like a hack but this seems to work for me. After executing the above line,
admin.update_attributes(:confirmed_at => Time.now)
just coment :confirmable in User or Admin model
devise :database_authenticatable, :recoverable, :rememberable, :trackable, #:confirmable...
In config/inicializers/devise.rb
you can set here how many time user have to confirm his account