autoforme 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 83fda57cc1135158108ed30103403c23d0600ccf
4
- data.tar.gz: 42e3f1e0bae263ea3e5babc767cb3492bf2f5efe
2
+ SHA256:
3
+ metadata.gz: 5112ef1a062e3fa4a586f605365004eb733e25c7e49c7d52d0399d2d5596a692
4
+ data.tar.gz: 3142feb7e88e43ec825eedb9dfa700dd2c710cdce59b7839241117ad66b6568a
5
5
  SHA512:
6
- metadata.gz: 0d716b34aec6a9b8a7e85e6c3928a029240ff1959b3e94358cdbcd974164f34a6a68206d698977d5cdfedbf253b6973ae04713574693f20d18c6933647e7c47f
7
- data.tar.gz: fc8efa80a2e498952c10c1052b9eccee17d20a5d488e7416537e3eae89b76f6505cddf3058be80580f139e959f5d3a9f82c2c8bbfb411b172f7783e704b5f0c0
6
+ metadata.gz: 937e7ced506f742fbd9ec7632cf69a6a93b1996d884a63996162a38ad949c0ef3b6022a910fe51748f9792c9d9ce3703ffa6691e321f93bcd9917e05f3f24677
7
+ data.tar.gz: a369fc3b50aef5cf9546fb512c0d92a63de9cc0f15b8ac16f84b5fa2291f688ea10f0a711ddf9573b3e1c6257015174c147f05af6e7f073ae37be1e392386c85
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ === 1.8.0 (2018-06-11)
2
+
3
+ * Add support for Roda route_csrf plugin for request-specific CSRF tokens (jeremyevans)
4
+
5
+ * Default to size of 10 for select multiple inputs (jeremyevans)
6
+
1
7
  === 1.7.0 (2017-10-27)
2
8
 
3
9
  * Respect Model#forme_namespace method for parameter names (adam12, jeremyevans) (#9)
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2017 Jeremy Evans
1
+ Copyright (c) 2013-2018 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
@@ -197,7 +197,7 @@ symbol and request).
197
197
 
198
198
  Additionally, AutoForme.for accepts a :prefix option that controls where the forms are mounted:
199
199
 
200
- AutoForm.for(:sinatra, self, :prefix=>'/path/to') do
200
+ AutoForme.for(:sinatra, self, :prefix=>'/path/to') do
201
201
  model Artist
202
202
  end
203
203
 
@@ -225,11 +225,11 @@ module AutoForme
225
225
  end
226
226
 
227
227
  # Options to use for the form. If the form uses POST, automatically adds the CSRF token.
228
- def form_opts
228
+ def form_opts(action=nil)
229
229
  opts = model.form_options_for(type, request).dup
230
230
  hidden_tags = opts[:hidden_tags] = []
231
- if csrf = request.csrf_token_hash
232
- hidden_tags << lambda{|tag| csrf if tag.attr[:method].to_s.upcase == 'POST'}
231
+ if csrf = request.csrf_token_hash(action)
232
+ hidden_tags << lambda{|tag| csrf if (tag.attr[:method] || tag.attr['method']).to_s.upcase == 'POST'}
233
233
  end
234
234
  opts
235
235
  end
@@ -243,7 +243,8 @@ module AutoForme
243
243
  # HTML content used for the new action
244
244
  def new_page(obj, opts={})
245
245
  page do
246
- Forme.form(obj, form_attributes(:action=>url_for("create")), form_opts) do |f|
246
+ form_attr = form_attributes(:action=>url_for("create"))
247
+ Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f|
247
248
  model.columns_for(:new, request).each do |column|
248
249
  col_opts = column_options_for(:new, request, obj, column)
249
250
  if html = model.edit_html_for(obj, column, :new, request)
@@ -318,7 +319,8 @@ module AutoForme
318
319
  end.to_s
319
320
  end
320
321
  if type == :delete
321
- t << Forme.form(form_attributes(:action=>url_for("destroy/#{model.primary_key_value(obj)}"), :method=>:post), form_opts) do |f1|
322
+ form_attr = form_attributes(:action=>url_for("destroy/#{model.primary_key_value(obj)}"), :method=>:post)
323
+ t << Forme.form(form_attr, form_opts(form_attr[:action])) do |f1|
322
324
  f1.button(:value=>'Delete', :class=>'btn btn-danger')
323
325
  end.to_s
324
326
  else
@@ -341,7 +343,8 @@ module AutoForme
341
343
  def edit_page(obj)
342
344
  page do
343
345
  t = String.new
