From a46ff394b12304988a697999b68b52c1db7a245c Mon Sep 17 00:00:00 2001 From: Raphael Sofaer Date: Thu, 12 May 2011 14:46:19 -0700 Subject: [PATCH 1/6] update devise_invitable and devise --- Gemfile | 4 +-- Gemfile.lock | 25 ++++++++----------- app/models/invitation.rb | 3 ++- ...haml => invitation_instructions.html.haml} | 0 config/locales/devise/devise.en.yml | 2 +- spec/models/invitation_spec.rb | 4 +-- 6 files changed, 18 insertions(+), 20 deletions(-) rename app/views/devise/mailer/{invitation.html.haml => invitation_instructions.html.haml} (100%) diff --git a/Gemfile b/Gemfile index a92a25eca..cb6d11592 100644 --- a/Gemfile +++ b/Gemfile @@ -11,8 +11,8 @@ gem 'ohai', '0.5.8', :require => false #Chef dependency gem 'nokogiri', '1.4.3.1' #Security -gem 'devise', '1.1.3' -gem 'devise_invitable', :git => 'git://github.com/zhitomirskiyi/devise_invitable.git', :branch => '0.3.5' +gem 'devise', '1.3.1' +gem 'devise_invitable', '0.5.0' #Authentication gem 'omniauth', '0.1.6' diff --git a/Gemfile.lock b/Gemfile.lock index be193e65b..1312cdc57 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,14 +50,6 @@ GIT multi_xml (~> 0.2.0) simple_oauth (~> 0.1.2) -GIT - remote: git://github.com/zhitomirskiyi/devise_invitable.git - revision: 85abb5fef4ab4f74db818ed3d8104c2f7d24b94e - branch: 0.3.5 - specs: - devise_invitable (0.3.5) - devise (~> 1.1.0) - PATH remote: vendor/gems/jasmine specs: @@ -166,9 +158,13 @@ GEM culerity (0.2.15) daemons (1.1.2) database_cleaner (0.6.0) - devise (1.1.3) + devise (1.3.1) bcrypt-ruby (~> 2.1.2) - warden (~> 0.10.7) + orm_adapter (~> 0.0.3) + warden (~> 1.0.3) + devise_invitable (0.5.0) + devise (~> 1.3.1) + rails (>= 3.0.0, <= 3.2) diff-lcs (1.1.2) erubis (2.6.6) abstract (>= 1.0.0) @@ -301,6 +297,7 @@ GEM oa-oauth (= 0.1.6) oa-openid (= 0.1.6) open4 (1.0.1) + orm_adapter (0.0.5) polyglot (0.3.1) pyu-ruby-sasl (0.0.3.2) rack (1.2.2) @@ -391,8 +388,8 @@ GEM uuidtools (2.1.2) vegas (0.1.8) rack (>= 1.0.0) - warden (0.10.7) - rack (>= 1.0.0) + warden (1.0.4) + rack (>= 1.0) webmock (1.6.2) addressable (>= 2.2.2) crack (>= 0.1.7) @@ -418,8 +415,8 @@ DEPENDENCIES cloudfiles (= 1.4.10) cucumber-rails (= 0.3.2) database_cleaner (= 0.6.0) - devise (= 1.1.3) - devise_invitable! + devise (= 1.3.1) + devise_invitable (= 0.5.0) em-websocket! excon (= 0.2.4) factory_girl_rails diff --git a/app/models/invitation.rb b/app/models/invitation.rb index 0463bc08b..0ac394dba 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -74,7 +74,8 @@ class Invitation < ActiveRecord::Base opts[:from].save! invitee.reload end - invitee.invite!(:email => (opts[:service] == 'email')) + invitee.skip_invitation = (opts[:service] != 'email') + invitee.invite! log_string = "event=invitation_sent to=#{opts[:identifier]} service=#{opts[:service]} " log_string << "inviter=#{opts[:from].diaspora_handle} inviter_uid=#{opts[:from].id} inviter_created_at_unix=#{opts[:from].created_at.to_i}" if opts[:from] Rails.logger.info(log_string) diff --git a/app/views/devise/mailer/invitation.html.haml b/app/views/devise/mailer/invitation_instructions.html.haml similarity index 100% rename from app/views/devise/mailer/invitation.html.haml rename to app/views/devise/mailer/invitation_instructions.html.haml diff --git a/config/locales/devise/devise.en.yml b/config/locales/devise/devise.en.yml index 4af406233..c3c86413b 100644 --- a/config/locales/devise/devise.en.yml +++ b/config/locales/devise/devise.en.yml @@ -72,7 +72,7 @@ en: account_locked: "Your account has been locked due to an excessive amount of unsuccessful sign in attempts." click_to_unlock: "Click the link below to unlock your account:" unlock: "Unlock my account" - invitation: + invitation_instructions: subject: "You've been invited to join Diaspora!" accept: "Accept invitation" ignore: "If you don't want to accept the invitation, please ignore this email." diff --git a/spec/models/invitation_spec.rb b/spec/models/invitation_spec.rb index 004fd6612..93a412b14 100644 --- a/spec/models/invitation_spec.rb +++ b/spec/models/invitation_spec.rb @@ -225,10 +225,10 @@ describe Invitation do }.should_not change { @invitee.reload.serialized_private_key } end - it "changes the invitation token" do + it "does not change the invitation token" do old_token = @invitee.invitation_token Invitation.create_invitee(@valid_params) - @invitee.reload.invitation_token.should_not == old_token + @invitee.reload.invitation_token.should == old_token end end context 'with an inviter' do From 5f531f14f198dedb47a38aee6ea4bba78e1464e2 Mon Sep 17 00:00:00 2001 From: Raphael Sofaer Date: Thu, 12 May 2011 15:15:56 -0700 Subject: [PATCH 2/6] Don't use rails case_sensitive false, it is very slow. --- app/models/person.rb | 6 +++--- app/models/user.rb | 7 ++++--- db/migrate/20110512220310_downcase_usernames_again.rb | 10 ++++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20110512220310_downcase_usernames_again.rb diff --git a/app/models/person.rb b/app/models/person.rb index 6ab4a9109..45128e3db 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -20,7 +20,7 @@ class Person < ActiveRecord::Base has_one :profile delegate :last_name, :to => :profile - before_save :downcase_diaspora_handle + before_validation :downcase_diaspora_handle def downcase_diaspora_handle diaspora_handle.downcase! end @@ -39,7 +39,7 @@ class Person < ActiveRecord::Base before_validation :clean_url validates_presence_of :url, :profile, :serialized_public_key - validates_uniqueness_of :diaspora_handle, :case_sensitive => false + validates_uniqueness_of :diaspora_handle scope :searchable, joins(:profile).where(:profiles => {:searchable => true}) @@ -230,7 +230,7 @@ class Person < ActiveRecord::Base def remove_all_traces Notification.joins(:notification_actors).where(:notification_actors => {:person_id => self.id}).all.each{ |n| n.destroy} end - + def fix_profile Webfinger.new(self.diaspora_handle).fetch self.reload diff --git a/app/models/user.rb b/app/models/user.rb index 93e0cce1b..8707c4f6d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -19,7 +19,7 @@ class User < ActiveRecord::Base before_validation :set_current_language, :on => :create validates_presence_of :username - validates_uniqueness_of :username, :case_sensitive => false + validates_uniqueness_of :username validates_format_of :username, :with => /\A[A-Za-z0-9_]+\z/ validates_length_of :username, :maximum => 32 validates_inclusion_of :language, :in => AVAILABLE_LANGUAGE_CODES @@ -76,12 +76,13 @@ class User < ActiveRecord::Base self.language = I18n.locale.to_s if self.language.blank? end - def self.find_for_authentication(conditions={}) + def self.find_for_database_authentication(conditions={}) + conditions = conditions.dup conditions[:username] = conditions[:username].downcase if conditions[:username] =~ /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i # email regex conditions[:email] = conditions.delete(:username) end - super(conditions) + where(conditions).first end def can_add?(person) diff --git a/db/migrate/20110512220310_downcase_usernames_again.rb b/db/migrate/20110512220310_downcase_usernames_again.rb new file mode 100644 index 000000000..02eeed8eb --- /dev/null +++ b/db/migrate/20110512220310_downcase_usernames_again.rb @@ -0,0 +1,10 @@ +require 'db/migrate/20110421120744_downcase_usernames' +class DowncaseUsernamesAgain < ActiveRecord::Migration + def self.up + DowncaseUsernames.up + end + + def self.down + DowncaseUsernames.down + end +end From f8b73074413d6a29932096ca0f6f28dab3b8e1ac Mon Sep 17 00:00:00 2001 From: Raphael Sofaer Date: Fri, 13 May 2011 12:14:55 -0700 Subject: [PATCH 3/6] Downcase emails upon inviting --- app/controllers/users_controller.rb | 2 +- app/models/invitation.rb | 1 + app/models/user.rb | 2 +- config/deploy.rb | 1 + ...20110512220310_downcase_usernames_again.rb | 10 ------- ...0513175000_eliminate_stray_user_records.rb | 29 +++++++++++++++++++ spec/models/invitation_spec.rb | 2 +- 7 files changed, 34 insertions(+), 13 deletions(-) delete mode 100644 db/migrate/20110512220310_downcase_usernames_again.rb create mode 100644 db/migrate/20110513175000_eliminate_stray_user_records.rb diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 431259e51..a0e0f2f51 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -32,7 +32,7 @@ class UsersController < ApplicationController if u[:email_preferences] @user.update_user_preferences(u[:email_preferences]) flash[:notice] = I18n.t 'users.update.email_notifications_changed' - # change passowrd + # change password elsif u[:current_password] && u[:password] && u[:password_confirmation] if @user.update_with_password(u) flash[:notice] = I18n.t 'users.update.password_changed' diff --git a/app/models/invitation.rb b/app/models/invitation.rb index 0ac394dba..a0527977f 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -11,6 +11,7 @@ class Invitation < ActiveRecord::Base validates_presence_of :sender, :recipient, :aspect def self.invite(opts = {}) + opts[:identifier].downcase! return false if opts[:identifier] == opts[:from].email existing_user = self.find_existing_user(opts[:service], opts[:identifier]) diff --git a/app/models/user.rb b/app/models/user.rb index 8707c4f6d..23894a777 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -15,7 +15,7 @@ class User < ActiveRecord::Base :recoverable, :rememberable, :trackable, :validatable, :timeoutable - before_validation :strip_and_downcase_username, :on => :create + before_validation :strip_and_downcase_username before_validation :set_current_language, :on => :create validates_presence_of :username diff --git a/config/deploy.rb b/config/deploy.rb index 39052bb6c..2069cec3c 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -17,6 +17,7 @@ set :use_sudo, false set :scm_verbose, true set :repository_cache, "remote_cache" set :deploy_via, :checkout +set :branch, 'devise_invitable-update' namespace :deploy do task :symlink_config_files do diff --git a/db/migrate/20110512220310_downcase_usernames_again.rb b/db/migrate/20110512220310_downcase_usernames_again.rb deleted file mode 100644 index 02eeed8eb..000000000 --- a/db/migrate/20110512220310_downcase_usernames_again.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'db/migrate/20110421120744_downcase_usernames' -class DowncaseUsernamesAgain < ActiveRecord::Migration - def self.up - DowncaseUsernames.up - end - - def self.down - DowncaseUsernames.down - end -end diff --git a/db/migrate/20110513175000_eliminate_stray_user_records.rb b/db/migrate/20110513175000_eliminate_stray_user_records.rb new file mode 100644 index 000000000..856d36ab7 --- /dev/null +++ b/db/migrate/20110513175000_eliminate_stray_user_records.rb @@ -0,0 +1,29 @@ +class EliminateStrayUserRecords < ActiveRecord::Migration + def self.up + duplicated_emails = execute("SELECT LOWER(email) from users GROUP BY LOWER(email) HAVING COUNT(*) > 1").to_a + duplicated_emails.each do |email| + records = execute("SELECT users.id, users.username, users.created_at from users WHERE LOWER(users.email) = '#{email}'").to_a + with_username = records.select { |r| !r[1].blank? } + if with_username.length == 1 + execute("DELETE FROM users WHERE LOWER(users.email) = '#{email}' AND users.username IS NULL") + end + if with_username.length == 0 + newest_record = records.sort_by{|r| r[2].to_i}.last + execute("DELETE FROM users WHERE LOWER(users.email) = '#{email}' AND users.id != #{newest_record[0]}") + end + end + execute < Date: Fri, 13 May 2011 14:21:17 -0700 Subject: [PATCH 4/6] Don't delete facebook invitations --- db/migrate/20110513175000_eliminate_stray_user_records.rb | 4 ++-- db/schema.rb | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/db/migrate/20110513175000_eliminate_stray_user_records.rb b/db/migrate/20110513175000_eliminate_stray_user_records.rb index 856d36ab7..7bd1ee00a 100644 --- a/db/migrate/20110513175000_eliminate_stray_user_records.rb +++ b/db/migrate/20110513175000_eliminate_stray_user_records.rb @@ -1,13 +1,13 @@ class EliminateStrayUserRecords < ActiveRecord::Migration def self.up - duplicated_emails = execute("SELECT LOWER(email) from users GROUP BY LOWER(email) HAVING COUNT(*) > 1").to_a + duplicated_emails = execute("SELECT LOWER(email) from users WHERE users.email != '' GROUP BY LOWER(email) HAVING COUNT(*) > 1").to_a duplicated_emails.each do |email| records = execute("SELECT users.id, users.username, users.created_at from users WHERE LOWER(users.email) = '#{email}'").to_a with_username = records.select { |r| !r[1].blank? } if with_username.length == 1 execute("DELETE FROM users WHERE LOWER(users.email) = '#{email}' AND users.username IS NULL") end - if with_username.length == 0 + if with_username.length == 0 && !email.blank? newest_record = records.sort_by{|r| r[2].to_i}.last execute("DELETE FROM users WHERE LOWER(users.email) = '#{email}' AND users.id != #{newest_record[0]}") end diff --git a/db/schema.rb b/db/schema.rb index 7a87f0dda..6170e86b9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20110507212759) do +ActiveRecord::Schema.define(:version => 20110513175000) do create_table "aspect_memberships", :force => true do |t| t.integer "aspect_id", :null => false @@ -357,9 +357,11 @@ ActiveRecord::Schema.define(:version => 20110507212759) do t.string "language" t.string "email", :default => "", :null => false t.string "encrypted_password", :limit => 128, :default => "", :null => false - t.string "password_salt", :default => "", :null => false - t.string "invitation_token", :limit => 20 + t.string "invitation_token", :limit => 60 t.datetime "invitation_sent_at" + t.integer "invitation_limit" + t.integer "invited_by_id" + t.string "invited_by_type" t.string "reset_password_token" t.string "remember_token" t.datetime "remember_created_at" From a4f81c6410e257ff18d6373dc95b2f0dade795af Mon Sep 17 00:00:00 2001 From: Raphael Sofaer Date: Fri, 13 May 2011 16:29:54 -0700 Subject: [PATCH 5/6] Finish fixing password changing and keeping emails downcased --- app/controllers/users_controller.rb | 8 +++++++- app/models/invitation.rb | 2 +- app/models/person.rb | 2 +- config/locales/diaspora/en.yml | 2 +- features/change_password.feature | 7 +++---- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a0e0f2f51..b0001ad64 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -21,6 +21,7 @@ class UsersController < ApplicationController def update + password_changed = false u = params[:user] @user = current_user @@ -35,6 +36,7 @@ class UsersController < ApplicationController # change password elsif u[:current_password] && u[:password] && u[:password_confirmation] if @user.update_with_password(u) + password_changed = true flash[:notice] = I18n.t 'users.update.password_changed' else flash[:error] = I18n.t 'users.update.password_not_changed' @@ -58,7 +60,11 @@ class UsersController < ApplicationController render :nothing => true, :status => 204 } format.all{ - redirect_to edit_user_path + if password_changed + redirect_to new_user_session_path + else + redirect_to edit_user_path + end } end end diff --git a/app/models/invitation.rb b/app/models/invitation.rb index a0527977f..80336c405 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -11,7 +11,7 @@ class Invitation < ActiveRecord::Base validates_presence_of :sender, :recipient, :aspect def self.invite(opts = {}) - opts[:identifier].downcase! + opts[:identifier].downcase! if opts[:identifier] return false if opts[:identifier] == opts[:from].email existing_user = self.find_existing_user(opts[:service], opts[:identifier]) diff --git a/app/models/person.rb b/app/models/person.rb index 45128e3db..511c0ccad 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -22,7 +22,7 @@ class Person < ActiveRecord::Base before_validation :downcase_diaspora_handle def downcase_diaspora_handle - diaspora_handle.downcase! + diaspora_handle.downcase! unless diaspora_handle.blank? end has_many :contacts #Other people's contacts for this person diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 68dc49ff7..1c33450bf 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -645,7 +645,7 @@ en: find_your_friends_on_diaspora: "Would you like to find your Facebook friends on Diaspora?" skip: "Skip" update: - password_changed: "Password Changed" + password_changed: "Password Changed. You can now log in with your new password." password_not_changed: "Password Change Failed" language_changed: "Language Changed" language_not_changed: "Language Change Failed" diff --git a/features/change_password.feature b/features/change_password.feature index d93f2c725..aeb80bad2 100644 --- a/features/change_password.feature +++ b/features/change_password.feature @@ -10,8 +10,7 @@ Feature: Change password And I fill in "user_password" with "newsecret" And I fill in "user_password_confirmation" with "newsecret" And I press "Change Password" - Then I should see "Password Changed" - When I sign out - Then I should be on the home page - And I sign in with password "newsecret" + Then I should see "Password Changed" + Then I should be on the new user session page + When I sign in with password "newsecret" Then I should be on the aspects page From 32ceb278bfe792963b134fe245c37587340047a5 Mon Sep 17 00:00:00 2001 From: Raphael Sofaer Date: Fri, 13 May 2011 16:35:55 -0700 Subject: [PATCH 6/6] Restore deploy.rb --- config/deploy.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/deploy.rb b/config/deploy.rb index 2069cec3c..39052bb6c 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -17,7 +17,6 @@ set :use_sudo, false set :scm_verbose, true set :repository_cache, "remote_cache" set :deploy_via, :checkout -set :branch, 'devise_invitable-update' namespace :deploy do task :symlink_config_files do