From a919c59ceef28b9b5582cc275ab70b90f195a7ca Mon Sep 17 00:00:00 2001 From: Derek Prior Date: Fri, 14 Feb 2014 10:48:03 -0500 Subject: [PATCH] Backfill remember_token for existing user records The clearance migration to add clearance fields to an existing users table now also ensures each user has a generated remember_token. --- NEWS.md | 4 +++ features/add_migrations_to_project.feature | 7 ++-- .../step_definitions/configuration_steps.rb | 33 +++++++++++-------- lib/clearance/token.rb | 7 ++++ lib/clearance/user.rb | 5 +-- .../db/migrate/add_clearance_to_users.rb | 10 ++++++ spec/clearance/token_spec.rb | 10 ++++++ 7 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 lib/clearance/token.rb create mode 100644 spec/clearance/token_spec.rb diff --git a/NEWS.md b/NEWS.md index ee3b4e75b..9f5b5fcc7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ Thank you to all the [contributors](https://github.com/thoughtbot/clearance/graphs/contributors)! +New on MASTER +* Installing Clearance with an existing User model will now add remember tokens + to all user records. + New for 1.2.1 (March 6, 2014): * Query string is now included in the redirect URL when Clearance redirects to a previously stored URL. diff --git a/features/add_migrations_to_project.feature b/features/add_migrations_to_project.feature index 5635f7b12..4dbba97b8 100644 --- a/features/add_migrations_to_project.feature +++ b/features/add_migrations_to_project.feature @@ -14,14 +14,15 @@ Feature: add migrations to the project Scenario: Users table without clearance fields exists in the database When I install dependencies - And I create a simple migration - And I successfully run `bundle exec rake db:migrate` + And I create a simple user model + And I add an existing user And I successfully run `bundle exec rails generate clearance:install` - And I successfully run `ls db/migrate` + And I successfully run `bundle exec rake db:migrate` Then the output should contain: """ add_clearance_to_users.rb """ + And the existing user should have a remember token Scenario: Users table with clearance fields exists in the database When I install dependencies diff --git a/features/step_definitions/configuration_steps.rb b/features/step_definitions/configuration_steps.rb index 483a60c31..565f719df 100644 --- a/features/step_definitions/configuration_steps.rb +++ b/features/step_definitions/configuration_steps.rb @@ -89,21 +89,26 @@ class PostsControllerTest < ActionController::TestCase } end -When /^I create a simple migration$/ do +When /^I create a simple user model$/ do steps %Q{ - When I write to "db/migrate/001_create_users.rb" with: - """ - class CreateUsers < ActiveRecord::Migration - def self.up - create_table(:users) do |t| - t.string :email - t.string :name - end - end - def self.down - end - end - """ + When I successfully run `rails generate model user email:string name:string` + And I successfully run `bundle exec rake db:migrate` + } +end + +When /^I add an existing user$/ do + command = %q{rails runner "User.create!(email: 'a@b.com', name: 'foo')"} + + steps %Q{ + When I successfully run `#{command}` + } +end + +When /existing user should have a remember token$/ do + command = 'rails runner "exit(1) unless User.first.remember_token"' + + steps %Q{ + When I successfully run `#{command}` } end diff --git a/lib/clearance/token.rb b/lib/clearance/token.rb new file mode 100644 index 000000000..683563d04 --- /dev/null +++ b/lib/clearance/token.rb @@ -0,0 +1,7 @@ +module Clearance + class Token + def self.new + SecureRandom.hex(20).encode('UTF-8') + end + end +end diff --git a/lib/clearance/user.rb b/lib/clearance/user.rb index 541ae89c8..d4e31a1fb 100644 --- a/lib/clearance/user.rb +++ b/lib/clearance/user.rb @@ -1,5 +1,6 @@ require 'digest/sha1' require 'email_validator' +require 'clearance/token' module Clearance module User @@ -102,11 +103,11 @@ def skip_password_validation? end def generate_confirmation_token - self.confirmation_token = SecureRandom.hex(20).encode('UTF-8') + self.confirmation_token = Clearance::Token.new end def generate_remember_token - self.remember_token = SecureRandom.hex(20).encode('UTF-8') + self.remember_token = Clearance::Token.new end end end diff --git a/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb b/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb index 45ea790ca..87f271130 100644 --- a/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb +++ b/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb @@ -9,6 +9,16 @@ def self.up <% config[:new_indexes].values.each do |index| -%> <%= index %> <% end -%> + + users = select_all('SELECT id FROM users WHERE remember_token IS NULL') + + users.each do |user| + update <<-SQL + UPDATE users + SET remember_token = '#{Clearance::Token.new}' + WHERE id = '#{user['id']}' + SQL + end end def self.down diff --git a/spec/clearance/token_spec.rb b/spec/clearance/token_spec.rb new file mode 100644 index 000000000..3a2c6c9e5 --- /dev/null +++ b/spec/clearance/token_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe Clearance::Token do + it 'is a random hex string' do + token = 'my_token' + SecureRandom.stubs(:hex).with(20).returns(token) + + expect(Clearance::Token.new).to eq token + end +end