344
- t << Forme.form(obj, form_attributes(:action=>url_for("update/#{model.primary_key_value(obj)}")), form_opts) do |f|
346
+ form_attr = form_attributes(:action=>url_for("update/#{model.primary_key_value(obj)}"))
347
+ t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f|
345
348
  model.columns_for(:edit, request).each do |column|
346
349
  col_opts = column_options_for(:edit, request, obj, column)
347
350
  if html = model.edit_html_for(obj, column, :edit, request)
@@ -479,7 +482,8 @@ module AutoForme
479
482
  page do
480
483
  t = String.new
481
484
  t << "<h2>Edit #{humanize(assoc)} for #{h model.object_display_name(type, request, obj)}</h2>"
482
- t << Forme.form(obj, form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}")), form_opts) do |f|
485
+ form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}"))
486
+ t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f|
483
487
  opts = model.column_options_for(:mtm_edit, request, assoc)
484
488
  add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts
485
489
  remove_opts = opts[:remove] ? opts.merge(opts.delete(:remove)) : opts
@@ -487,9 +491,9 @@ module AutoForme
487
491
  if model.association_autocomplete?(assoc, request)
488
492
  f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge(add_opts))
489
493
  else
490
- f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj)}.merge(add_opts))
494
+ f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :size=>10}.merge(add_opts))
491
495
  end
492
- f.input(assoc, {:name=>'remove[]', :id=>'remove', :label=>'Disassociate From', :dataset=>model.associated_mtm_objects(request, assoc, obj), :value=>[]}.merge(remove_opts))
496
+ f.input(assoc, {:name=>'remove[]', :id=>'remove', :label=>'Disassociate From', :dataset=>model.associated_mtm_objects(request, assoc, obj), :value=>[], :size=>10}.merge(remove_opts))
493
497
  f.button(:value=>'Update', :class=>'btn btn-primary')
494
498
  end.to_s
495
499
  end
@@ -641,7 +645,7 @@ module AutoForme
641
645
  t << "<div class='inline_mtm_add_associations'>"
642
646
  assocs.each do |assoc|
643
647
  form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}&redir=edit"), :class => 'mtm_add_associations', 'data-remove' => "##{assoc}_remove_list")
644
- t << Forme.form(obj, form_attr, form_opts) do |f|
648
+ t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f|
645
649
  opts = model.column_options_for(:mtm_edit, request, assoc)
646
650
  add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts.dup
647
651
  add_opts = {:name=>'add[]', :id=>"add_#{assoc}"}.merge(add_opts)
@@ -674,7 +678,7 @@ module AutoForme
674
678
  t << "<li>"
675
679
  t << association_link(mc, assoc_obj)
676
680
  form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}&remove%5b%5d=#{model.primary_key_value(assoc_obj)}&redir=edit"), :method=>'post', :class => 'mtm_remove_associations', 'data-add'=>"#add_#{assoc}")
677
- t << Forme.form(form_attr, form_opts) do |f|
681
+ t << Forme.form(form_attr, form_opts(form_attr[:action])) do |f|
678
682
  f.button(:value=>'Remove', :class=>'btn btn-xs btn-danger')
679
683
  end.to_s
680
684
  t << "</li>"
@@ -29,7 +29,7 @@ module AutoForme
29
29
  end
30
30
 
31
31
  # Use Rails's form_authenticity_token for CSRF protection.
32
- def csrf_token_hash
32
+ def csrf_token_hash(action=nil)
33
33
  vc = @controller.view_context
34
34
  {vc.request_forgery_protection_token.to_s=>vc.form_authenticity_token} if vc.protect_against_forgery?
35
35
  end
@@ -38,8 +38,20 @@ module AutoForme
38
38
  end
39
39
 
40
40
  # Use Rack::Csrf for csrf protection if it is defined.
41
- def csrf_token_hash
42
- {::Rack::Csrf.field=>::Rack::Csrf.token(@env)} if defined?(::Rack::Csrf)
41
+ def csrf_token_hash(action=nil)
42
+ if @controller.respond_to?(:check_csrf!)
43
+ # Using route_csrf plugin
44
+ # :nocov:
45
+ token = if @controller.use_request_specific_csrf_tokens?
46
+ @controller.csrf_token(@controller.csrf_path(action))
47
+ else
48
+ @controller.csrf_token
49
+ end
50
+ {@controller.csrf_field=>token}
51
+ # :nocov:
52
+ elsif defined?(::Rack::Csrf)
53
+ {::Rack::Csrf.field=>::Rack::Csrf.token(@env)}
54
+ end
43
55
  end
44
56
  end
45
57
 
@@ -29,7 +29,7 @@ module AutoForme
29
29
  end
30
30
 
31
31
  # Use Rack::Csrf for csrf protection if it is defined.
