From 6eeadfdee4d388fe4dde4c603e95c4b773b64f43 Mon Sep 17 00:00:00 2001 From: Josh Adams Date: Mon, 29 Dec 2008 22:41:24 -0600 Subject: [PATCH 1/6] wrapped the fckeditor in a jquery document.ready, so as to avoid the frustrating fckeditor not defined js bug --- app/helpers/content_section_helper.rb | 7 +++++-- .../app/views/admin/content_sections/_edit.html.erb | 4 +++- vendor/plugins/fckeditor/lib/fckeditor.rb | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/helpers/content_section_helper.rb b/app/helpers/content_section_helper.rb index c3ccfc0..dd1396e 100644 --- a/app/helpers/content_section_helper.rb +++ b/app/helpers/content_section_helper.rb @@ -5,10 +5,13 @@ def rollback_dropdown content_section, options={} the_options = options_for_select(versions.reverse) the_id = content_section.id the_select = content_tag("select", the_options, :onchange => "redirect_to_rollback_link(#{the_id}, this.options[this.selectedIndex].value)") - content_tag("div", the_select, :id => options[:id]) + dropdown = content_tag("div", the_select, :id => options[:id]) + form_row "Revision", dropdown end def versions_array content_section - (1..content_section.versions.length).to_a + content_section.versions.map do |version| + ["Version ##{version.version} - " + version.created_at.to_s, version.version] + end end end diff --git a/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb b/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb index 356f38f..ecb64e6 100644 --- a/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb +++ b/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb @@ -1,7 +1,9 @@ <% @content_section = plugin_module if local_assigns.include?(:plugin_module) %> <% remote_form_for :content_section, @content_section, :url => admin_content_section_path(@content_section), :html => { :method => :put }, :before => fckeditor_before_js(:content_section, :contents), :success => "update_dropdown_for(#{@content_section.id})" do |f| -%> <%= fckeditor_textarea(:content_section, :contents, :toolbarSet => 'Simple', :width => '100%', :height => '400px', :ajax => true) -%>
- <%= rollback_dropdown(@content_section) %> + + <%= rollback_dropdown(@content_section) %> +
<%= submit_tag("Update Content Section", :id => 'close_modal_and_flash') -%> <% end -%>
diff --git a/vendor/plugins/fckeditor/lib/fckeditor.rb b/vendor/plugins/fckeditor/lib/fckeditor.rb index 59bd106..f4c571c 100644 --- a/vendor/plugins/fckeditor/lib/fckeditor.rb +++ b/vendor/plugins/fckeditor/lib/fckeditor.rb @@ -44,10 +44,10 @@ def fckeditor_textarea_tag(name, value='', options={}) js_path = "#{ActionController::Base.relative_url_root}/javascripts" base_path = "#{js_path}/fckeditor/" return inputs << - javascript_tag("var oFCKeditor = new FCKeditor('#{options[:id]}', '#{width}', '#{height}', '#{toolbarSet}');\n" << + javascript_tag("jQuery(document).ready(function(){ var oFCKeditor = new FCKeditor('#{options[:id]}', '#{width}', '#{height}', '#{toolbarSet}');\n" << "oFCKeditor.BasePath = \"#{base_path}\"\n" << "oFCKeditor.Config['CustomConfigurationsPath'] = '#{js_path}/fckcustom.js';\n" << - "oFCKeditor.ReplaceTextarea();\n") + "oFCKeditor.ReplaceTextarea(); });\n") end From 455eb8bebb2fc47d2d011db0cd655757a0f3079e Mon Sep 17 00:00:00 2001 From: Josh Adams Date: Tue, 30 Dec 2008 19:46:52 -0600 Subject: [PATCH 2/6] fixed bug I introduced in a recent commit on the content section plugin that caused the revisioning widget to look stupid after you updated. --- app/helpers/content_section_helper.rb | 2 +- public/proxy.html | 10 ++++++++++ .../app/views/admin/content_sections/_edit.html.erb | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 public/proxy.html diff --git a/app/helpers/content_section_helper.rb b/app/helpers/content_section_helper.rb index dd1396e..fa36436 100644 --- a/app/helpers/content_section_helper.rb +++ b/app/helpers/content_section_helper.rb @@ -6,7 +6,7 @@ def rollback_dropdown content_section, options={} the_id = content_section.id the_select = content_tag("select", the_options, :onchange => "redirect_to_rollback_link(#{the_id}, this.options[this.selectedIndex].value)") dropdown = content_tag("div", the_select, :id => options[:id]) - form_row "Revision", dropdown + dropdown end def versions_array content_section diff --git a/public/proxy.html b/public/proxy.html new file mode 100644 index 0000000..74b58bf --- /dev/null +++ b/public/proxy.html @@ -0,0 +1,10 @@ + + + + + +UWA Container Proxy + + + + diff --git a/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb b/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb index ecb64e6..993726d 100644 --- a/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb +++ b/vendor/plugins/ansuz_content_section/app/views/admin/content_sections/_edit.html.erb @@ -2,7 +2,7 @@ <% remote_form_for :content_section, @content_section, :url => admin_content_section_path(@content_section), :html => { :method => :put }, :before => fckeditor_before_js(:content_section, :contents), :success => "update_dropdown_for(#{@content_section.id})" do |f| -%> <%= fckeditor_textarea(:content_section, :contents, :toolbarSet => 'Simple', :width => '100%', :height => '400px', :ajax => true) -%>
- <%= rollback_dropdown(@content_section) %> + <%= form_row "Revision", rollback_dropdown(@content_section) %>
<%= submit_tag("Update Content Section", :id => 'close_modal_and_flash') -%> <% end -%> From 141927c77853b38e7e4e1387a443597fb65eb4d2 Mon Sep 17 00:00:00 2001 From: Josh Adams Date: Tue, 30 Dec 2008 20:42:21 -0600 Subject: [PATCH 3/6] changed FCKEditor to use br mode by default. It kept wrapping script tags in p, etc. --- public/javascripts/fckcustom.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/javascripts/fckcustom.js b/public/javascripts/fckcustom.js index d18cf8d..9770095 100644 --- a/public/javascripts/fckcustom.js +++ b/public/javascripts/fckcustom.js @@ -31,3 +31,5 @@ FCKConfig.ToolbarSets["Simple"] = [ ['TextColor','BGColor'], ['-','About'] ] ; + +FCKConfig.EnterMode = 'br'; From 840f5ebcc8ff59fb929ca1ddf62e6d27540539fd Mon Sep 17 00:00:00 2001 From: Josh Adams Date: Wed, 31 Dec 2008 17:25:44 -0600 Subject: [PATCH 4/6] added basic database dumper plugin --- config/routes.rb | 1 + lib/tasks/backup.rake | 47 +++++++++++++++++++ .../admin/database_dumpers_controller.rb | 21 +++++++++ .../admin/database_dumpers/show.html.erb | 8 ++++ vendor/plugins/ansuz_database_dumper/init.rb | 1 + .../plugins/ansuz_database_dumper/routes.rb | 3 ++ 6 files changed, 81 insertions(+) create mode 100644 lib/tasks/backup.rake create mode 100644 vendor/plugins/ansuz_database_dumper/app/controllers/admin/database_dumpers_controller.rb create mode 100644 vendor/plugins/ansuz_database_dumper/app/views/admin/database_dumpers/show.html.erb create mode 100644 vendor/plugins/ansuz_database_dumper/init.rb create mode 100644 vendor/plugins/ansuz_database_dumper/routes.rb diff --git a/config/routes.rb b/config/routes.rb index 233beb1..6ed7dee 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,7 @@ map.from_plugin :ansuz_feed_reader map.from_plugin :ansuz_jskit map.from_plugin :ansuz_twitterati + map.from_plugin :ansuz_database_dumper map.resources :tags map.resources :users diff --git a/lib/tasks/backup.rake b/lib/tasks/backup.rake new file mode 100644 index 0000000..3ed36c7 --- /dev/null +++ b/lib/tasks/backup.rake @@ -0,0 +1,47 @@ +namespace :db do + namespace :backup do + + def interesting_tables + ActiveRecord::Base.connection.tables.sort.reject! do |tbl| + ['schema_info', 'sessions', 'public_exceptions'].include?(tbl) + end + end + + desc "Dump entire db." + task :write => :environment do + + dir = RAILS_ROOT + '/db/backup' + FileUtils.mkdir_p(dir) + FileUtils.chdir(dir) + + interesting_tables.each do |tbl| + + klass = tbl.classify.constantize + puts "Writing #{tbl}..." + File.open("#{tbl}.yml", 'w+') { |f| YAML.dump klass.find(:all).collect(&:attributes), f } + end + + end + + task :read => [:environment, 'db:schema:load'] do + + dir = RAILS_ROOT + '/db/backup' + FileUtils.mkdir_p(dir) + FileUtils.chdir(dir) + + interesting_tables.each do |tbl| + + klass = tbl.classify.constantize + ActiveRecord::Base.transaction do + + puts "Loading #{tbl}..." + YAML.load_file("#{tbl}.yml").each do |fixture| + ActiveRecord::Base.connection.execute "INSERT INTO #{tbl} (#{fixture.keys.join(",")}) VALUES (#{fixture.values.collect { |value| ActiveRecord::Base.connection.quote(value) }.join(",")})", 'Fixture Insert' + end + end + end + + end + + end +end diff --git a/vendor/plugins/ansuz_database_dumper/app/controllers/admin/database_dumpers_controller.rb b/vendor/plugins/ansuz_database_dumper/app/controllers/admin/database_dumpers_controller.rb new file mode 100644 index 0000000..4b77d7f --- /dev/null +++ b/vendor/plugins/ansuz_database_dumper/app/controllers/admin/database_dumpers_controller.rb @@ -0,0 +1,21 @@ +class Admin::DatabaseDumpersController < Admin::BaseController + def show + end + + def mysql_dump + backup_path = File.join(RAILS_ROOT, "tmp", Time.now.to_f.to_s) + config = Rails::Configuration.new.database_configuration[RAILS_ENV] + options = [] + options << "-u#{config["username"]}" + options << "-p#{config["password"]}" unless config["password"].blank? + options << "#{config["database"]}" + command = "mysqldump #{options.join(" ")} > #{backup_path}" + logger.info command + begin + `#{command}` + render :file => backup_path + ensure + File.delete backup_path + end + end +end diff --git a/vendor/plugins/ansuz_database_dumper/app/views/admin/database_dumpers/show.html.erb b/vendor/plugins/ansuz_database_dumper/app/views/admin/database_dumpers/show.html.erb new file mode 100644 index 0000000..8a930c1 --- /dev/null +++ b/vendor/plugins/ansuz_database_dumper/app/views/admin/database_dumpers/show.html.erb @@ -0,0 +1,8 @@ +<%= title "Import / Export your data" %> +<% content_for :sidebar do %> +
+ At present, only mysql is supported. We should make that not true. +
+<% end %> + +<%= link_to "Download a dump of your database", mysql_dump_admin_database_dumper_path %> diff --git a/vendor/plugins/ansuz_database_dumper/init.rb b/vendor/plugins/ansuz_database_dumper/init.rb new file mode 100644 index 0000000..8988716 --- /dev/null +++ b/vendor/plugins/ansuz_database_dumper/init.rb @@ -0,0 +1 @@ +Ansuz::PluginManagerInstance.register_admin_menu_entry('Ansuz', 'Database Import/Export', '/admin/database_dumper') diff --git a/vendor/plugins/ansuz_database_dumper/routes.rb b/vendor/plugins/ansuz_database_dumper/routes.rb new file mode 100644 index 0000000..f954b2b --- /dev/null +++ b/vendor/plugins/ansuz_database_dumper/routes.rb @@ -0,0 +1,3 @@ +namespace :admin do |admin| + admin.resource :database_dumper, :collection => [:mysql_dump] +end From a070f7b13068450d67e455720e231ffd3946e3fe Mon Sep 17 00:00:00 2001 From: Josh Adams Date: Fri, 2 Jan 2009 15:15:23 -0600 Subject: [PATCH 5/6] updated admin to include link to google group --- VERSION | 2 +- app/views/layouts/admin.html.erb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 17e51c3..d917d3e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.1.2 diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index eec27f0..eb6d4a7 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb @@ -39,6 +39,7 @@
  • <%= link_to("Visit site", "/") %>
  • +
  • <%= link_to("Google Group", "http://groups.google.com/group/ansuz-cms/topics") %>
  • <%= link_to "File a Bug Report", "http://ansuz.lighthouseapp.com/projects/15780-ansuz/tickets/new" %>
  • <%= link_to "Make a Feature Request", "http://ansuzcms.crowdsound.com/suggestions/new" %>
