diff --git a/lib/notification_factory/renderer.rb b/lib/notification_factory/renderer.rb index 628bf2df4..86e60814f 100644 --- a/lib/notification_factory/renderer.rb +++ b/lib/notification_factory/renderer.rb @@ -39,14 +39,23 @@ examples how to use def d(key, escape = nil) # do validaton, ignore some methodes - if key =~ /(`|\.(|\s*)(save|destroy|delete|remove|drop|update\(|update_att|create\(|new|all|where|find))/i - return "#{key} (not allowed)" - end + return "\#{#{key} / not allowed}" if !data_key_valid?(key) - value = nil - object_methods = key.split('.') - object_name = object_methods.shift.to_sym - object_refs = @objects[object_name] + value = nil + object_methods = key.split('.') + object_name = object_methods.shift + + # if no object is given, just return + return "\#{no such object}" if object_name.empty? + object_refs = @objects[object_name] || @objects[object_name.to_sym] + + # if object is not in avalable objects, just return + return "\#{#{object_name} / no such object}" if !object_refs + + # if content of method is a complex datatype, just return + if object_methods.empty? && object_refs.class != String && object_refs.class != Float && object_refs.class != Fixnum + return "\#{#{key} / no such method}" + end object_methods_s = '' object_methods.each { |method_raw| @@ -57,12 +66,17 @@ examples how to use end object_methods_s += method - # if method exists - if !object_refs.respond_to?( method.to_sym ) + if object_methods_s == '' value = "\#{#{object_name}.#{object_methods_s} / no such method}" break end - object_refs = object_refs.send( method.to_sym ) + + # if method exists + if !object_refs.respond_to?(method.to_sym) + value = "\#{#{object_name}.#{object_methods_s} / no such method}" + break + end + object_refs = object_refs.send(method.to_sym) } placeholder = if !value object_refs @@ -121,4 +135,10 @@ examples how to use return key if escape.nil? && !@escape h key end + + def data_key_valid?(key) + return false if key =~ /`|\.(|\s*)(save|destroy|delete|remove|drop|update|create|new|all|where|find)/i + true + end + end diff --git a/test/unit/notification_factory_renderer_test.rb b/test/unit/notification_factory_renderer_test.rb index 992018a72..a6e5bb0e7 100644 --- a/test/unit/notification_factory_renderer_test.rb +++ b/test/unit/notification_factory_renderer_test.rb @@ -26,7 +26,6 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase test 'replace object attribute' do template = "<%= d 'ticket.title' %>" - result = described_class.new( { ticket: ticket, @@ -34,8 +33,48 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase 'en-us', template, ).render - assert_equal(CGI.escapeHTML(ticket.title), result) + + template = "<%= d 'ticket. title' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML(ticket.title), result) + + template = "<%= d 'ticket.\n title' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML(ticket.title), result) + + template = "<%= d 'ticket.\t title' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML(ticket.title), result) + + template = "<%= d 'ticket.\t\n title\t' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML(ticket.title), result) + end test 'config' do @@ -52,6 +91,20 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase ).render assert_equal(Setting.get(setting), result) + + setting1 = 'fqdn' + setting2 = 'product_name' + template = "some <%= c '#{setting1}' %> and <%= c '#{setting2}' %>" + + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + + assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result) end test 'translation' do @@ -67,6 +120,19 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase ).render assert_equal('neu', result) + + template = "some text <%= t 'new' %> and <%= t 'open' %>" + + result = described_class.new( + { + ticket: ticket, + }, + 'de-de', + template, + ).render + + assert_equal('some text neu and offen', result) + end test 'chained function calls' do @@ -83,4 +149,293 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase assert_equal('neu', result) end + + test 'not existing object and attribute' do + + template = "<%= d '' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{no such object}'), result) + + template = "<%= d 'notexsiting.notexsiting' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result) + + template = "<%= d 'ticket.notexsiting' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result) + + template = "<%= d 'ticket.' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket. / no such method}'), result) + + template = "<%= d 'ticket.title.notexsiting' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.title.notexsiting / no such method}'), result) + + template = "<%= d 'ticket.notexsiting.notexsiting' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result) + + template = "<%= d 'notexsiting' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result) + + template = "<%= d 'notexsiting.' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result) + + template = "<%= d 'string' %>" + result = described_class.new( + { + string: 'some string', + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('some string'), result) + + template = "<%= d 'fixum' %>" + result = described_class.new( + { + fixum: 123, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('123'), result) + + template = "<%= d 'float' %>" + result = described_class.new( + { + float: 123.99, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('123.99'), result) + + end + + test 'data key validation' do + + template = "<%= d 'ticket.title `echo 1`' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.title `echo 1` / not allowed}'), result) + + template = "<%= d 'ticket.destroy' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result) + + template = "<%= d 'ticket.save' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.save / not allowed}'), result) + + template = "<%= d 'ticket.update' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.update / not allowed}'), result) + + template = "<%= d 'ticket.delete' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.delete / not allowed}'), result) + + template = "<%= d 'ticket.remove' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.remove / not allowed}'), result) + + template = "<%= d 'ticket.drop' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.drop / not allowed}'), result) + + template = "<%= d 'ticket.create' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result) + + template = "<%= d 'ticket.new' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.new / not allowed}'), result) + + template = "<%= d 'ticket.update_att' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.update_att / not allowed}'), result) + + template = "<%= d 'ticket.all' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.all / not allowed}'), result) + + template = "<%= d 'ticket.find' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.find / not allowed}'), result) + + template = "<%= d 'ticket.where' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket.where / not allowed}'), result) + + template = "<%= d 'ticket. destroy' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML('#{ticket. destroy / not allowed}'), result) + + template = "<%= d 'ticket.\n destroy' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML("\#{ticket.\n destroy / not allowed}"), result) + + template = "<%= d 'ticket.\t destroy' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML("\#{ticket.\t destroy / not allowed}"), result) + + template = "<%= d 'ticket.\r destroy' %>" + result = described_class.new( + { + ticket: ticket, + }, + 'en-us', + template, + ).render + assert_equal(CGI.escapeHTML("\#{ticket.\r destroy / not allowed}"), result) + + end + end diff --git a/test/unit/notification_factory_template_test.rb b/test/unit/notification_factory_template_test.rb index f5bf4ebea..c8ad841f7 100644 --- a/test/unit/notification_factory_template_test.rb +++ b/test/unit/notification_factory_template_test.rb @@ -37,4 +37,23 @@ class NotificationFactoryTemplateTest < ActiveSupport::TestCase result = described_class.new(template_before).to_s assert_equal(template_after, result) end + + test 'empty tag' do + + template_before = '<%= d "#{}" %>' + template_after = '<%= d "#{}" %>' + + result = described_class.new(template_before).to_s + assert_equal(template_after, result) + end + + test 'empty tag with space' do + + template_before = '<%= d "#{ }" %>' + template_after = '<%= d "#{ }" %>' + + result = described_class.new(template_before).to_s + assert_equal(template_after, result) + end + end