Rails 3.1. Create one user in console with secure password - ruby-on-rails

I want to create one user (admin) and I want to use console (without user registration model). I use solution from RailsCasts (http://railscasts.com/episodes/270-authentication-in-rails-3-1).
But I have one problem: when I do User.create(..., :password => "pass") in console my password stored in database without encription (like "pass"). And I can't login with my data.
How can I create user from console? :)

Straight from the Rails API
# Schema: User(name:string, password_digest:string)
class User < ActiveRecord::Base
has_secure_password
end
user = User.new(:name => "david", :password => "", :password_confirmation => "nomatch")
user.save # => false, password required
user.password = "mUc3m00RsqyRe"
user.save # => false, confirmation doesn't match
user.password_confirmation = "mUc3m00RsqyRe"
user.save # => true
user.authenticate("notright") # => false
user.authenticate("mUc3m00RsqyRe") # => user
You need to include :password_confirmation => "pass in your hash!
Right, so taking a look at has_secure_password you want to perform BCrypt::Password.create(unencrypted_password) to obtain it. You'll need the bcrypt-ruby gem to do the above.

Related

Existence of ActiveModel::SecurePassword authenticate method (Rails 6)

The "authenticate" method can only be found here: https://apidock.com/rails/ActiveModel/SecurePassword/InstanceMethodsOnActivation/authenticate
, with version 6.0.0 being grayed out. So this seems to be outdated.
I have searched the Rails 6 documentation for the authenticate method, and found no record of it under https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html.
Yet in the code snippet on the same page
# Schema: User(name:string, password_digest:string, recovery_password_digest:string)
class User < ActiveRecord::Base
has_secure_password
has_secure_password :recovery_password, validations: false
end
user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
user.save # => false, password required
user.password = 'mUc3m00RsqyRe'
user.save # => false, confirmation doesn't match
user.password_confirmation = 'mUc3m00RsqyRe'
user.save # => true
user.recovery_password = "42password"
user.recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC"
user.save # => true
user.authenticate('notright') # => false
user.authenticate('mUc3m00RsqyRe') # => user
user.authenticate_recovery_password('42password') # => user
User.find_by(name: 'david')&.authenticate('notright') # => false
User.find_by(name: 'david')&.authenticate('mUc3m00RsqyRe') # => user
The authenticate method is still used (user.authenticate). Where does this method come from if I can't find it in the latest documentation?
Edit:
A related question regarding differences in documentation: I am able to find ActionDispatch::Request::Session on rubydocs but not on api.rubyonrails.
https://www.rubydoc.info/docs/rails/ActionDispatch/Request/Session
https://api.rubyonrails.org/classes/ActionDispatch/Request.html
Now I am not certain where I should be looking when searching for methods. Is api.rubyonrails not the "definitive" place to look for documentation?
It looks like they forgot to mention it in the documentation for has_secure_password. If you look into source code of ActiveModel::SecurePassword. You will find
# Returns +self+ if the password is correct, otherwise +false+.
#
# class User < ActiveRecord::Base
# has_secure_password validations: false
# end
#
# user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
# user.save
# user.authenticate_password('notright') # => false
# user.authenticate_password('mUc3m00RsqyRe') # => user
define_method("authenticate_#{attribute}") do |unencrypted_password|
attribute_digest = public_send("#{attribute}_digest")
BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
end
alias_method :authenticate, :authenticate_password if attribute == :password
You can se it is now defined as dynamic method based on the parametr name provided to has_secure_password method. So they implemented it in more general way. And to be more friendly with backwards compatibility the implemented the alias authenticate for authenticate_password which was the original implementation.
Unfortunately these dynamic methods are not very well documented in the rails API docs.

How do you add an administratior in a rails 3 appliction

I have just built a rails 3 application by using Mike Hartl's "Learn Rails by Example". I am ready to deploy it but I am confused about how to add the administrator to the application. I will be the only administrator. Will the administrator be added before deployment and if so how do I do this.
What I believe you need when you talk about an "administrator account" is in fact two different things: authentication (the login) & authorization (what a login can/cannot do).
Under rails, one way to do that is by using two different gems. I suggest you have a look at devise, and cancan. They have both been developed and are actively maintained by rails superstars: José Valim and Ryan Bates.
The tutorial doesn't actually go through creating an interface where you can create admins. If you want to test the part where you're not allowed to delete other administrator accounts, you can test it with faker by adding 2 admins to the sample_data.rake file:
def make_users
admin = User.create!(:name => "Example User",
:email => "example#railstutorial.org",
:password => "foobar",
:password_confirmation => "foobar")
admin.toggle!(:admin)
admin2 = User.create!(:name => "Example User2",
:email => "example2#railstutorial.org",
:password => "foobar",
:password_confirmation => "foobar")
admin.toggle!(:admin)
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}#railstutorial.org"
password = "password"
User.create!(:name => name,
:email => email,
:password => password,
:password_confirmation => password)
end
end
If you want to add an admin to production, I'm guessing you could create your account and toggle the admin function with a database editor and then push the db to the production server? That's what I would do but I'm by no means an expert.
for admin control panel on my web-apps i'm using typus gem https://github.com/fesplugas/typus/
it will generate an admin page and by the default typus will use your model default_scope to fetch data.
I'm busy with the same thing!
I found this on STACK:
rails c
Loading development environment (Rails 3.0.0.beta3)
irb(main):001:0> admin = Admin.create! do |u|
irb(main):002:1* u.email = 'sample#sample.com'
irb(main):003:1> u.password = 'password'
irb(main):004:1> u.password_confirmation = 'password'
irb(main):005:1> end
I changed the Admin to User, but the problem is it creates a normal user not an admin user. Somewhere we need to put in - admin.toggle!(:admin) or make it true. I'll let you know if I find anything else.