From f791e320084c18bc1f66291dd7da66618e68758f Mon Sep 17 00:00:00 2001 From: Josh Adams Date: Fri, 2 Jan 2009 19:32:32 -0600 Subject: [PATCH 6/6] added custom css to site settings --- app/models/site_setting.rb | 2 + app/views/admin/site_settings/edit.html.erb | 1 + app/views/admin/site_settings/show.html.erb | 1 + app/views/shared/_stylesheets.html.erb | 3 + ...3012646_add_custom_css_to_site_settings.rb | 9 ++ db/schema.rb | 4 +- lib/site_settings_helper.rb | 1 + vendor/plugins/css_file_sanitize/README | 0 .../css_file_sanitize/lib/css_sanitize.rb | 26 ++++ .../test/css_sanitize_test.rb | 115 ++++++++++++++++++ 10 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20090103012646_add_custom_css_to_site_settings.rb create mode 100644 vendor/plugins/css_file_sanitize/README create mode 100644 vendor/plugins/css_file_sanitize/lib/css_sanitize.rb create mode 100644 vendor/plugins/css_file_sanitize/test/css_sanitize_test.rb diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 6972393..f936d07 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -1,4 +1,6 @@ class SiteSetting < ActiveRecord::Base + include CssSanitize + def get_theme_setting theme_setting = self.send(:user_theme_name) theme_setting.blank? ? 'default' : theme_setting diff --git a/app/views/admin/site_settings/edit.html.erb b/app/views/admin/site_settings/edit.html.erb index b0d721b..b60fc28 100644 --- a/app/views/admin/site_settings/edit.html.erb +++ b/app/views/admin/site_settings/edit.html.erb @@ -11,6 +11,7 @@ <%= form_row "Site Title", f.text_field(:site_title) %> <%= form_row "Show in-line edit links?", f.check_box(:show_inline_edit_links) %> + <%= form_row "Custom CSS", f.text_area(:custom_css) %>

