Skip confirmation mail in devise - ruby-on-rails

I want to skip the sending of confirmation mail from devise in my rails 4 application. I tried so many things, but none of them worked.
In my user.rb
before_create :my_method
def my_method
self.skip_confirmation
end
I tried this also
before_create :my_method
def my_method
!confirmed
end
I tried removing :confirmable from user.rb but none of them seems to work. Thanks in advance :)

Note: If you want to skip only on certain places
If you are calling User.create before skip_confirmation!, you need to call User.new and user.save.
#user = User.new(:first_name => "John", :last_name => "Doe")
#user.skip_confirmation!
#user.confirm!
#user.save
A/C to your way
before_create :my_method
def my_method
self.skip_confirmation!
self.confirm!
end
excluding the term confirmable in devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable should skip in a whole

Try this
#user = User.new(:email => 'email#example.com', :password => 'password')
#user.skip_confirmation_notification!
#user.save
skip_confirmation_notification! generate a confirmation token but does not send confirmation email.

Try adding this to user.rb
protected
def confirmation_required?
false
end

For every User instance:
class User < ApplicationRecord
after_initialize do |user|
user.skip_confirmation_notification!
end
end
For some particular instance:
john = User.new
john.skip_confirmation_notification!
P.S. The answers above are about disabling the confirmation process entirely, whereas the author asked about disabling just sending an email.

Related

Error Handling - Email LDAP - Rails

I'm beginner in Ruby on Rails and I need help
In my project, I need to catch on LDAP the e-mail of user.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :ldap_authenticatable,:rememberable, :trackable
#validates :username, presence: true, uniqueness: true
validates :email, presence: true
validates_uniqueness_of :email
before_validation :get_ldap_email
before_save :get_ldap_email
def get_ldap_email
self.email = Devise::LDAP::Adapter.get_ldap_param(self.username,"mail").first
end
But If in LDAP doesn't have an e-mail, shows an Rails´ error message and I want to redirect to a page with a message made by me.
So, in SessionController i want make an "if", but i don't have success to call the method.
class Users::SessionsController < Devise::SessionsController
require_relative '../../models/User.rb'
def create
super
if get_ldap_email == nil
# redirect to /errorlogin
end
end
And here show message
undefined local variable or method `get_ldap_email' for #
Users::SessionsController:0x67342e0>
Also I modificed the User for this...
def get_ldap_email
ldapEmail = Devise::LDAP::Adapter.get_ldap_param(self.username,"mail")
if ldapEmail == nil
else
self.email = ldapEmail.first
end
end
But now show this message
Validation failed: Email can't be blank
I don't what I need to do...
The issue is that you're calling super before your get_ldap_email, so the validation in Devise's SessionController is checking for a valid email. This should work:
def create
if get_ldap_email == nil
# redirect to /errorlogin
end
super
end

Restrict Login with Google OAuth2.0 and Devise to Specific Whitelist Table using Ruby

So I was trying to use omniauth2 to check if the email had the right #domain.com but I think using a database table will allow more functionality as well as being more secure and such.
My previous question: Restrict Login with Google OAuth2.0 to Specific Whitelisted Domain Name on Ruby
I think I want to use a database table to check the email that google authenticated against a whitelist of emails, is there anyway to do this with devise and omniauth2? That way I can say only certain users are authorized after they get authenticated with Google. I have most info listed on my previous question but if there is some more info I can give let me know.
Thanks.
EDIT: Not sure how much this helps but here is a question similar; however, I am still using google and omniauth Whitelisting with devise
EDIT: I think the above "Whitelisting with devise" is pretty close to the answer, but there are still a few kinks to work out. I'm not sure how to start implementing everything I'm pretty new to ruby in particular.
Here is my route:
devise_for :user, :controllers => { :omniauth_callbacks => "user/omniauth_callbacks" }
And that controller:
class User::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
If I understand the Whitelisting with devise correctly I have to create another controller in between and use that to check the email? Any help would be greatly appreciated.
EDIT: Here is my user.rb I think this might hold the answer possibly?:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable, :omniauth_providers => [:google_oauth2]
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :provider, :uid, :avatar
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(name: data["name"],
email: data["email"],
password: Devise.friendly_token[0,20]
)
end
user
end
end
I'd add a validation to the User Model so, no user would be created if the email that comes from oauth is not form a certain domain:
validates :email,
presence: true,
uniqueness: true,
format: {
message: 'domain must be example.com',
with: /\A[\w+-.]+#example.com\z/i
}

Anonymous user in devise - rails

I'm new to rails and I tried to make simple authentication with anonymous user. I followed this tutorial and I have this error:
undefined method `find_or_initialize_by_token'
This is my AnonymousUser model:
class AnonymousUser < User
ACCESSIBLE_ATTRS = [:name, :email]
attr_accessible *ACCESSIBLE_ATTRS, :type, :token, as: :registrant
def register(params)
params = params.merge(type: 'User', token: nil)
self.update_attributes(params, as: :registrant)
end
end
This is my User model:
class User < ActiveRecord::Base
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
:rememberable, :registerable, :trackable, :timeoutable, :validatable,
:token_authenticatable
attr_accessible :email, :password, :password_confirmation, :remember_me
end
And the last one important is my ApplicationController which has this error:
class ApplicationController < ActionController::Base
protect_from_forgery
def authenticate_user!(*args)
current_user.present? || super(*args)
end
def current_user
super || AnonymousUser.find_or_initialize_by_token(anonymous_user_token).tap do |user|
user.save(validate: false) if user.new_record?
end
end
private
def anonymous_user_token
session[:user_token] ||= SecureRandom.hex(8)
end
end
Someone told me that if AnonymousUser user inherits from User then AnonymousUser have method called find_or_initialize_by_token, but i don't know how to fix it.
Provided you have latest rails installed, try to refactor:
# in ApplicationController#current_user
AnonymousUser.find_or_initialize_by_token(anonymous_user_token).tap do |user|
user.save(validate: false) if user.new_record?
end
to something like this:
AnonymousUser.safely_find(anonymous_user_token)
and push the find_or_initialize_by_token and save(validate: false) into the model.
I wrote the blog post you referenced, but today, I would use
AnonymousUser.where(anonymous_user_token: anonymous_user_token).first_or_initialize
Dynamic finders have been deprecated AFAIK.
However, #Saurabh Jain is absolutely correct in his suggestion to refactor that block into a nice little push-button class method on the AnonymousUser.

