How to authenticate users using rubycas-server with multi-field? - ruby-on-rails

I used rubycas-server to build an sso systems, using devise to do the user's system, but now my question is, rubycas-server only one field like 'email' , I want to use 'email' / 'tel' / 'nickname' for user login. no more info in wiki
authenticator:
class: CASServer::Authenticators::SQLBcrypt
database:
adapter: mysql2
database: xxxx
username: root
password: xxxx
host: localhost
user_table: users
username_column: email # tel/nickname
password_column: encrypted_password
sorry about my poor English! help me, thanks very much!

I'm affraid it woulnd't be possible. As can be seen in the official repository, this authenticator just matches given column name with user name:
def matching_users
results = user_model.find(:all, :conditions => ["#{username_column} = ?", #username])
results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == #password }
end
For your case the best idea would be to write custom authenticator that matches email/tel/nickname. This is however very tough login name though, consider some more user friendly.

Modify the following code in rubycas-server/lib/casserver/authenticators/sql_bcrypt.rb
def matching_users
results = user_model.find(:all, :conditions => ["#{username_column} = ?", #username])
results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == #password }
end
to
def matching_users
if username_column.include?(',')
columns = username_column.split(',')
sql = ''
conditions = []
columns.each do |field|
if sql.length != 0
sql += ' or '
end
sql += "#{field} = ?"
conditions << #username
end
conditions.unshift(sql)
else
conditions = ["#{username_column} = ?", #username]
end
results = user_model.find(:all, :conditions => conditions)
results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == #password }
end
then u can use mutli-fieds in config.yml like this:
authenticator:
class: CASServer::Authenticators::SQLBcrypt
database:
adapter: mysql2
database: test
username: root
password: map
host: localhost
user_table: users
username_column: email,nickname,tel
password_column: encrypted_password

Related

Don't stop rake task if raise an error

I have simple rake file.
It imports data from the .xls file to the database.
But some of the data is invalid. Then data is invalid rake stop excecuting script.
But I wan to just skip this row and try with the next.
Part of my code:
data.each do |row|
username = row[0].slice!(0..2) + row[1].slice!(0..2) + rand(100).to_s
username.downcase
password = "pass1234"
User.create!(
email: row[2].downcase,
username: username,
first_name: row[0],
last_name: row[1],
expiration_date: row[3],
password: password,
password_confirmation: password)
p 'done'
end
The error is about the validation, eg.:
rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Expiration date must be after 2015-10-27
Script is stopped and valid records are not added.
Wrap it in a begin/rescue block.
data.each do |row|
begin
username = row[0].slice!(0..2) + row[1].slice!(0..2) + rand(100).to_s
username.downcase
password = "pass1234"
User.create!(
email: row[2].downcase,
username: username,
first_name: row[0],
last_name: row[1],
expiration_date: row[3],
password: password,
password_confirmation: password)
p 'done'
rescue => e
# log exception or ignore it.
end
end
Note that this works because the default rescue is for StandardError. Since ActiveRecord::RecordInvalid < StandardError. It will be 'catched'.
You could rescue the specific error first if you only want to do something with those specific errors.
(For reference also see the API: http://ruby-doc.org/core-2.2.0/Exception.html)

Problems with 'seeding' data to different users

I would like to seed some data to my wiki model user the 'faker gem'. I have created three users and would like to 'spread' 20 wikis over them.
I installed the faker gem, run bundle and set up my seedfile like this:
require 'faker'
# Create an admin user
admin = User.new(
email: 'admin2#example.com',
password: 'helloworld',
role: 'administrator'
)
admin.save!
# Create a moderator
moderator = User.new(
email: 'moderator2#example.com',
password: 'helloworld',
role: 'moderator'
)
moderator.save!
# Create a member
member = User.new(
email: 'member2#example.com',
password: 'helloworld'
)
member.save!
users = User.all
15.times do
Wiki.create!(
title: Faker::Lorem.sentence,
body: Faker::Lorem.paragraph
user: users.sample
)
end
wikis = Wiki.all
puts "Seeds finished"
If I run this I get an error:
SyntaxError: /Users/marcvanderpeet/Projects/bloc/blocipedia/db/seeds.rb:37: syntax error, unexpected tIDENTIFIER, expecting ')'
user: users.sample
I dont understand why I get this error as when Im running rails c I can just type in a user:
2.1.5 :001 > u = Wiki.new
=> #
Any clues on how to fix this?
You have a syntax error: the line
body: Faker::Lorem.paragraph
should end with a comma.
Already got it, forgot a ','. Devil is in the details!

How do I allow uppercase usernames in Refinery CMS?

I believe Refinery uses Devise, and I found this guide to allow uppercase usernames in Devise
https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-sign-in-using-their-username-or-email-address
However, even with
config.authentication_keys = [ :login ]
config.case_insensitive_keys = [:email]
it still forced the username to lowercase.
> u = User.create username: "UsErNaMe", password: "secret", email: "email#com.com"
=> #<Refinery::User id: 60, username: "username", email: "email#com.com",
I saw this question, but it did not help
Devise: Allow users to register as "UsErNaMe" but login with "username"
Refinery 2.1.1, Devise 2.2.8, Rails 3.2.14
It is in the Refinery::User model. There's a before_validation filter that downcases usernames:
...
before_validation :downcase_username, :strip_username
...
private
def downcase_username
self.username = self.username.downcase if self.username?
end
You could decorate the Refinery::User model:
Refinery::User.class_eval do
private
def downcase_username
self.username if self.username?
end
end
Found it
intended_username = user_params[:username] # save the username because Refinery converts it to lowercase! https://github.com/refinery/refinerycms/blob/master/authentication/app/models/refinery/user.rb#L28
intended_username.strip! # trim spaces
if current_refinery_user.update_without_password(user_params)
current_refinery_user.username = intended_username # restore the username as the user intended with mixed case
current_refinery_user.save(validate: false) # skip validations

Select when devise send the confirmation mail or not

i need to select when devise send the confirmation mail. I overwrite the send_confirmation_instructions and add a date field named invited on my user model. If the invited field is null send the mail, otherwise not sent.
Here's my code:
def send_confirmation_instructions
unless invited.nil?
self.confirmation_token = nil if reconfirmation_required?
#reconfirmation_required = false
generate_confirmation_token! if self.confirmation_token.blank?
else
self.confirmation_token = nil if reconfirmation_required?
#reconfirmation_required = false
generate_confirmation_token! if self.confirmation_token.blank?
self.devise_mailer.confirmation_instructions(self).deliver
end
end
The output of my console its:
Loading development environment (Rails 3.0.10)
1.9.3-p0 :001 > User.create!(:email => "hello#test.com") NoMethodError: undefined method `reconfirmation_required?' for
I have rewrite many other devise method without problems. Any idea ?
Thanks in advance.
The best solution was to connect manually to the database and add the fields to the users table.
# read configuration from database.yml
config = Rails.application.config.database_configuration[Rails.env]
host = config["host"]
database = config["database"]
username = config["username"]
password = config["password"]
# stablish db connection
mysql = Mysql2::Client.new(:host => host, :username => username, :database => database, :password => password)
# generate devise confirmation token
token = (Digest::MD5.hexdigest "#{ActiveSupport::SecureRandom.hex(10)}-#{DateTime.now.to_s}")
# made the sql
sql = "INSERT INTO users (email, confirmation_token, confirmation_sent_at) VALUES ('email#test.com', '#{token}', '#{Time.now.to_s}')"
# execute query
mysql.query(sql)
# close mysql connection
mysql.close
I hope this will be useful.

Nested attributes in rake task

I'm trying to create a rake task to populate my DB. I need to to create 1 user with a specifc set of deatails and 99 other randomly genraterated . The details that are required are for two Models at the same time, similar to a form with nested attribues. My model uses an after_create call back to create and link a users to a team. The team name by default is the users name
the current code that I have used it producing errors
sample_data.rake
namespace :db do
desc "Fill database with sample data"
task populate: :environment do
user = User.create!(:profile_attributes => { name: Forgery::Name.full_name },
email: "test#example.com",
password: "123qwe",
password_confirmation: "123qwe")
99.times do |n|
:profile_attributes => { name: Forgery::Name.full_name },
email = Forgery::Internet.email_address
password = "password"
user = User.create!(email: email,
password: password,
password_confirmation: password)
end
end
end
Model that relys on the nested attibute.
class User < ActiveRecord::Base
after_create :set_user_on_team
private
def set_user_on_team
self.create_owned_team(:name => self.profile.name ).users << self
end
end
error message
rake aborted!
/lib/tasks/sample_date.rake:9: syntax error, unexpected tASSOC, expecting keyword_end
:profile_attributes => { name: Forgery::Name.full_name },
^
/lib/tasks/sample_date.rake:9: syntax error, unexpected ',', expecting keyword_end
I noticed some syntax errors in the 99.times block. You could try it like this:
99.times do |n|
profile_attributes = { name: Forgery::Name.full_name }
email = Forgery::Internet.email_address
password = "password"
user = User.create!(profile_attributes: profile_attributes, #my assumption
email: email,
password: password,
password_confirmation: password)
end

Resources