diff --git a/app/views/admin/site_settings/show.html.erb b/app/views/admin/site_settings/show.html.erb index ab2b5d1..5958c6e 100644 --- a/app/views/admin/site_settings/show.html.erb +++ b/app/views/admin/site_settings/show.html.erb @@ -7,6 +7,7 @@ <%= form_row "Site Title", @settings.site_title -%> <%= form_row "Show in-line edit links?", @settings.show_inline_edit_links? ? 'Yes' : 'No' -%> + <%= form_row "Custom CSS", content_tag("pre", get_setting(:custom_css)) -%> <%= form_row "User Theme", "#{@settings.get_theme_setting}" + "
" + @settings.get_theme_setting + " " + link_to("(change)", choose_theme_admin_site_settings_path) -%>
diff --git a/app/views/shared/_stylesheets.html.erb b/app/views/shared/_stylesheets.html.erb index 04f01c2..14daed2 100644 --- a/app/views/shared/_stylesheets.html.erb +++ b/app/views/shared/_stylesheets.html.erb @@ -6,3 +6,6 @@ <%= stylesheet_link_tag 'jquery.lightbox-0.5.css' %> <%= stylesheet_link_tag 'jquery.popeye.css' %> <%= stylesheet_link_tag 'galimg' %> + diff --git a/db/migrate/20090103012646_add_custom_css_to_site_settings.rb b/db/migrate/20090103012646_add_custom_css_to_site_settings.rb new file mode 100644 index 0000000..dd6697d --- /dev/null +++ b/db/migrate/20090103012646_add_custom_css_to_site_settings.rb @@ -0,0 +1,9 @@ +class AddCustomCssToSiteSettings < ActiveRecord::Migration + def self.up + add_column :site_settings, :custom_css, :text + end + + def self.down + remove_column :site_settings, :custom_css + end +end diff --git a/db/schema.rb b/db/schema.rb index b10ab24..738592d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20081226000031) do +ActiveRecord::Schema.define(:version => 20090103012646) do create_table "ansuz_themes", :force => true do |t| t.string "name" @@ -34,6 +34,7 @@ t.integer "created_by" t.datetime "created_at" t.datetime "updated_at" + t.string "url" end create_table "content_section_versions", :force => true do |t| @@ -256,6 +257,7 @@ t.datetime "updated_at" t.string "site_title" t.boolean "show_inline_edit_links", :default => false + t.text "custom_css" end create_table "taggings", :force => true do |t| diff --git a/lib/site_settings_helper.rb b/lib/site_settings_helper.rb index 8b4b032..78232e2 100644 --- a/lib/site_settings_helper.rb +++ b/lib/site_settings_helper.rb @@ -7,6 +7,7 @@ def get_theme_setting settings.get_theme_setting end + protected def settings SiteSetting.find_or_create_by_name(:default) end diff --git a/vendor/plugins/css_file_sanitize/README b/vendor/plugins/css_file_sanitize/README new file mode 100644 index 0000000..e69de29 diff --git a/vendor/plugins/css_file_sanitize/lib/css_sanitize.rb b/vendor/plugins/css_file_sanitize/lib/css_sanitize.rb new file mode 100644 index 0000000..833e642 --- /dev/null +++ b/vendor/plugins/css_file_sanitize/lib/css_sanitize.rb @@ -0,0 +1,26 @@ +# Include this module into your ActiveRecord model. +module CssSanitize + + def custom_css=(text) + # Mostly stolen from http://code.sixapart.com/svn/CSS-Cleaner/trunk/lib/CSS/Cleaner.pm + text = "Error: invalid/disallowed characters in CSS" if text =~ /(\w\/\/)/ # a// comment immediately following a letter + text = "Error: invalid/disallowed characters in CSS" if text =~ /(\w\/\/*\*)/ # a/* comment immediately following a letter + text = "Error: invalid/disallowed characters in CSS" if text =~ /(\/\*\/)/ # /*/ --> hack attempt, IMO + + # Now, strip out any comments, and do some parsing. + no_comments = text.gsub(/(\/\*.*?\*\/)/, "") # filter out any /* ... */ + no_comments.gsub!("\n", "") + # No backslashes allowed + evil = [ + /(\bdata:\b|eval|cookie|\bwindow\b|\bparent\b|\bthis\b)/i, # suspicious javascript-type words + /behaviou?r|expression|moz-binding|@import|@charset|(java|vb)?script|[\<]|\\\w/i, + /[\<>]/, # back slash, html tags, + /[\x7f-\xff]/, # high bytes -- suspect + /[\x00-\x08\x0B\x0C\x0E-\x1F]/, #low bytes -- suspect + /&\#/, # bad charset + ] + evil.each { |regex| text = "Error: invalid/disallowed characters in CSS" and break if no_comments =~ regex } + + write_attribute :custom_css, text + end +end \ No newline at end of file diff --git a/vendor/plugins/css_file_sanitize/test/css_sanitize_test.rb b/vendor/plugins/css_file_sanitize/test/css_sanitize_test.rb new file mode 100644 index 0000000..5ed02d1 --- /dev/null +++ b/vendor/plugins/css_file_sanitize/test/css_sanitize_test.rb @@ -0,0 +1,115 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class Site < ActiveRecord::Base + include CssSanitize +end + +class CssSanitizeTest < Test::Unit::TestCase + + before do + @site = Site.new(:name => 'Foo', :owner_id => 1) + end + + it "disallows evil css" do + bad_strings = [ + "div.foo { width: 500px; behavior: url(http://foo.com); height: 200px; }", + ".test { color: red; background-image: url('javascript:alert'); border: 1px solid brown; }", + "div.foo { width: 500px; -moz-binding: foo; height: 200px; }", + + # no @import for you + "\@import url(javascript:alert('Your cookie:'+document.cookie));", + + # no behavior either + "behaviour:expression(function(element){alert('xss');}(this));'>", + + # case-sensitivity test + '-Moz-binding: url("http://www.example.comtest.xml");', + + # \uxxrl unicode + "background:\75rl('javascript:alert(\"\\75rl\")');", + "background:url(javascript:alert('html &#x75;'))", + "b\nackground: url(javascript:alert('line-broken background '))", + "background:url(javascript:alert('&#xff55;rl(full-width u)'))", + "background:url(javascript:alert(&#117;rl'))", + "background:url(javascript:alert('&#x75;rl'))", + "background:\75rl('javascript:alert(\"\\75rl\")')", + + # \\d gets parsed out on ffx and ie + "background:url("javascri\\dpt:alert('injected js goes here')")", + + # http://rt.livejournal.org/Ticket/Display.html?id=436 + '-\4d oz-binding: url("http://localhost/test.xml#foo");', + + # css comments are ignored sometimes + "xss:expr/*XSS*/ession(alert('XSS'));", + + # html comments? fail + "background:url(javascript:alert('XSS'));", + + # weird comments + 'color: e/* * / */xpression("r" + "e" + "d");', + + # weird comments to really test that regex + 'color: e/*/**/xpression("r" + "e" + "d");', + + # we're not using a parser, but nonetheless ... if we were.. + <<-STR + p { + dummy: '//'; background:url(javascript:alert('XSS')); + } +STR + ] + bad_strings.each do |string| + @site.custom_css = string + @site.custom_css.should == "Error: invalid/disallowed characters in CSS" + end + end + + + it "allows good css" do + good_strings = [ + ".test { color: red; border: 1px solid brown; }", + "h1 { background: url(http://foobar.com/meh.jpg)}", + "div.foo { width: 500px; height: 200px; }", + "GI b gkljfl kj { { { ********" # gibberish, but should work. + ] + good_strings.each do |string| + @site.custom_css = string + @site.custom_css.should == string + end + + end + + it "does not strip real comments" do + text = <