mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add support for generate scaffold password:digest
* adds password_digest attribute to the migration * adds has_secure_password to the model * adds password and password_confirmation password_fields to _form.html * omits password entirely from index.html and show.html * adds password and password_confirmation to the controller * adds unencrypted password and password_confirmation to the controller test * adds encrypted password_digest to the fixture
This commit is contained in:
parent
cd9f7508df
commit
3008994d1e
11 changed files with 90 additions and 14 deletions
|
@ -2,8 +2,12 @@ class <%= migration_class_name %> < ActiveRecord::Migration
|
||||||
def change
|
def change
|
||||||
create_table :<%= table_name %> do |t|
|
create_table :<%= table_name %> do |t|
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.each do |attribute| -%>
|
||||||
|
<% if attribute.password_digest? -%>
|
||||||
|
t.string :password_digest<%= attribute.inject_options %>
|
||||||
|
<% else -%>
|
||||||
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
<% end -%>
|
||||||
<% if options[:timestamps] %>
|
<% if options[:timestamps] %>
|
||||||
t.timestamps
|
t.timestamps
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<% module_namespacing do -%>
|
<% module_namespacing do -%>
|
||||||
class <%= class_name %> < <%= parent_class_name.classify %>
|
class <%= class_name %> < <%= parent_class_name.classify %>
|
||||||
<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
|
<% attributes.select(&:reference?).each do |attribute| -%>
|
||||||
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
<% if attributes.any?(&:password_digest?) -%>
|
||||||
|
has_secure_password
|
||||||
|
<% end -%>
|
||||||
end
|
end
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
## Rails 4.0.0 (unreleased) ##
|
## Rails 4.0.0 (unreleased) ##
|
||||||
|
|
||||||
|
* Add support for generate scaffold password:digest
|
||||||
|
|
||||||
|
* adds password_digest attribute to the migration
|
||||||
|
* adds has_secure_password to the model
|
||||||
|
* adds password and password_confirmation password_fields to _form.html
|
||||||
|
* omits password from index.html and show.html
|
||||||
|
* adds password and password_confirmation to the controller
|
||||||
|
* adds unencrypted password and password_confirmation to the controller test
|
||||||
|
* adds encrypted password_digest to the fixture
|
||||||
|
|
||||||
|
*Sam Ruby*
|
||||||
|
|
||||||
* Rails now generates a `test/test_helper.rb` file with `fixtures :all` commented out by default,
|
* Rails now generates a `test/test_helper.rb` file with `fixtures :all` commented out by default,
|
||||||
since we don't want to force loading all fixtures for user when a single test is run. However,
|
since we don't want to force loading all fixtures for user when a single test is run. However,
|
||||||
fixtures are still going to be loaded automatically for test suites.
|
fixtures are still going to be loaded automatically for test suites.
|
||||||
|
|
|
@ -13,8 +13,17 @@
|
||||||
|
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.each do |attribute| -%>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<% if attribute.password_digest? -%>
|
||||||
|
<%%= f.label :password %><br />
|
||||||
|
<%%= f.password_field :password %>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<%%= f.label :password_confirmation %><br />
|
||||||
|
<%%= f.password_field :password_confirmation %>
|
||||||
|
<% else -%>
|
||||||
<%%= f.label :<%= attribute.name %> %><br />
|
<%%= f.label :<%= attribute.name %> %><br />
|
||||||
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
|
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
|
||||||
|
<% end -%>
|
||||||
</div>
|
</div>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
||||||
<th><%= attribute.human_name %></th>
|
<th><%= attribute.human_name %></th>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
|
<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
|
||||||
<tr>
|
<tr>
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
||||||
<td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
|
<td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<td><%%= link_to 'Show', <%= singular_table_name %> %></td>
|
<td><%%= link_to 'Show', <%= singular_table_name %> %></td>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<p id="notice"><%%= notice %></p>
|
<p id="notice"><%%= notice %></p>
|
||||||
|
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
||||||
<p>
|
<p>
|
||||||
<strong><%= attribute.human_name %>:</strong>
|
<strong><%= attribute.human_name %>:</strong>
|
||||||
<%%= @<%= singular_table_name %>.<%= attribute.name %> %>
|
<%%= @<%= singular_table_name %>.<%= attribute.name %> %>
|
||||||
|
|
|
@ -130,6 +130,10 @@ module Rails
|
||||||
@has_uniq_index
|
@has_uniq_index
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def password_digest?
|
||||||
|
name == 'password' && type == :digest
|
||||||
|
end
|
||||||
|
|
||||||
def inject_options
|
def inject_options
|
||||||
"".tap { |s| @attr_options.each { |k,v| s << ", #{k}: #{v.inspect}" } }
|
"".tap { |s| @attr_options.each { |k,v| s << ", #{k}: #{v.inspect}" } }
|
||||||
end
|
end
|
||||||
|
|
|
@ -163,6 +163,7 @@ module Rails
|
||||||
def attributes_names
|
def attributes_names
|
||||||
@attributes_names ||= attributes.each_with_object([]) do |a, names|
|
@attributes_names ||= attributes.each_with_object([]) do |a, names|
|
||||||
names << a.column_name
|
names << a.column_name
|
||||||
|
names << 'password_confirmation' if a.password_digest?
|
||||||
names << "#{a.name}_type" if a.polymorphic?
|
names << "#{a.name}_type" if a.polymorphic?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
|
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
|
||||||
|
|
||||||
<% unless attributes.empty? -%>
|
<% unless attributes.empty? -%>
|
||||||
one:
|
<% %w(one two).each do |name| %>
|
||||||
|
<%= name %>:
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.each do |attribute| -%>
|
||||||
|
<%- if attribute.password_digest? -%>
|
||||||
|
password_digest: <%%= BCrypt::Password.create('secret') %>
|
||||||
|
<%- else -%>
|
||||||
<%= yaml_key_value(attribute.column_name, attribute.default) %>
|
<%= yaml_key_value(attribute.column_name, attribute.default) %>
|
||||||
|
<%- end -%>
|
||||||
<%- if attribute.polymorphic? -%>
|
<%- if attribute.polymorphic? -%>
|
||||||
<%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %>
|
<%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
two:
|
|
||||||
<% attributes.each do |attribute| -%>
|
|
||||||
<%= yaml_key_value(attribute.column_name, attribute.default) %>
|
|
||||||
<%- if attribute.polymorphic? -%>
|
|
||||||
<%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %>
|
|
||||||
<%- end -%>
|
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% else -%>
|
<% else -%>
|
||||||
|
|
||||||
# This model initially had no columns defined. If you add columns to the
|
# This model initially had no columns defined. If you add columns to the
|
||||||
# model remove the '{}' from the fixture names and add the columns immediately
|
# model remove the '{}' from the fixture names and add the columns immediately
|
||||||
# below each fixture, per the syntax in the comments below
|
# below each fixture, per the syntax in the comments below
|
||||||
|
|
|
@ -21,7 +21,11 @@ module TestUnit # :nodoc:
|
||||||
return if attributes_names.empty?
|
return if attributes_names.empty?
|
||||||
|
|
||||||
attributes_names.map do |name|
|
attributes_names.map do |name|
|
||||||
"#{name}: @#{singular_table_name}.#{name}"
|
if %w(password password_confirmation).include?(name) && attributes.any?(&:password_digest?)
|
||||||
|
"#{name}: 'secret'"
|
||||||
|
else
|
||||||
|
"#{name}: @#{singular_table_name}.#{name}"
|
||||||
|
end
|
||||||
end.sort.join(', ')
|
end.sort.join(', ')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -271,4 +271,45 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_scaffold_generator_password_digest
|
||||||
|
run_generator ["user", "name", "password:digest"]
|
||||||
|
|
||||||
|
assert_file "app/models/user.rb", /has_secure_password/
|
||||||
|
|
||||||
|
assert_migration "db/migrate/create_users.rb" do |m|
|
||||||
|
assert_method :change, m do |up|
|
||||||
|
assert_match(/t\.string :name/, up)
|
||||||
|
assert_match(/t\.string :password_digest/, up)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_file "app/controllers/users_controller.rb" do |content|
|
||||||
|
assert_instance_method :user_params, content do |m|
|
||||||
|
assert_match(/permit\(:name, :password, :password_confirmation\)/, m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_file "app/views/users/_form.html.erb" do |content|
|
||||||
|
assert_match(/<%= f\.password_field :password %>/, content)
|
||||||
|
assert_match(/<%= f\.password_field :password_confirmation %>/, content)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_file "app/views/users/index.html.erb" do |content|
|
||||||
|
assert_no_match(/password/, content)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_file "app/views/users/show.html.erb" do |content|
|
||||||
|
assert_no_match(/password/, content)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_file "test/controllers/users_controller_test.rb" do |content|
|
||||||
|
assert_match(/password: 'secret'/, content)
|
||||||
|
assert_match(/password_confirmation: 'secret'/, content)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_file "test/fixtures/users.yml" do |content|
|
||||||
|
assert_match(/password_digest: <%= BCrypt::Password.create\('secret'\) %>/, content)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue