shamu 0.0.8 → 0.0.9

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
2
  SHA1:
3
- metadata.gz: afa18618f6ec75e4163bbc06c2ac89d60b5729d6
4
- data.tar.gz: 0d3fc88e85d907868e82a98d8b877c326eacb4b9
3
+ metadata.gz: e6619b53b0ccf99f395e9ef5687a3eb9cd2fd661
4
+ data.tar.gz: 425daaaa1d330ffeb4ec885a59e9b0c63e5e1548
5
5
  SHA512:
6
- metadata.gz: 405509ea9020934875f4d74015c62b4733511b948c81caa617e67c94ffb3512dffd2264a8f8dcfcccd8277a2835eb142c6a84fb6edf090f6ed8dfdbd9aa8becf
7
- data.tar.gz: af3f05ab6ac199ae75d9716d430ff3270eab6fc156f74a709ad87be0d70d7042fbcc8865cb5f660cdc60d1494657854b76a8c7e6fc10a2c0039ab98402cd6f35
6
+ metadata.gz: 6f1cad8cd5b39cbfe4b186d4dfbb5b4c4f1c5e549dabb829cc801d708516fb15be7e16b8da1f9e1829203ae1d4b695ac6acb8f943767910f716591deb93fc659
7
+ data.tar.gz: 9cccb625e79e236cc7829cf86db880f0a0ac814847b305137c7e33d222e63ca507c0e373c243c9472d40159e503f65fb5169fb4c1d9e5bd684a6def1aac54662
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 2.3.1
data/Gemfile CHANGED
@@ -14,7 +14,7 @@ group :test do
14
14
 
15
15
  gem "sqlite3", "~> 1.3.11"
16
16
  gem "guard", "~> 2.12.8"
17
- gem "rubocop"
17
+ gem "rubocop", "~> 0.39.0"
18
18
  gem "guard-rubocop"
19
19
  gem "spring"
20
20
  gem "guard-rspec"