32
- def csrf_token_hash
32
+ def csrf_token_hash(action=nil)
33
33
  {::Rack::Csrf.field=>::Rack::Csrf.token(@env)} if defined?(::Rack::Csrf)
34
34
  end
35
35
  end
@@ -1,8 +1,22 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module AutoForme
4
+ # The major version of AutoForme, updated only for major changes that are
5
+ # likely to require modification to apps using AutoForme.
6
+ MAJOR = 1
7
+
8
+ # The minor version of AutoForme, updated for new feature releases of AutoForme.
9
+ MINOR = 8
10
+
11
+ # The patch version of AutoForme, updated only for bug fixes from the last
12
+ # feature release.
13
+ TINY = 0
14
+
4
15
  # Version constant, use <tt>AutoForme.version</tt> instead.
5
- VERSION = '1.7.0'.freeze
16
+ VERSION = "#{MAJOR}.#{MINOR}.#{TINY}".freeze
17
+
18
+ # The full version of AutoForme as a number (1.8.0 => 10800)
19
+ VERSION_NUMBER = MAJOR*10000 + MINOR*100 + TINY
6
20
 
7
21
  # Returns the version as a frozen string (e.g. '0.1.0')
8
22
  def self.version
@@ -5,6 +5,9 @@ require 'autoforme'
5
5
  class AutoFormeSpec::App
6
6
  def self.autoforme(klass=nil, opts={}, &block)
7
7
  sc = Class.new(Rails::Application)
8
+ def sc.name
9
+ "AutoForme Test"
10
+ end
8
11
  framework = nil
9
12
  sc.class_eval do
10
13
  controller = Class.new(ActionController::Base)
@@ -50,13 +53,14 @@ HTML
50
53
  end
51
54
  end
52
55
 
53
- config.secret_token = routes.append do
56
+ st = routes.append do
54
57
  get 'session/set', :controller=>'autoforme', :action=>'session_set'
55
58
  end.inspect
59
+ config.secret_token = st if Rails.respond_to?(:version) && Rails.version < '5.2'
56
60
  config.active_support.deprecation = :stderr
57
61
  config.middleware.delete(ActionDispatch::ShowExceptions)
58
62
  config.middleware.delete(Rack::Lock)
59
- config.secret_key_base = 'foo'
63
+ config.secret_key_base = st*15
60
64
  config.eager_load = true
61
65
  if Rails.version > '4.2'
62
66
  config.action_dispatch.cookies_serializer = :json
@@ -31,7 +31,11 @@ class AutoFormeSpec::App < Roda
31
31
  HTML
32
32
 
33
33
  use Rack::Session::Cookie, :secret => '1'
34
- use Rack::Csrf
34
+ if ENV['RODA_ROUTE_CSRF'].to_i > 0
35
+ plugin :route_csrf, :require_request_specific_tokens=>ENV['RODA_ROUTE_CSRF'] == '1'
36
+ else
37
+ use Rack::Csrf
38
+ end
35
39
 
36
40
  template_opts = {:default_encoding=>nil}
37
41
  plugin :render, :layout=>{:inline=>LAYOUT}, :template_opts=>template_opts, :opts=>template_opts
@@ -54,6 +58,8 @@ HTML
54
58
  end
55
59
 
56
60
  route do |r|
61
+ check_csrf! if ENV['RODA_ROUTE_CSRF'].to_i > 0
62
+
57
63
  r.get 'session/set' do
58
64
  session.merge!(r.params)
59
65
  ''
@@ -24,13 +24,15 @@ require "./spec/#{ENV['FRAMEWORK']}_spec_helper"
24
24
  require 'capybara'
25
25
  require 'capybara/dsl'
26
26
  require 'rack/test'
27
+
28
+ ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
27
29
  gem 'minitest'
28
30
  require 'minitest/autorun'
29
31
  require 'minitest/hooks/default'
30
32
 
31
33
  if ENV['WARNING']
32
34
  require 'warning'
33
- Warning.ignore([:missing_ivar, :fixnum])
35
+ Warning.ignore([:missing_ivar, :fixnum, :not_reached])
34
36
  end
35
37
 
36
38
  require './spec/sequel_spec_helper'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoforme
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-27 00:00:00.000000000 Z
11
+ date: 2018-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forme
@@ -267,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
267
  version: '0'
268
268
  requirements: []
269
269
  rubyforge_project:
270
- rubygems_version: 2.6.13
270
+ rubygems_version: 2.7.6
271
271
  signing_key:
272
272
  specification_version: 4
273
273
  summary: Web Administrative Console for Roda/Sinatra/Rails and Sequel::Model