sanitized_attributes 1.1.0 → 1.1.1

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "sanitized_attributes"
8
+ gem.summary = %Q{HTML-sanitizing attribute accessors for Ruby and Rails}
9
+ gem.description = %Q{A wrapper to make automatic sanitization of incoming data easier. Uses the sanitize gem and works in both plain Ruby and Rails projects.}
10
+ gem.email = "matthew.boeh@gmail.com"
11
+ gem.homepage = "http://github.com/mboeh/sanitized_attributes"
12
+ gem.authors = ["Matthew Boeh", "CrowdCompass, Inc."]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "sanitize", "> 0"
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ spec.rcov_opts = ['--exclude', File.expand_path("~/.rvm"), "--exclude", "spec"]
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "sanitized_attributes #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.1
@@ -0,0 +1,90 @@
1
+ require 'rubygems'
2
+ require 'sanitize'
3
+ require 'sanitized_attributes/sanitized_attribute'
4
+
5
+ module SanitizedAttributes
6
+
7
+ def self.included(into)
8
+ into.extend(ClassMethods)
9
+ end
10
+
11
+ class << self
12
+
13
+ def add_option(name, &blk)
14
+ @option_transforms = nil
15
+ @options ||= {}
16
+ @options[name] = blk
17
+ end
18
+
19
+ def add_profile(name, options = {})
20
+ @profiles ||= {}
21
+ @profiles[name] = options
22
+ end
23
+
24
+ def profile(name)
25
+ @profiles ||= {}
26
+ @profiles[name] || {}
27
+ end
28
+
29
+ def sanitize_options(options)
30
+ pr =
31
+ if options.kind_of?(Symbol)
32
+ profile(options)
33
+ else
34
+ options
35
+ end
36
+ o = merge_options(default_profile, pr)
37
+ o
38
+ end
39
+
40
+ protected
41
+
42
+ def default_profile
43
+ merge_options(profile(:default), obligatory_options)
44
+ end
45
+
46
+ def merge_options(ops, new_ops)
47
+ final_ops = ops.dup
48
+ new_ops.each do |key,val|
49
+ old = final_ops[key]
50
+ if key == :transformers
51
+ final_ops[key] ||= []
52
+ final_ops[key] = ([old] + [val]).flatten.uniq.compact
53
+ else
54
+ final_ops[key] = val
55
+ end
56
+ final_ops.delete(key) if final_ops[key].nil?
57
+ end
58
+ return final_ops
59
+ end
60
+
61
+ def obligatory_options
62
+ { :transformers => option_transforms }
63
+ end
64
+
65
+ def option_transforms
66
+ @option_transforms ||=
67
+ begin
68
+ if @options
69
+ @options.map do |name, tproc|
70
+ lambda do |env|
71
+ tproc.call(env, env[:config][name]) if env[:config][name]
72
+ end
73
+ end
74
+ else
75
+ []
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+ module ClassMethods
83
+
84
+ def sanitize_attribute(attr_name, options = {})
85
+ SanitizedAttribute.add(self, attr_name, options)
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,48 @@
1
+ module SanitizedAttributes; class SanitizedAttribute
2
+
3
+ def initialize(attr_name, options = {})
4
+ @attr_name = attr_name
5
+ @options = options
6
+ end
7
+
8
+ def sanitize(content)
9
+ Sanitize.clean("<SPURIOUS-TOPLEVEL>" + content + "</SPURIOUS-TOPLEVEL>", sanitize_config).gsub(%r{</?SPURIOUS-TOPLEVEL>}, "")
10
+ end
11
+
12
+ def define_ar_writer_method(klass)
13
+ this = self
14
+ attr_name = @attr_name
15
+ klass.send(:define_method, "#{@attr_name}=") {|value|
16
+ send(:write_attribute, attr_name, this.sanitize(value))
17
+ }
18
+ end
19
+
20
+ def define_writer_method(klass)
21
+ this = self
22
+ attr_name = @attr_name
23
+ klass.send(:define_method, "#{@attr_name}_with_sanitization=") {|value|
24
+ send("#{attr_name}_without_sanitization=", this.sanitize(value))
25
+ }
26
+ end
27
+
28
+ protected
29
+
30
+ def sanitize_config
31
+ SanitizedAttributes.sanitize_options(@options)
32
+ end
33
+
34
+ class << self
35
+
36
+ def add(klass, attr_name, options = {})
37
+ attrib = new(attr_name, options)
38
+ if klass.respond_to?(:alias_method_chain)
39
+ attrib.define_ar_writer_method(klass)
40
+ else
41
+ attrib.define_writer_method(klass)
42
+ klass.send(:alias_method, "#{attr_name}_without_sanitization=", "#{attr_name}=")
43
+ klass.send(:alias_method, "#{attr_name}=", "#{attr_name}_with_sanitization=")
44
+ end
45
+ end
46
+
47
+ end
48
+ end; end
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sanitized_attributes}
8
+ s.version = "1.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Matthew Boeh", "CrowdCompass, Inc."]
12
+ s.date = %q{2011-01-27}
13
+ s.description = %q{A wrapper to make automatic sanitization of incoming data easier. Uses the sanitize gem and works in both plain Ruby and Rails projects.}
14
+ s.email = %q{matthew.boeh@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/sanitized_attributes.rb",
26
+ "lib/sanitized_attributes/sanitized_attribute.rb",
27
+ "sanitized_attributes.gemspec",
28
+ "spec/sanitized_attributes_spec.rb",
29
+ "spec/spec.opts",
30
+ "spec/spec_helper.rb"
31
+ ]
32
+ s.homepage = %q{http://github.com/mboeh/sanitized_attributes}
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.7}
35
+ s.summary = %q{HTML-sanitizing attribute accessors for Ruby and Rails}
36
+ s.test_files = [
37
+ "spec/sanitized_attributes_spec.rb",
38
+ "spec/spec_helper.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
47
+ s.add_runtime_dependency(%q<sanitize>, ["> 0"])
48
+ else
49
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
50
+ s.add_dependency(%q<sanitize>, ["> 0"])
51
+ end
52
+ else
53
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
54
+ s.add_dependency(%q<sanitize>, ["> 0"])
55
+ end
56
+ end
57
+
@@ -0,0 +1,67 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "SanitizedAttributes" do
4
+
5
+ before do
6
+ @klass = Class.new do
7
+ include SanitizedAttributes
8
+ attr_accessor :orz
9
+ attr_accessor :vux
10
+ end
11
+ SanitizedAttributes.add_option(:no_empties) do |env, forbidden_empties|
12
+ if env[:node].content.empty?
13
+ if forbidden_empties.include?(env[:node_name])
14
+ {:node => Nokogiri::XML::Text.new("", env[:node].document)}
15
+ end
16
+ end
17
+ end
18
+ SanitizedAttributes.add_option(:gsub) do |env, substitutions|
19
+ env[:node].children.each do |node|
20
+ if node.kind_of?(Nokogiri::XML::Text)
21
+ text = node.content
22
+ substitutions.each do |regex, subst|
23
+ text.gsub!(regex, subst)
24
+ end
25
+ node.content = text
26
+ end
27
+ end
28
+ nil
29
+ end
30
+ SanitizedAttributes.add_profile(:default, :gsub => { "\r" => "" })
31
+ SanitizedAttributes.add_profile(:quotes_only, :elements => %w[blockquote])
32
+ end
33
+
34
+ it "removes all HTML by default" do
35
+ @klass.module_eval do
36
+ sanitize_attribute :orz
37
+ end
38
+ obj = @klass.new
39
+ obj.orz = "<a>Orz are not *many bubbles* like <p/>*campers*. <p></p>Orz <b>are just</b> Orz. <p>- Orz</p>"
40
+ obj.orz.should == "Orz are not *many bubbles* like *campers*. Orz are just Orz. - Orz"
41
+ end
42
+
43
+ it "allows a default sanitizing profile to be set up" do
44
+ SanitizedAttributes.add_profile(:default, Sanitize::Config::BASIC)
45
+ @klass.module_eval do
46
+ sanitize_attribute :orz
47
+ end
48
+ obj = @klass.new
49
+ obj.orz = "<a>Orz are not *many bubbles* like <p/>*campers*. <p></p>Orz <b>are just</b> Orz. <p>- Orz</p>"
50
+ obj.orz.should == "<a rel=\"nofollow\">Orz are not *many bubbles* like <p></p>*campers*. <p></p>Orz <b>are just</b> Orz. <p>- Orz</p></a>"
51
+ SanitizedAttributes.add_profile(:default, Sanitize::Config::BASIC.merge(:no_empties => %w[p]))
52
+ obj.orz = "<a>Orz are not *many bubbles* like <p/>*campers*. <p></p>Orz <b>are just</b> Orz. <p>- Orz</p>"
53
+ obj.orz.should == "<a rel=\"nofollow\">Orz are not *many bubbles* like *campers*. Orz <b>are just</b> Orz. <p>- Orz</p></a>"
54
+ end
55
+
56
+ it "sanitizes attributes with custom options and profiles" do
57
+ @klass.module_eval do
58
+ sanitize_attribute :orz, :elements => %w[p], :no_empties => %w[p]
59
+ sanitize_attribute :vux, :quotes_only
60
+ end
61
+ obj = @klass.new
62
+ obj.vux = "<blockquote>Our special today is <b>particle fragmentation!</b></blockquote> - VUX"
63
+ obj.vux.should == "<blockquote>Our special today is particle fragmentation!</blockquote> - VUX"
64
+ obj.orz = "\r\nOrz are not *many bubbles* like <p/>*campers*. <p></p>Orz <b>\r\nare just</b> Orz. <p>- Orz</p>"
65
+ obj.orz.should == "\nOrz are not *many bubbles* like *campers*. Orz \nare just Orz. <p>- Orz</p>"
66
+ end
67
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'sanitized_attributes'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanitized_attributes
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 0
10
- version: 1.1.0
9
+ - 1
10
+ version: 1.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matthew Boeh
@@ -59,8 +59,17 @@ extra_rdoc_files:
59
59
  - LICENSE
60
60
  - README.rdoc
61
61
  files:
62
+ - .document
62
63
  - LICENSE
63
64
  - README.rdoc
65
+ - Rakefile
66
+ - VERSION
67
+ - lib/sanitized_attributes.rb
68
+ - lib/sanitized_attributes/sanitized_attribute.rb
69
+ - sanitized_attributes.gemspec
70
+ - spec/sanitized_attributes_spec.rb
71
+ - spec/spec.opts
72
+ - spec/spec_helper.rb
64
73
  has_rdoc: true
65
74
  homepage: http://github.com/mboeh/sanitized_attributes
66
75
  licenses: []
@@ -95,5 +104,6 @@ rubygems_version: 1.3.7
95
104
  signing_key:
96
105
  specification_version: 3
97
106
  summary: HTML-sanitizing attribute accessors for Ruby and Rails
98
- test_files: []
99
-
107
+ test_files:
108
+ - spec/sanitized_attributes_spec.rb
109
+ - spec/spec_helper.rb