@@ -0,0 +1,218 @@
1
+ require "loofah"
2
+
3
+ module Shamu
4
+ module Attributes
5
+
6
+ # Adds an HTML sanitation option to attributes. When present, string values
7
+ # will be sanitized when the attribute is read.
8
+ #
9
+ # The raw unfiltered value is always available as `#{ attribute }_raw`.
10
+ module HtmlSanitation
11
+ extend ActiveSupport::Concern
12
+
13
+ # The standard HTML sanitation filter methods.
14
+ STANDARD_FILTER_METHODS = [
15
+ :none, # Don't allow any HTML
16
+ :simple, # Allow very simple HTML. See {#simple_html_sanitize}.
17
+ :body, # Allow subset useful for body copy. See
18
+ # {#body_html_sanitize}.
19
+ :safe, # Allow a broad subset of HTML tags and attributes. See
20
+ # {#safe_html_sanitize}.
21
+ :allow # Allow all HTML.
22
+ ].freeze
23
+
24
+ # Tags safe for simple text.
25
+ SIMPLE_TAGS = %w( B I STRONG EM ).freeze
26
+
27
+ # Tags safe for body text.
28
+ BODY_TAGS = %w( B BR CODE DIV EM H2 H3 H4 H5 H6 HR I LI OL P PRE SPAN STRONG U UL ).freeze
29
+
30
+ # Tags that are not safe.
31
+ UNSAFE_TAGS = %w( FORM SCRIPT IFRAME FRAME ).freeze
32
+
33
+ class_methods do
34
+ # (see Attributes.attribute)
35
+ # @param [Symbol,#call] html sanitation options. Acceptable values are
36
+ #
37
+ # - `:none` strip all HTML. The default.
38
+ # - `:simple` simple formatting suitable for most places. See
39
+ # {#simple_html_sanitize} for details.
40
+ # - `:body` basic formatting for 'body' text. See
41
+ # {#body_html_sanitize} for details.
42
+ # - `:allow` permit any HTML tag.
43
+ # - Any other symbol is assumed to be a method on the entity that will
44
+ # be called to filter the html.
45
+ # - `#call` anything that responds to `#call` that takes a single
46
+ # argument of the raw string and returns the sanitized HTML.
47
+ def attribute( name, *args, **options, &block )
48
+ super.tap do
49
+ define_html_sanitized_attribute_reader( name, options[ :html ] ) if options.key?( :html )
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def define_attribute_reader( name, as: nil, ** )
56
+ super
57
+
58
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
59
+ def #{ name }_raw # def attribute_raw
60
+ return @#{ name } if defined? @#{ name } # return @attribute if defined? @attribute
61
+ @#{ name } = fetch_#{ name } # @attribute = fetch_attribute
62
+ end # end
63
+ RUBY
64
+ end
65
+
66
+ def define_html_sanitized_attribute_reader( name, method )
67
+ method ||= :none
68
+
69
+ filter_method = resolve_html_filter_method( name, method )
70
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
71
+ def #{ name } # def attribute
72
+ return @#{ name }_html_sanitized if defined? @#{ name }_html_sanitized # return @attribute_html_sanitized if defined? @attribute_html_sanitized
73
+ @#{ name }_html_sanitized = #{ filter_method }( #{ name }_raw ) # @attribute_html_sanitized = simple_html_sanitized( attribute_raw )
74
+ end # end
75
+ RUBY
76
+ end
77
+
78
+ def resolve_html_filter_method( name, method )
79
+ if STANDARD_FILTER_METHODS.include?( method )
80
+ "#{ method }_html_sanitize"
81
+ elsif method.is_a?( Symbol )
82
+ method
83
+ else
84
+ filter_method = "custom_#{ name }_html_sanitize"
85
+ define_method filter_method, &method
86
+ filter_method
87
+ end
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ # @!visibility public
94
+ #
95
+ # Remove all HTML from the value.
96
+ #
97
+ # @param [String] value to sanitize.
98
+ # @return [String] the sanitized value.
99
+ def none_html_sanitize( value )
100
+ return value unless value.is_a?( String )
101
+
102
+ Loofah.fragment( value ).scrub!( NoneScrubber.new ).to_s
103
+ end
104
+
105
+ # @!visibility public
106
+ #
107
+ # Remove all but the simplest html tags <B>, <I>, <STRONG>, <EM>.
108
+ #
109
+ # @param [String] value to sanitize.
110
+ # @return [String] the sanitized value.
111
+ def simple_html_sanitize( value )
112
+ return value unless value.is_a?( String )
113
+
114
+ Loofah.fragment( value ).scrub!( SimpleScrubber.new ).to_s
115
+ end
116
+
117
+ # @!visibility public
118
+ #
119
+ # Remove all but a limited subset of common tags useful for body copy
120
+ # text. See {BODY_TAGS}.
121
+ #
122
+ # @param [String] value to sanitize.
123
+ # @return [String] the sanitized value.
124
+ def body_html_sanitize( value )
125
+ return value unless value.is_a?( String )
126
+
127
+ Loofah.fragment( value ).scrub!( BodyScrubber.new ).to_s
128
+ end
129
+
130
+ # @!visibility public
131
+ #
132
+ # Remove all HTML from the value.
133
+ #
134
+ # @param [String] value to sanitize.
135
+ # @return [String] the sanitized value.
136
+ def safe_html_sanitize( value )
137
+ return value unless value.is_a?( String )
138
+
139
+ Loofah.fragment( value )
140
+ .scrub!( SafeScrubber.new )
141
+ .scrub!( :no_follow )
142
+ .to_s
143
+ end
144
+
145
+ # @!visibility public
146
+ #
147
+ # Does not perform any sanitization of the value.
148
+ #
149
+ # @param [String] value to sanitize.
150
+ # @return [String] the sanitized value.
151
+ def allow_html_sanitize( value )
152
+ return value unless value.is_a?( String )
153
+
154
+ Loofah.fragment( value ).scrub!( :no_follow ).to_s
155
+ end
156
+
157
+ class NoneScrubber < Loofah::Scrubber
158
+ def initialize
159
+ @direction = :bottom_up
160
+ end
161
+
162
+ def scrub( node )
163
+ if node.text?
164
+ Loofah::Scrubber::CONTINUE
165
+ else
166
+ node.before node.children
167
+ node.remove
168
+ end
169
+ end
170
+ end
171
+
172
+ class PermitScrubber < Loofah::Scrubber
173
+ def initialize
174
+ @direction = :bottom_up
175
+ end
176
+
177
+ def scrub( node )
178
+ if node.type == Nokogiri::XML::Node::ELEMENT_NODE
179
+ if allowed_element?( node.name )
180
+ Loofah::HTML5::Scrub.scrub_attributes node
181
+ else
182
+ node.before node.children unless unsafe_element?( node.name )
183
+ node.remove
184
+ end
185
+ end
186
+
187
+ Loofah::Scrubber::CONTINUE
188
+ end
189
+
190
+ def allowed_element?( name )
191
+ end
192
+
193
+ def unsafe_element?( name )
194
+ UNSAFE_TAGS.include?( name.upcase )
195
+ end
196
+ end
197
+
198
+ class SimpleScrubber < PermitScrubber
199
+ def allowed_element?( name )
200
+ SIMPLE_TAGS.include?( name.upcase )
201
+ end
202
+ end
203
+
204
+ class BodyScrubber < PermitScrubber
205
+ def allowed_element?( name )
206
+ BODY_TAGS.include?( name.upcase )
207
+ end
208
+ end
209
+
210
+ class SafeScrubber < PermitScrubber
211
+ def allowed_element?( name )
212
+ !unsafe_element?( name )
213
+ end
214
+ end
215
+
216
+ end
217
+ end
218
+ end
@@ -12,6 +12,7 @@ module Shamu
12
12
  # - {Attributes::FluidAssignment}
13
13
  # - {Attributes::Validation}
14
14
  # - {Attributes::Equality}
15
+ # - {Attributes::HtmlSanitation}
15
16
  #
16
17
  # @example
17
18
  #
@@ -27,6 +28,7 @@ module Shamu
27
28
  require "shamu/attributes/fluid_assignment"
28
29
  require "shamu/attributes/validation"
29
30
  require "shamu/attributes/equality"
31
+ require "shamu/attributes/html_sanitation"
30
32
 
31
33
  def initialize( *attributes )
32
34
  assign_attributes( attributes.last )
@@ -0,0 +1,24 @@
1
+ module Shamu
2
+ module Entities
3
+
4
+ # Forces all string attributes to be html sanitized.
5
+ module HtmlSanitation
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include Shamu::Attributes::HtmlSanitation
10
+ extend AttributeMethod
11
+ end
12
+
13
+ module AttributeMethod
14
+ # (see Attributes::HtmlSanitation.attribute)
15
+ def attribute( name, *args, **options, &block )
16
+ options[:html] ||= :none
17
+
18
+ super name, *args, **options, &block
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -7,5 +7,6 @@ module Shamu
7
7
  require "shamu/entities/list_scope"
8
8
  require "shamu/entities/identity_cache"
9
9
  require "shamu/entities/entity_path"
10
+ require "shamu/entities/html_sanitation"
10
11
  end
11
12
  end
@@ -17,7 +17,7 @@ en:
17
17
  access_denied: You are not permitted to do that.
18
18
  incomplete_setup: Security has been enabled but is not yet configured.
19
19
  no_actiev_record_policy_checks: Don't check for policy on ActiveRecord resources. Check their projected Entity instead.
20
-
20
+ no_policy_impersonation: Impersonation is not supported by this principal.
21
21
  events:
22
22
  errors:
23
23
  unknown_runner: Unknown runner. Each process should offer a consitent but unique runner_id.
@@ -0,0 +1,19 @@
1
+ module Shamu
2
+ module Security
3
+
4
+ # ...
5
+ class DelegatePrincipal < Principal
6
+
7
+ # (see Principal#impersonate)
8
+ def impersonate( user_id )
9
+ fail NoPolicyImpersonationError
10
+ end
11
+
12
+ # (see Principal#service_delegate?)
13
+ def service_delegate?
14
+ true
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -61,5 +61,11 @@ module Shamu
61
61
  end
62
62
  end
63
63
 
64
+ # Principal does not support impersonation.
65
+ class NoPolicyImpersonationError < Error
66
+ def initialize( message = :no_policy_impersonation )
67
+ super
68
+ end
69
+ end
64
70
  end
65
71
  end
@@ -67,6 +67,12 @@ module Shamu
67
67
  self.class.new( user_id: user_id, parent_principal: self, remote_ip: remote_ip, elevated: elevated )
68
68
  end
69
69
 
70
+ # @return [Boolean] true if the principal was offered by one service to
71
+ # another and requesting that the downstream service delegate security
72
+ # checks to the calling service.
73
+ def service_delegate?
74
+ end
75
+
70
76
  end
71
77
  end
72
78
  end
@@ -76,6 +76,7 @@ module Shamu
76
76
  # @return [Boolean] true if the service has been asked to delegate
77
77
  # policy checks to the upstream service and
78
78
  def service_policy_delegation?
79
+ security_principal.service_delegate?
79
80
  end
80
81
 
81
82
  end
@@ -70,10 +70,34 @@ module Shamu
70
70
  # end
71
71
  # end
72
72
  def with_request( params, request_class, &block )
73
- request = request_class.coerce( params )
74
- sources = yield( request ) if request.valid?
73
+ with_partial_request params, request_class do |request|
74
+ next unless request.valid?
75
75
 
76
- result request, *sources
76
+ yield request
77
+ end
78
+ end
79
+
80
+ # @!visibility public
81
+ #
82
+ # Behaves the same as {#with_request} but always executes the block even
83
+ # if the params are not yet valid. Allows the block to populate the
84
+ # request with missing information before validating.
85
+ #
86
+ # @param (see #with_request)
87
+ # @return (see #with_request)
88
+ # @see #with_request
89
+ def with_partial_request( params, request_class, &block )
90
+ request = request_class.coerce( params )
91
+ # Make sure the request captures errors even if the block doesn't
92
+ # check
93
+ request.valid?
94
+ sources = yield( request )
95
+
96
+ if sources.is_a?( Result )
97
+ sources
98
+ else
99
+ result request, *Array.wrap( sources )
100
+ end
77
101
  end
78
102
 
79
103
  # Static methods added to {RequestSupport}
@@ -116,9 +116,9 @@ module Shamu
116
116
  # record.
117
117
  # @param [Symbol,#call(record)] match the attribute or a Proc used to
118
118
  # extract the id used to compare records.
119
- # @param [Symbol,#call] coerce a method that can be used to coerce id values
120
- # to the same type (eg :to_i). If not set, automatically uses :to_i
121
- # if match is an 'id' attribute.
119
+ # @param [Symbol,#call] coerce a method that can be used to coerce id
120
+ # values to the same type (eg :to_i). If not set, automatically uses
121
+ # :to_model_id if match is an 'id' attribute.
122
122
  # @yield (see #entity_list)
123
123
  # @yieldparam (see #entity_list)
124
124
  # @yieldreturn (see #entity_list)
@@ -153,7 +153,7 @@ module Shamu
153
153
  def entity_lookup_list( records, ids, null_class, match: :id, coerce: :not_set, &transformer )
154
154
  matcher = entity_lookup_list_matcher( match )
155
155
  coerce = coerce_method( coerce, match )
156
- ids = ids.map( &coerce ) if coerce
156
+ ids = ids.map( &coerce ) if coerce
157
157
 
158
158
  list = entity_list records, &transformer
159
159
  matched = ids.map do |id|
@@ -175,7 +175,7 @@ module Shamu
175
175
 
176
176
  def coerce_method( coerce, match )
177
177
  return coerce unless coerce == :not_set
178
- :to_i if match.is_a?( Symbol ) && match =~ /(^|_)id$/
178
+ :to_model_id if match.is_a?( Symbol ) && match =~ /(^|_)ids?$/
179
179
  end
180
180
 
181
181
  # @!visibility public
@@ -297,6 +297,8 @@ module Shamu
297
297
  # end
298
298
  # end
299
299
  def cached_lookup( ids, match: :id, coerce: :not_set, entity: nil, &lookup )
300
+ coerce = coerce_method( coerce, match )
301
+ ids = ids.map( &coerce ) if coerce
300
302
  cache = cache_for( key: match, coerce: coerce, entity: entity )
301
303
  missing_ids = cache.uncached_keys( ids )
302
304
 
data/lib/shamu/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Shamu
3
3
  # The primary version number
4
- VERSION_NUMBER = "0.0.8".freeze
4
+ VERSION_NUMBER = "0.0.9".freeze
5
5
 
6
6
  # Version suffix such as 'beta' or 'alpha'
7
7
  VERSION_SUFFIX = "".freeze
data/shamu.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "rack", "~> 1"
28
28
  spec.add_dependency "listen", "~> 3"
29
29
  spec.add_dependency "crc32", "~> 1"
30
-
30
+ spec.add_dependency "loofah", "~> 2"
31
31
 
32
32
  spec.add_development_dependency "bundler", "~> 1.6"
33
33
  spec.add_development_dependency "i18n", "~> 0.7"
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ module HtmlSanitationSpec
4
+ class Attrs
5
+ include Shamu::Attributes
6
+ include Shamu::Attributes::HtmlSanitation
7
+
8
+ attribute :bio, html: :body
9
+ attribute :name, html: :simple
10
+ attribute :email, html: :none
11
+ end
12
+ end
13
+
14
+ describe Shamu::Attributes::HtmlSanitation do
15
+ context "simple sanitation" do
16
+ let( :entity ) { HtmlSanitationSpec::Attrs.new( name: "<b>Bold</b> <p>Name</p>" ) }
17
+
18
+ it "removes non-simple HTML by default" do
19
+ expect( entity.name ).to eq "<b>Bold</b> Name"
20
+ end
21
+
22
+ it "exposes original value available via raw attribute" do
23
+ expect( entity.name_raw ).to eq "<b>Bold</b> <p>Name</p>"
24
+ end
25
+ end
26
+
27
+ context "none sanitation" do
28
+ let( :entity ) { HtmlSanitationSpec::Attrs.new( email: "<b>Bold</b> <p>Name</p>" ) }
29
+
30
+ it "removes all HTML by default" do
31
+ expect( entity.email ).to eq "Bold Name"
32
+ end
33
+ end
34
+
35
+ context "body sanitation" do
36
+ let( :entity ) { HtmlSanitationSpec::Attrs.new( bio: "<script>alert('Hacked')</script><h2>Title</h2>" ) }
37
+
38
+ it "only removes illegal HTML" do
39
+ expect( entity.bio ).to eq "<h2>Title</h2>"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ module HtmlSanitationSpec
4
+ class Entity < Shamu::Entities::Entity
5
+ include Shamu::Entities::HtmlSanitation
6
+
7
+ attribute :name
8
+ end
9
+ end
10
+
11
+ describe Shamu::Attributes::HtmlSanitation do
12
+ let( :entity ) { HtmlSanitationSpec::Entity.new( name: "<b>Bold</b> <p>Name</p>" ) }
13
+
14
+ it "removes all HTML by default" do
15
+ expect( entity.name ).to eq "Bold Name"
16
+ end
17
+ end
@@ -15,6 +15,12 @@ module RequestSupportSpec
15
15
  end
16
16
  end
17
17
 
18
+ def partial_process( params )
19
+ with_partial_request( params, Request::Change ) do |_|
20
+ request_hook
21
+ end
22
+ end
23
+
18
24
  def request_hook
19
25
  end
20
26
 
@@ -120,6 +126,24 @@ describe Shamu::Services::RequestSupport do
120
126
  end
121
127
  end
122
128
 
129
+ describe "#with_partial_request" do
130
+ let( :request_params ) { { level: 1, amount: 5 } }
131
+ let( :service ) { scorpion.new RequestSupportSpec::Service }
132
+
133
+ it "yields even if params are invalid" do
134
+ request_params.delete :amount
135
+ expect( service ).to receive( :request_hook )
136
+ service.partial_process( request_params )
137
+ end
138
+
139
+ it "reports errors even if block doesn't check" do
140
+ request_params.delete :amount
141
+ result = service.partial_process( request_params )
142
+
143
+ expect( result.request.errors ).not_to be_empty
144
+ end
145
+ end
146
+
123
147
  describe "#request_for" do
124
148
  it "returns request" do
125
149
  request = service.request_for( :create )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shamu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Alexander
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-20 00:00:00.000000000 Z
11
+ date: 2016-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: loofah
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: bundler
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -213,6 +227,7 @@ files:
213
227
  - lib/shamu/attributes/assignment.rb
214
228
  - lib/shamu/attributes/equality.rb
215
229
  - lib/shamu/attributes/fluid_assignment.rb
230
+ - lib/shamu/attributes/html_sanitation.rb
216
231
  - lib/shamu/attributes/validation.rb
217
232
  - lib/shamu/auditing.rb
218
233
  - lib/shamu/auditing/README.md
@@ -228,6 +243,7 @@ files:
228
243
  - lib/shamu/entities/active_record_soft_destroy.rb
229
244
  - lib/shamu/entities/entity.rb
230
245
  - lib/shamu/entities/entity_path.rb
246
+ - lib/shamu/entities/html_sanitation.rb
231
247
  - lib/shamu/entities/identity_cache.rb
232
248
  - lib/shamu/entities/list.rb
233
249
  - lib/shamu/entities/list_scope.rb
@@ -311,6 +327,7 @@ files:
311
327
  - lib/shamu/security.rb
312
328
  - lib/shamu/security/README.md
313
329
  - lib/shamu/security/active_record_policy.rb
330
+ - lib/shamu/security/delegate_principal.rb
314
331
  - lib/shamu/security/error.rb
315
332
  - lib/shamu/security/hashed_value.rb
316
333
  - lib/shamu/security/no_policy.rb
@@ -350,6 +367,7 @@ files:
350
367
  - spec/lib/shamu/attributes/assignment_spec.rb
351
368
  - spec/lib/shamu/attributes/equality_spec.rb
352
369
  - spec/lib/shamu/attributes/fluid_assignment_spec.rb
370
+ - spec/lib/shamu/attributes/html_sanitation_spec.rb
353
371
  - spec/lib/shamu/attributes/validation_spec.rb
354
372
  - spec/lib/shamu/attributes_spec.rb
355
373
  - spec/lib/shamu/auditing/logging_auditing_service_spec.rb
@@ -358,6 +376,7 @@ files:
358
376
  - spec/lib/shamu/entities/active_record_spec.rb
359
377
  - spec/lib/shamu/entities/entity_path_spec.rb
360
378
  - spec/lib/shamu/entities/entity_spec.rb
379
+ - spec/lib/shamu/entities/html_sanitation_spec.rb
361
380
  - spec/lib/shamu/entities/identity_cache_spec.rb
362
381
  - spec/lib/shamu/entities/list_scope/dates_spec.rb
363
382
  - spec/lib/shamu/entities/list_scope/paging_spec.rb
@@ -463,6 +482,7 @@ test_files:
463
482
  - spec/lib/shamu/attributes/assignment_spec.rb
464
483
  - spec/lib/shamu/attributes/equality_spec.rb
465
484
  - spec/lib/shamu/attributes/fluid_assignment_spec.rb
485
+ - spec/lib/shamu/attributes/html_sanitation_spec.rb
466
486
  - spec/lib/shamu/attributes/validation_spec.rb
467
487
  - spec/lib/shamu/attributes_spec.rb
468
488
  - spec/lib/shamu/auditing/logging_auditing_service_spec.rb
@@ -471,6 +491,7 @@ test_files:
471
491
  - spec/lib/shamu/entities/active_record_spec.rb
472
492
  - spec/lib/shamu/entities/entity_path_spec.rb
473
493
  - spec/lib/shamu/entities/entity_spec.rb
494
+ - spec/lib/shamu/entities/html_sanitation_spec.rb
474
495
  - spec/lib/shamu/entities/identity_cache_spec.rb
475
496
  - spec/lib/shamu/entities/list_scope/dates_spec.rb
476
497
  - spec/lib/shamu/entities/list_scope/paging_spec.rb