Wrong "from" email when using ActionMailer

Rails 2.3.11
I'm trying to send an activation-style email whenever a user registers. The email gets sent successfully, but has the wrong "from" email address. The subject, content, and recipient's email are all fine. Instead of being sent from activation#[domain].net, they come from [login-name]#box570.bluehost.com.
/app/models/franklin.rb:
class Franklin < ActionMailer::Base
def activation(user)
recipients user.email
from "activation#[sub].[domain].net"
subject "[Product] Registration"
body :user => user
end
end
Applicable part of the controller that calls it:
#user = User.create(
:first_name => params[:first_name],
:last_name => params[:last_name],
:email => params[:email],
:password => params[:password],
:password_confirmation => params[:password_confirmation],
:user_class => "User"
)
Franklin.deliver_activation(#user)
/config/environments/development.rb:
# Settings specified here will take precedence over those in config/environment.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 webserver when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_view.debug_rjs = true
config.action_controller.perform_caching = false
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :sendmail
Thank you!
This looks like a Bluehost-specific problem. You may need to make sure the activation#[sub].[domain].net e-mail address is actually set up as a full email account with Bluehost (this seems to be a common solution).

Create a devise user from Ruby console

Any idea on how to create and save a new User object with devise from the ruby console?
When I tried to save it, I'm getting always false. I guess I'm missing something but I'm unable to find any related info.
You can add false to the save method to skip the validations if you want.
User.new({:email => "guy#gmail.com", :roles => ["admin"], :password => "111111", :password_confirmation => "111111" }).save(false)
Otherwise I'd do this
User.create!({:email => "guy#gmail.com", :roles => ["admin"], :password => "111111", :password_confirmation => "111111" })
If you have confirmable module enabled for devise, make sure you are setting the confirmed_at value to something like Time.now while creating.
You should be able to do this using
u = User.new(:email => "user#name.com", :password => 'password', :password_confirmation => 'password')
u.save
if this returns false, you can call
u.errors
to see what's gone wrong.
When on your model has :confirmable option this mean the object user should be confirm first. You can do two ways to save user.
a. first is skip confirmation:
newuser = User.new({email: 'superadmin1#testing.com', password: 'password', password_confirmation: 'password'})
newuser.skip_confirmation!
newuser.save
b. or use confirm! :
newuser = User.new({email: 'superadmin2#testing.com', password: 'password', password_confirmation: 'password'})
newuser.confirm!
newuser.save
If you want to avoid sending confirmation emails, the best choice is:
u = User.new({
email: 'demo#greenant.com.br',
password: '12feijaocomarroz',
password_confirmation: '12feijaocomarroz'
})
u.confirm
u.save
So if you're using a fake email or have no internet connection, that'll avoid errors.
None of the above answers worked for me.
This is what I did:
User.create(email: "a#a.com", password: "asdasd", password_confirmation: "asdasd")
Keep in mind that the password must be bigger than 6 characters.

Rails LDAP login using net/ldap

I am trying to get LDAP authentication to work under Rails.
I have chosen net/ldap since it's a native Ruby LDAP library.
I have tried all possible stuff, specially examples from http://net-ldap.rubyforge.org/classes/Net/LDAP.html but still unable to get it work.
Any ideas?
The best solution I managed to reach is a Model with the following:
require 'net/ldap'
class User < ActiveRecord::Base
def after_initialize
#config = YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
end
def ldap_auth(user, pass)
ldap = initialize_ldap_con
result = ldap.bind_as(
:base => #config['base_dn'],
:filter => "(#{#config['attributes']['id']}=#{user})",
:password => pass
)
if result
# fetch user DN
get_user_dn user
sync_ldap_with_db user
end
nil
end
private
def initialize_ldap_con
options = { :host => #config['host'],
:port => #config['port'],
:encryption => (#config['tls'] ? :simple_tls : nil),
:auth => {
:method => :simple,
:username => #config['ldap_user'],
:password => #config['ldap_password']
}
}
Net::LDAP.new options
end
def get_user_dn(user)
ldap = initialize_ldap_con
login_filter = Net::LDAP::Filter.eq #config['attributes']['id'], "#{user}"
object_filter = Net::LDAP::Filter.eq "objectClass", "*"
ldap.search :base => #config['base_dn'],
:filter => object_filter & login_filter,
:attributes => ['dn', #config['attributes']['first_name'], #config['attributes']['last_name'], #config['attributes']['mail']] do |entry|
logger.debug "DN: #{entry.dn}"
entry.each do |attr, values|
values.each do |value|
logger.debug "#{attr} = #{value}"
end
end
end
end
end
I work on a Devise plugin for Rails 3 that uses LDAP for authentication, you can look at the source to get some ideas, it currently uses net-ldap 0.1.1:
http://github.com/cschiewek/devise_ldap_authenticatable
The actual connecting and authenticating to the LDAP sever is done at:
http://github.com/cschiewek/devise_ldap_authenticatable/blob/master/lib/devise_ldap_authenticatable/ldap_adapter.rb
Lastly, you can look at the sample LDAP server config and Rails 3 app I use to run the tests against:
App: http://github.com/cschiewek/devise_ldap_authenticatable/tree/master/test/rails_app/
Server: http://github.com/cschiewek/devise_ldap_authenticatable/tree/master/test/ldap/

Resources