sanitize-rails 0.5.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.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ Sanitize-Rails - sanitize .. on Rails.
2
+ ======================================
3
+
4
+ Installation
5
+ ------------
6
+
7
+ gem install sanitize-rails
8
+
9
+ Configuration
10
+ -------------
11
+
12
+ config/initializers/sanitizer.rb:
13
+
14
+ Sanitize::Rails.configure(
15
+ :elements => [ ... ],
16
+ :attribiutes => { ... },
17
+ ...
18
+ )
19
+
20
+ Usage
21
+ -----
22
+
23
+ app/models/foo.rb:
24
+
25
+ sanitizes :field
26
+ sanitizes :some_other_field, :on => :create
27
+ sanitizes :yet_another_field, :on => :save
28
+
29
+ ActionView `sanitize` helper is overriden to use
30
+ the Sanitize gem - transparently.
31
+
32
+ Testing
33
+ -------
34
+
35
+ Only Test::Unit for now - please write matchers
36
+ and send a pull request :-)
37
+
38
+ test/test\_helper:
39
+
40
+ Sanitize::Rails::TestHelpers.setup(self,
41
+ :invalid => 'some <a>string',
42
+ :valid => 'some <a>string</a>'
43
+ )
44
+
45
+ your test:
46
+
47
+ assert_sanitizes(Model, :field, :some_other_field)
48
+
49
+ Compatibility
50
+ -------------
51
+
52
+ Tested with Rails 3.0.x under Ruby 1.8 and 1.9.
53
+
54
+ Have fun.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+
4
+ require 'lib/sanitize/rails'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gemspec|
9
+ gemspec.name = 'sanitize-rails'
10
+
11
+ gemspec.summary = 'A sanitizer bridge for Rails applications'
12
+ gemspec.authors = ['Marcello Barnaba']
13
+ gemspec.email = 'vjt@openssl.it'
14
+ gemspec.homepage = 'http://github.com/vjt/sanitize-rails'
15
+
16
+ gemspec.files = %w( README.md Rakefile rails/init.rb ) + Dir['lib/**/*']
17
+ gemspec.extra_rdoc_files = %w( README.md )
18
+ gemspec.has_rdoc = true
19
+
20
+ gemspec.version = Sanitize::Rails::Version
21
+ gemspec.require_path = 'lib'
22
+
23
+ gemspec.add_dependency('rails', '~> 3.0')
24
+ gemspec.add_dependency('sanitize')
25
+ end
26
+ rescue LoadError
27
+ puts 'Jeweler not available. Install it with: gem install jeweler'
28
+ end
29
+
30
+ desc 'Generate the rdoc'
31
+ Rake::RDocTask.new do |rdoc|
32
+ rdoc.rdoc_files.add %w( README.md lib/**/*.rb )
33
+
34
+ rdoc.main = 'README.md'
35
+ rdoc.title = 'Sanitizer-Rails'
36
+ end
37
+
38
+ desc 'Will someone help write tests?'
39
+ task :default do
40
+ puts
41
+ puts 'Can you help in writing tests? Please do :-)'
42
+ puts
43
+ end
@@ -0,0 +1,188 @@
1
+ # Sanitize gem bridge and helpers
2
+ #
3
+ require 'sanitize'
4
+ require 'sanitize/railtie' if defined? Rails
5
+
6
+ module Sanitize::Rails
7
+ Version = '0.5.0'
8
+
9
+ # Configures the sanitizer with the given `config` hash.
10
+ #
11
+ # In your environment.rb, in the after_initialize block:
12
+ #
13
+ # Sanitize::Rails.configure(
14
+ # :elements => [ ... ],
15
+ # :attributes => [ ... ],
16
+ # ...
17
+ # )
18
+ #
19
+ def self.configure(config)
20
+ Engine.configure(config)
21
+ end
22
+
23
+ module Engine
24
+ extend self
25
+
26
+ def configure(config)
27
+ @@config = config.freeze
28
+ end
29
+
30
+ # Returns a memoized instance of the Engine with the
31
+ # configuration passed to the +configure+ method or with
32
+ # the Gem default configuration.
33
+ #
34
+ def cleaner
35
+ @sanitizer ||= ::Sanitize.new(@@config || {})
36
+ end
37
+
38
+ # Returns a copy of the given `string` after sanitizing it
39
+ #
40
+ def clean(string)
41
+ string.dup.tap {|s| clean!(s)} unless string.blank?
42
+ end
43
+
44
+ # Sanitizes the given string in place, forcing UTF-8 encoding on it.
45
+ #
46
+ def clean!(string)
47
+ cleaner.clean!(string) unless string.blank?
48
+ end
49
+
50
+ def callback_for(options) #:nodoc:
51
+ point = (options[:on] || 'save').to_s
52
+
53
+ unless %w( save create ).include?(point)
54
+ raise ArgumentError, "Invalid callback point #{point}, valid ones are :save and :create"
55
+ end
56
+
57
+ "before_#{point}".intern
58
+ end
59
+
60
+ def method_for(fields) #:nodoc:
61
+ "sanitize_#{fields.join('_')}".intern
62
+ end
63
+ end
64
+
65
+ module ActionView
66
+ def self.included(base)
67
+ base.class_eval do
68
+ # To make sure we're called *after* the method is defined
69
+ undef_method :sanitize
70
+
71
+ # Overrides ActionView's sanitize() helper to use +Engine#clean+
72
+ def sanitize(string)
73
+ Engine.clean(string)
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ # Adds the +sanitizes+ method to ActiveRecord children classes
81
+ #
82
+ module ActiveRecord
83
+ # Generates before_save/before_create filters that implement
84
+ # sanitization on the given fields, in the given callback
85
+ # point.
86
+ #
87
+ # Usage:
88
+ #
89
+ # sanitizes :some_field, :some_other_field #, :on => :save
90
+ #
91
+ # Valid callback points are :save and :create, callbacks are installed "before_"
92
+ # by default. Generated callbacks are named with the "sanitize_" prefix follwed
93
+ # by the field names separated by an underscore.
94
+ #
95
+ def sanitizes(*fields)
96
+ options = fields.extract_options!
97
+ callback = Engine.callback_for(options)
98
+ sanitizer = Engine.method_for(fields)
99
+
100
+ define_method(sanitizer) do # def sanitize_fieldA_fieldB
101
+ fields.each do |field| # # Unrolled version
102
+ sanitized = Engine.clean(send(field)) # self.fieldA = Engine.clean(self.fieldA)
103
+ send("#{field}=", sanitized) # self.fieldB = Engine.clean(self.fieldB)
104
+ end # # For clarity :-)
105
+ end # end
106
+
107
+ protected sanitizer # protected :sanitize_fieldA_fieldB
108
+ send callback, sanitizer # before_save :sanitize_fieldA_fieldB
109
+ end
110
+ end
111
+
112
+ # Adds two `sanitize_as_html{,!}` helpers to String itself,
113
+ # that call +Engine#clean+ or +Engine#clean!+ in turn
114
+ #
115
+ module String
116
+ # Calls +Engine#clean+ on this String instance
117
+ #
118
+ def sanitize_as_html
119
+ Engine.clean(self)
120
+ end
121
+
122
+ # Calls +Engine#clean!+ on this String instance
123
+ #
124
+ def sanitize_as_html!
125
+ Engine.clean!(self)
126
+ end
127
+ end
128
+
129
+ # Test instrumentation
130
+ #
131
+ module TestHelpers
132
+ class << self
133
+ # Instruments the given base class with the +assert_sanitizes+
134
+ # helper, and memoizes the given options, accessible from the
135
+ # helper itself via the +valid+ and +invalid+ methods.
136
+ #
137
+ # Those methods contains two HTML strings, one assumed to be
138
+ # "invalid" and the other, well, "valid".
139
+ #
140
+ # In your ActiveSupport::Testcase:
141
+ #
142
+ # Sanitize::Rails::TestHelpers.setup(self,
143
+ # :invalid => 'some <a>string',
144
+ # :valid => 'some <a>string</a>'
145
+ # )
146
+ #
147
+ def setup(base, options = {})
148
+ base.instance_eval { include TestHelpers }
149
+ @@options = options
150
+ end
151
+
152
+ def valid; @@options[:valid] rescue nil end
153
+ def invalid; @@options[:invalid] rescue nil end
154
+ end
155
+
156
+ # Verifies that the given `klass` sanitizes the given `fields`, by
157
+ # checking both the presence of the sanitize callback and that it
158
+ # works as expected, by setting the +invalid+ string first, invoking
159
+ # the callback and then checking that the string has been changed
160
+ # into the +valid+ one.
161
+ #
162
+ # If you pass an Hash as the last argument, it can contain `:valid`,
163
+ # `:invalid` and `:object` keys. The first two ones override the
164
+ # configured defaults, while the third executes assertions on the
165
+ # specified object. If no :object is given, a new object is instantiated
166
+ # by the given `klass` with no arguments.
167
+ #
168
+ # If neither `:valid`/`:invalid` strings are configured nor are passed
169
+ # via the options, the two default strings in the method source are
170
+ # used.
171
+ #
172
+ def assert_sanitizes(klass, *fields)
173
+ options = fields.extract_options!
174
+ sanitizer = Engine.method_for(fields)
175
+
176
+ # Verify the callback works
177
+ invalid = options[:invalid] || TestHelpers.invalid || '<b>ntani<br>'
178
+ valid = options[:valid] || TestHelpers.valid || '<b>ntani<br /></b>'
179
+ object = options[:object] || klass.new
180
+
181
+ fields.each {|field| object.send("#{field}=", invalid) }
182
+
183
+ object.send sanitizer
184
+
185
+ fields.each {|field| assert_equal(valid, object.send(field)) }
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,19 @@
1
+ require 'sanitize/rails'
2
+
3
+ class Sanitize::Railtie < ::Rails::Railtie
4
+ initializer 'sanitize-rails.insert_into_action_view' do
5
+ ActiveSupport.on_load :action_view do
6
+ ActionView::Helpers::SanitizeHelper.instance_eval { include Sanitize::Rails::ActionView }
7
+ end
8
+ end
9
+
10
+ initializer 'sanitize-rails.insert_into_active_record' do
11
+ ActiveSupport.on_load :active_record do
12
+ ActiveRecord::Base.extend Sanitize::Rails::ActiveRecord
13
+ end
14
+ end
15
+
16
+ initializer 'sanitie-rails.insert_into_string' do
17
+ ::String.instance_eval { include Sanitize::Rails::String }
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sanitize-rails
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
+ platform: ruby
11
+ authors:
12
+ - Marcello Barnaba
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-03-29 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rails
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 3
30
+ - 0
31
+ version: "3.0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: sanitize
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ description:
48
+ email: vjt@openssl.it
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files:
54
+ - README.md
55
+ files:
56
+ - README.md
57
+ - Rakefile
58
+ - lib/sanitize/rails.rb
59
+ - lib/sanitize/railtie.rb
60
+ has_rdoc: true
61
+ homepage: http://github.com/vjt/sanitize-rails
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.3.7
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: A sanitizer bridge for Rails applications
92
+ test_files: []
93
+