Admin user administration with Devise

I am trying out Devise for the first time. One of the things that I wanted to do is provide an interface for Admin users to create, find and edit users. Here's where I may have gone wrong.
I created a PeopleController class which inherits from ApplicationController that lists people and provides methods and views for creating and updating users. Everything works fine with one exception. When the admin user updates their own record, the session is cleared and they have to login again after saving it.
In this application I'm not using the registerable module. Only an admin user can create new users. What is the right way in devise to provide user management tools. Creating my own controller seems to have been the wrong path to take.
Thanks in advance for your help.
Thank you very much for the help. This is essentially exactly what I am doing. I discovered a clue that helped me solve the problem of the user's session being cleared when they edit their own record in this wiki:
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password
This is the line I needed:
sign_in resource_name, resource, :bypass => true
This method is located in Devise::Controllers::Helpers so I did this in my controller.
class PeopleController < ApplicationController
include Devise::Controllers::Helpers
Then in my update method I call it only if the current_user.id equals the id that is being edited:
def update
#person = User.find(params[:id])
if #person.update_attributes(params[:user])
sign_in #person, :bypass => true if current_user.id == #person.id
redirect_to person_path(#person), :notice => "Successfully updated user."
else
render :action => 'edit'
end
end
Now if the current user edits their own record, the session is restored after it is saved.
Thanks again for your responses.
This is how I manage users in one of my apps. I have only one User class generated with
rails g devise User
to which I added a role column with this migration:
class AddRoleToUser < ActiveRecord::Migration
def change
add_column :users, :role, :string, :default => "client"
end
end
and my User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable, :lockable and :timeoutable
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
def admin?
self.role == "admin"
end
end
Then to create new users all you would have to do is provide a custom method in a controller (maybe even subclass Devise::RegistrationsController) like this:
# some_controller.rb
def custom_create_user
if current_user.admin?
User.create(:email => params[:email], password => params[:password])
redirect_to(some_path, :notice => 'sucessfully updated user.')
else
redirect_to(some_other_path, :notice => 'You are not authorized to do this.')
end
end

Rails Devise: after_confirmation

Is there a way to create a after_confirmation :do_something ?
The goal is to send an e-mail after the user confirms using Devise :confirmable.
I'm using Devise 3.1.2, it has a placeholder method after_confirmation which is called after the confirmation finished successfully. We just need to override this method in User model.
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
# Override Devise::Confirmable#after_confirmation
def after_confirmation
# Do something...
end
end
See: Devise 3.5.9 Source Code: https://github.com/plataformatec/devise/blob/d293e00ef5f431129108c1cbebe942b32e6ba616/lib/devise/models/confirmable.rb
For new versions of devise 3.x :
See a different answer http://stackoverflow.com/a/20630036/2832282
For old versions of devise 2.x :
(Original answer)
but you should be able to put a before_save callback on the user (extra credit for using an observer) and check if confirmed_at was just set by devise. You can do something like:
send_the_email if self.confirmed_at_changed?
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html for more details on checking the change on the field.
You can override the confirm! method:
def confirm!
super
do_something
end
Discussion about the topic is at https://github.com/plataformatec/devise/issues/812. They say that there are no callbacks like after_confirmation :do_something because that approach would require a lot of different callbacks.
Rails 4:
combining multiple answers above
def first_confirmation?
previous_changes[:confirmed_at] && previous_changes[:confirmed_at].first.nil?
end
def confirm!
super
if first_confirmation?
# do first confirmation stuff
end
end
according to the Devise 3.5.9 source code, you can simply define a method on the Devise Resource model, e.g.:
class User < ActiveRecord::Base
...
def after_confirmation
do_something
end
end
See: Devise 3.5.9 Source Code: https://github.com/plataformatec/devise/blob/d293e00ef5f431129108c1cbebe942b32e6ba616/lib/devise/models/confirmable.rb
I don't see that callback too, maybe you can try to override the confirmation method and call your callback there.
def send_confirmation_instructions(attributes={})
super(attributes)
your_method_here
end
You can override the confirm! method on your model
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
def confirm!
super
do_something
end
end
There is a discussion about the topic is https://github.com/plataformatec/devise/issues/812. I tried this way, and it worked great.
We're combining answers from #Bernát and #RyanJM:
def confirm!
super
if confirmed_at_changed? and confirmed_at_was.nil?
do_stuff
end
end
This seems a bit more performance aware and safe than the two answers separately.

Resources