community_engine 3.0.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +4 -1
- data/.travis.yml +5 -2
- data/CHANGELOG.markdown +270 -0
- data/Gemfile +3 -0
- data/README.markdown +20 -21
- data/Rakefile +8 -6
- data/TODO.markdown +3 -0
- data/UPGRADING.markdown +46 -36
- data/app/assets/javascripts/active_admin.js.coffee +19 -0
- data/app/assets/javascripts/ckeditor/configs/ads.js.coffee +175 -0
- data/app/assets/javascripts/ckeditor/configs/comments.js.coffee +2 -0
- data/app/assets/javascripts/ckeditor/configs/posts.js.coffee +248 -0
- data/app/assets/javascripts/ckeditor/rte/rte.ads.js.coffee +7 -0
- data/app/assets/javascripts/ckeditor/rte/rte.comments.js.coffee +8 -0
- data/app/assets/javascripts/ckeditor/rte/rte.js.coffee +20 -0
- data/app/assets/javascripts/ckeditor/rte/rte.posts.js.coffee +14 -0
- data/app/assets/javascripts/community_engine.js +114 -123
- data/{vendor → app}/assets/javascripts/jcrop/jquery.Jcrop.js +0 -0
- data/{vendor → app}/assets/javascripts/jcrop/jquery.color.js +0 -0
- data/{vendor → app}/assets/javascripts/tag-it/tag-it.js +0 -0
- data/app/assets/stylesheets/active_admin.css.scss +27 -0
- data/{vendor → app}/assets/stylesheets/jcrop/Jcrop.gif +0 -0
- data/{vendor → app}/assets/stylesheets/jcrop/jquery.Jcrop.min.css +0 -0
- data/{vendor → app}/assets/stylesheets/tag-it/tag-it.css +0 -0
- data/{vendor → app}/assets/stylesheets/tag-it/tagit.ui-zendesk.css +0 -0
- data/app/controllers/activities_controller.rb +4 -4
- data/app/controllers/albums_controller.rb +13 -18
- data/app/controllers/authorizations_controller.rb +1 -1
- data/app/controllers/base_controller.rb +9 -32
- data/app/controllers/categories_controller.rb +1 -78
- data/app/controllers/clippings_controller.rb +3 -7
- data/app/controllers/comments_controller.rb +4 -24
- data/app/controllers/events_controller.rb +3 -12
- data/app/controllers/favorites_controller.rb +2 -2
- data/app/controllers/forums_controller.rb +5 -9
- data/app/controllers/invitations_controller.rb +1 -1
- data/app/controllers/messages_controller.rb +4 -8
- data/app/controllers/moderators_controller.rb +1 -1
- data/app/controllers/monitorships_controller.rb +1 -1
- data/app/controllers/pages_controller.rb +0 -62
- data/app/controllers/password_resets_controller.rb +2 -2
- data/app/controllers/photo_manager_controller.rb +3 -3
- data/app/controllers/photos_controller.rb +43 -14
- data/app/controllers/posts_controller.rb +7 -14
- data/app/controllers/rsvps_controller.rb +3 -3
- data/app/controllers/sb_posts_controller.rb +20 -20
- data/app/controllers/sessions_controller.rb +1 -1
- data/app/controllers/tags_controller.rb +4 -52
- data/app/controllers/topics_controller.rb +15 -10
- data/app/controllers/users_controller.rb +9 -16
- data/app/controllers/votes_controller.rb +2 -2
- data/app/helpers/base_helper.rb +4 -14
- data/app/models/acts_as_taggable_on/tag.rb +9 -41
- data/app/models/clipping.rb +1 -1
- data/app/models/forum.rb +2 -2
- data/app/models/photo.rb +1 -1
- data/app/models/post.rb +1 -1
- data/app/models/sb_post.rb +19 -15
- data/app/models/topic.rb +10 -10
- data/app/models/user.rb +1 -1
- data/app/policies/active_admin/page_policy.rb +11 -0
- data/app/policies/application_policy.rb +59 -0
- data/app/policies/post_policy.rb +13 -0
- data/app/policies/sb_post_policy.rb +15 -0
- data/app/policies/topic_policy.rb +23 -0
- data/app/views/ckeditor/pictures/index.html.haml +15 -0
- data/app/views/ckeditor/shared/_asset.html.haml +9 -0
- data/app/views/ckeditor/shared/_asset_tmpl.html.erb +14 -0
- data/app/views/comments/approve.js.haml +1 -1
- data/app/views/comments/create.js.erb +1 -1
- data/app/views/comments/edit.js.erb +2 -1
- data/app/views/events/_subscribe.html.haml +1 -1
- data/app/views/forums/show.html.haml +8 -4
- data/app/views/posts/show.html.haml +4 -0
- data/app/views/sb_posts/_edit_script.js.erb +2 -3
- data/app/views/sb_posts/_reply_script.js.erb +2 -4
- data/app/views/sb_posts/_sb_post.html.haml +7 -6
- data/app/views/sb_posts/create.js.erb +4 -4
- data/app/views/sb_posts/edit.js.erb +2 -1
- data/app/views/sessions/_menu_item.html.haml +4 -4
- data/app/views/shared/_end_javascript.html.haml +1 -2
- data/app/views/shared/_login_sidebar.html.haml +2 -2
- data/app/views/tags/show.html.haml +3 -3
- data/app/views/topics/show.html.haml +1 -1
- data/app/views/users/_profile_user_info_sidebar.html.haml +2 -2
- data/app/views/users/destroy.js.erb +3 -0
- data/app/views/users/new.html.haml +1 -1
- data/app/views/users/show.html.haml +1 -1
- data/app/views/users/signup_completed.html.haml +1 -1
- data/community_engine.gemspec +14 -11
- data/config/initializers/active_admin.rb +239 -0
- data/config/initializers/ckeditor.rb +8 -0
- data/config/initializers/ransack_bootstrap_fix.rb +25 -0
- data/config/locales/de-DE.yml +1 -0
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +14 -19
- data/config/spring.rb +1 -0
- data/db/migrate/083_create_active_admin_comments.rb +19 -0
- data/lib/community_engine.rb +7 -3
- data/lib/community_engine/admin/ads.rb +3 -0
- data/lib/community_engine/admin/categories.rb +20 -0
- data/lib/community_engine/admin/comments.rb +4 -0
- data/lib/community_engine/admin/dashboard.rb +38 -0
- data/lib/community_engine/admin/events.rb +3 -0
- data/lib/community_engine/admin/forums.rb +3 -0
- data/lib/community_engine/admin/homepage_features.rb +25 -0
- data/lib/community_engine/admin/metro_areas.rb +4 -0
- data/lib/community_engine/admin/pages.rb +26 -0
- data/lib/community_engine/admin/posts.rb +92 -0
- data/lib/community_engine/admin/tags.rb +21 -0
- data/lib/community_engine/admin/users.rb +54 -0
- data/lib/community_engine/authenticated_system.rb +5 -20
- data/lib/community_engine/engine.rb +5 -0
- data/lib/community_engine/version.rb +1 -1
- data/lib/resource_feeder/atom.rb +2 -0
- data/lib/resource_feeder/rss.rb +2 -0
- data/lib/white_list.rb +6 -11
- data/test/fixtures/events.yml +10 -0
- data/test/fixtures/tags.yml +6 -5
- data/test/functional/activities_controller_test.rb +19 -19
- data/test/functional/admin/posts_controller_test.rb +16 -0
- data/test/functional/admin_controller_test.rb +82 -82
- data/test/functional/categories_controller_test.rb +0 -39
- data/test/functional/comments_controller_test.rb +14 -7
- data/test/functional/favorites_controller_test.rb +15 -16
- data/test/functional/pages_controller_test.rb +0 -71
- data/test/functional/posts_controller_test.rb +21 -2
- data/test/functional/sb_posts_controller_test.rb +3 -3
- data/test/functional/sessions_controller_test.rb +2 -2
- data/test/functional/tags_controller_test.rb +9 -20
- data/test/functional/users_controller_test.rb +0 -8
- data/test/functional/votes_controller_test.rb +1 -1
- data/test/testapp/config/spring.rb +1 -0
- data/test/testapp/db/schema.rb +16 -1
- data/test/unit/event_test.rb +1 -1
- metadata +204 -170
- data/CHANGELOG +0 -144
- data/app/controllers/admin_controller.rb +0 -80
- data/app/controllers/ads_controller.rb +0 -90
- data/app/controllers/homepage_features_controller.rb +0 -74
- data/app/controllers/metro_areas_controller.rb +0 -74
- data/app/controllers/statistics_controller.rb +0 -35
- data/app/views/admin/comments.html.haml +0 -53
- data/app/views/admin/events.html.haml +0 -26
- data/app/views/admin/messages.html.haml +0 -3
- data/app/views/admin/update.js.erb +0 -1
- data/app/views/admin/users.html.haml +0 -57
- data/app/views/ads/_form.html.haml +0 -21
- data/app/views/ads/edit.html.haml +0 -7
- data/app/views/ads/index.html.haml +0 -29
- data/app/views/ads/new.html.haml +0 -6
- data/app/views/ads/show.html.haml +0 -19
- data/app/views/categories/_form.html.haml +0 -8
- data/app/views/categories/edit.html.haml +0 -4
- data/app/views/categories/index.html.haml +0 -20
- data/app/views/categories/new.html.haml +0 -4
- data/app/views/homepage_features/_form.html.haml +0 -6
- data/app/views/homepage_features/edit.html.haml +0 -6
- data/app/views/homepage_features/index.html.haml +0 -24
- data/app/views/homepage_features/new.html.haml +0 -2
- data/app/views/homepage_features/show.html.haml +0 -27
- data/app/views/metro_areas/_form.html.haml +0 -6
- data/app/views/metro_areas/edit.html.haml +0 -8
- data/app/views/metro_areas/index.html.haml +0 -21
- data/app/views/metro_areas/new.html.haml +0 -6
- data/app/views/metro_areas/show.html.haml +0 -14
- data/app/views/pages/_form.html.haml +0 -18
- data/app/views/pages/edit.html.haml +0 -4
- data/app/views/pages/index.html.haml +0 -34
- data/app/views/pages/new.html.haml +0 -7
- data/app/views/shared/_admin_nav.html.haml +0 -17
- data/app/views/shared/_load_tinymce.js.erb +0 -15
- data/app/views/statistics/activities.xml.builder +0 -33
- data/app/views/statistics/index.html.haml +0 -48
- data/app/views/tags/edit.html.haml +0 -12
- data/app/views/tags/manage.html.haml +0 -30
- data/app/views/users/update.js.erb +0 -1
- data/test/functional/ads_controller_test.rb +0 -51
- data/test/functional/homepage_features_controller_test.rb +0 -69
- data/test/functional/metro_areas_controller_test.rb +0 -63
- data/test/functional/statistics_controller_test.rb +0 -18
- data/test/unit/acts_as_taggable_on/tag_test.rb +0 -22
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/README +0 -3
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/Rakefile +0 -22
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/generators/publishing/publishing_generator.rb +0 -34
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/generators/publishing/templates/migration.rb +0 -13
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/install.rb +0 -3
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/test/acts_as_publishable_test.rb +0 -8
- data/vendor/converted2.3plugins_to_lib_leftovers/acts_as_publishable/uninstall.rb +0 -1
- data/vendor/converted2.3plugins_to_lib_leftovers/resource_feeder/README +0 -4
- data/vendor/converted2.3plugins_to_lib_leftovers/resource_feeder/Rakefile +0 -22
- data/vendor/converted2.3plugins_to_lib_leftovers/resource_feeder/test/atom_feed_test.rb +0 -85
- data/vendor/converted2.3plugins_to_lib_leftovers/resource_feeder/test/rss_feed_test.rb +0 -61
- data/vendor/converted2.3plugins_to_lib_leftovers/resource_feeder/test/test_helper.rb +0 -60
- data/vendor/converted2.3plugins_to_lib_leftovers/white_list/README +0 -35
- data/vendor/converted2.3plugins_to_lib_leftovers/white_list/Rakefile +0 -22
- data/vendor/converted2.3plugins_to_lib_leftovers/white_list/test/white_list_test.rb +0 -120
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
|
5
|
-
desc 'Default: run unit tests.'
|
6
|
-
task :default => :test
|
7
|
-
|
8
|
-
desc 'Test the acts_as_publishable plugin.'
|
9
|
-
Rake::TestTask.new(:test) do |t|
|
10
|
-
t.libs << 'lib'
|
11
|
-
t.pattern = 'test/**/*_test.rb'
|
12
|
-
t.verbose = true
|
13
|
-
end
|
14
|
-
|
15
|
-
desc 'Generate documentation for the acts_as_publishable plugin.'
|
16
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
-
rdoc.rdoc_dir = 'rdoc'
|
18
|
-
rdoc.title = 'ActsAsPublishable'
|
19
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
-
rdoc.rdoc_files.include('README')
|
21
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
class PublishingGenerator < Rails::Generator::Base
|
2
|
-
|
3
|
-
attr_reader :publishing_class
|
4
|
-
attr_reader :publishing_table_name
|
5
|
-
|
6
|
-
def initialize(args, options = {})
|
7
|
-
klass = args.last
|
8
|
-
|
9
|
-
begin; valid_klass = klass.camelcase.constantize; rescue; end
|
10
|
-
|
11
|
-
if valid_klass
|
12
|
-
@publishing_table_name = klass.to_s.downcase.pluralize
|
13
|
-
@publishing_class = klass.to_s.capitalize
|
14
|
-
else
|
15
|
-
raise "#{klass} is not a valid class in this application."
|
16
|
-
end
|
17
|
-
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def manifest
|
22
|
-
record do |m|
|
23
|
-
unless options[:skip_migration]
|
24
|
-
m.migration_template 'migration.rb', 'db/migrate',
|
25
|
-
:migration_file_name => "add_published_as_to_#{@publishing_table_name}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
def usage
|
32
|
-
puts "Usage: #{$0} publishing [ModelName]"
|
33
|
-
end
|
34
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class AddPublishedAsTo<%= publishing_class.pluralize %> < ActiveRecord::Migration
|
2
|
-
|
3
|
-
# Add the new tables.
|
4
|
-
def self.up
|
5
|
-
add_column :<%= publishing_table_name %>, :published_as, :string, :limit => 16, :default => 'draft'
|
6
|
-
end
|
7
|
-
|
8
|
-
# Remove the tables.
|
9
|
-
def self.down
|
10
|
-
remove_column :<%= publishing_table_name %>, :published_as
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
# Uninstall hook code here
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
|
5
|
-
desc 'Default: run unit tests.'
|
6
|
-
task :default => :test
|
7
|
-
|
8
|
-
desc 'Test the resource_feed plugin.'
|
9
|
-
Rake::TestTask.new(:test) do |t|
|
10
|
-
t.libs << 'lib'
|
11
|
-
t.pattern = 'test/**/*_test.rb'
|
12
|
-
t.verbose = true
|
13
|
-
end
|
14
|
-
|
15
|
-
desc 'Generate documentation for the resource_feed plugin.'
|
16
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
-
rdoc.rdoc_dir = 'rdoc'
|
18
|
-
rdoc.title = 'ResourceFeed'
|
19
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
-
rdoc.rdoc_files.include('README')
|
21
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/test_helper'
|
2
|
-
class AtomFeedTest < Test::Unit::TestCase
|
3
|
-
attr_reader :request
|
4
|
-
|
5
|
-
def setup
|
6
|
-
@request = OpenStruct.new
|
7
|
-
@request.host_with_port = 'example.com'
|
8
|
-
@records = Array.new(5).fill(Post.new)
|
9
|
-
@records.each &:save
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_default_atom_feed
|
13
|
-
atom_feed_for @records
|
14
|
-
|
15
|
-
assert_select 'feed' do
|
16
|
-
assert_select '>title', 'Posts'
|
17
|
-
assert_select '>id', "tag:#{request.host_with_port}:Posts"
|
18
|
-
assert_select '>link' do
|
19
|
-
assert_select "[rel='alternate']"
|
20
|
-
assert_select "[type='text/html']"
|
21
|
-
assert_select "[href='http://example.com/posts']"
|
22
|
-
end
|
23
|
-
assert_select 'entry', 5 do
|
24
|
-
assert_select 'title', :text => 'feed title (title)'
|
25
|
-
assert_select "content[type='html']", '<p>feed description (description)</p>'
|
26
|
-
assert_select 'id', "tag:#{request.host_with_port},#{@records.first.created_at.xmlschema}:#{'http://example.com/posts/1'}"
|
27
|
-
assert_select 'published', @records.first.created_at.xmlschema
|
28
|
-
assert_select 'updated', @records.first.created_at.xmlschema
|
29
|
-
assert_select 'link' do
|
30
|
-
assert_select "[rel='alternate']"
|
31
|
-
assert_select "[type='text/html']"
|
32
|
-
assert_select "[href='http://example.com/posts/1']"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_should_allow_custom_feed_options
|
39
|
-
atom_feed_for @records, :feed => { :title => 'Custom Posts', :link => '/posts', :description => 'stuff', :self => '/posts.atom' }
|
40
|
-
|
41
|
-
assert_select 'feed>title', 'Custom Posts'
|
42
|
-
assert_select "feed>link[href='/posts']"
|
43
|
-
assert_select 'feed>subtitle', 'stuff'
|
44
|
-
assert_select 'feed>link' do
|
45
|
-
assert_select "[rel='self']"
|
46
|
-
assert_select "[type='application/atom+xml']"
|
47
|
-
assert_select "[href='/posts.atom']"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_should_allow_custom_item_attributes
|
52
|
-
atom_feed_for @records, :item => { :title => :name, :description => :body, :pub_date => :create_date, :link => :id }
|
53
|
-
|
54
|
-
assert_select 'entry', 5 do
|
55
|
-
assert_select 'title', :text => 'feed title (name)'
|
56
|
-
assert_select "content[type='html']", '<p>feed description (body)</p>'
|
57
|
-
assert_select 'published', (@records.first.created_at - 5.minutes).xmlschema
|
58
|
-
assert_select 'updated', (@records.first.created_at - 5.minutes).xmlschema
|
59
|
-
assert_select 'id', "tag:#{request.host_with_port},#{(@records.first.created_at - 5.minutes).xmlschema}:1"
|
60
|
-
assert_select 'link' do
|
61
|
-
assert_select "[rel='alternate']"
|
62
|
-
assert_select "[type='text/html']"
|
63
|
-
assert_select "[href='1']"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_should_allow_custom_item_attribute_blocks
|
69
|
-
atom_feed_for @records, :item => { :title => lambda { |r| r.name }, :description => lambda { |r| r.body }, :pub_date => lambda { |r| r.create_date },
|
70
|
-
:link => lambda { |r| "/#{r.created_at.to_i}" }, :guid => lambda { |r| r.created_at.to_i } }
|
71
|
-
|
72
|
-
assert_select 'entry', 5 do
|
73
|
-
assert_select 'title', :text => 'feed title (name)'
|
74
|
-
assert_select "content[type='html']", '<p>feed description (body)</p>'
|
75
|
-
assert_select 'published', (@records.first.created_at - 5.minutes).xmlschema
|
76
|
-
assert_select 'updated', (@records.first.created_at - 5.minutes).xmlschema
|
77
|
-
assert_select 'id', /:\d+$/
|
78
|
-
assert_select 'link' do
|
79
|
-
assert_select "[rel='alternate']"
|
80
|
-
assert_select "[type='text/html']"
|
81
|
-
assert_select "[href=?]", /^\/\d+$/
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/test_helper'
|
2
|
-
class RssFeedTest < Test::Unit::TestCase
|
3
|
-
def setup
|
4
|
-
@records = Array.new(5).fill(Post.new)
|
5
|
-
@records.each &:save
|
6
|
-
end
|
7
|
-
|
8
|
-
def test_default_rss_feed
|
9
|
-
rss_feed_for @records
|
10
|
-
|
11
|
-
assert_select 'rss[version="2.0"]' do
|
12
|
-
assert_select 'channel' do
|
13
|
-
assert_select '>title', 'Posts'
|
14
|
-
assert_select '>link', 'http://example.com/posts'
|
15
|
-
assert_select 'language', 'en-us'
|
16
|
-
assert_select 'ttl', '40'
|
17
|
-
end
|
18
|
-
assert_select 'item', 5 do
|
19
|
-
assert_select 'title', :text => 'feed title (title)'
|
20
|
-
assert_select 'description', '<p>feed description (description)</p>'
|
21
|
-
%w(guid link).each do |node|
|
22
|
-
assert_select node, 'http://example.com/posts/1'
|
23
|
-
end
|
24
|
-
assert_select 'pubDate', @records.first.created_at.to_s(:rfc822)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_should_allow_custom_feed_options
|
30
|
-
rss_feed_for @records, :feed => { :title => 'Custom Posts', :link => '/posts', :description => 'stuff', :language => 'en-gb', :ttl => '80' }
|
31
|
-
|
32
|
-
assert_select 'channel>title', 'Custom Posts'
|
33
|
-
assert_select 'channel>link', '/posts'
|
34
|
-
assert_select 'channel>description', 'stuff'
|
35
|
-
assert_select 'channel>language', 'en-gb'
|
36
|
-
assert_select 'channel>ttl', '80'
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_should_allow_custom_item_attributes
|
40
|
-
rss_feed_for @records, :item => { :title => :name, :description => :body, :pub_date => :create_date, :link => :id }
|
41
|
-
|
42
|
-
assert_select 'item', 5 do
|
43
|
-
assert_select 'title', :text => 'feed title (name)'
|
44
|
-
assert_select 'description', '<p>feed description (body)</p>'
|
45
|
-
assert_select 'pubDate', (@records.first.created_at - 5.minutes).to_s(:rfc822)
|
46
|
-
assert_select 'link', '1'
|
47
|
-
assert_select 'guid', '1'
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_should_allow_custom_item_attribute_blocks
|
52
|
-
rss_feed_for @records, :item => { :title => lambda { |r| r.name }, :description => lambda { |r| r.body }, :pub_date => lambda { |r| r.create_date },
|
53
|
-
:link => lambda { |r| "/#{r.created_at.to_i}" }, :guid => lambda { |r| r.created_at.to_i } }
|
54
|
-
|
55
|
-
assert_select 'item', 5 do
|
56
|
-
assert_select 'title', :text => 'feed title (name)'
|
57
|
-
assert_select 'description', '<p>feed description (body)</p>'
|
58
|
-
assert_select 'pubDate', (@records.first.created_at - 5.minutes).to_s(:rfc822)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
Rails.env = 'test'
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
|
3
|
-
require 'action_controller/test_process'
|
4
|
-
require 'breakpoint'
|
5
|
-
require 'ostruct'
|
6
|
-
|
7
|
-
class Post
|
8
|
-
attr_reader :id, :created_at
|
9
|
-
def save; @id = 1; @created_at = Time.now.utc end
|
10
|
-
def new_record?; @id.nil? end
|
11
|
-
|
12
|
-
[:title, :name].each do |attr_name|
|
13
|
-
define_method attr_name do
|
14
|
-
"feed title (#{attr_name})"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
[:description, :body].each do |attr_name|
|
19
|
-
define_method attr_name do
|
20
|
-
"<p>feed description (#{attr_name})</p>"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def create_date
|
25
|
-
@created_at - 5.minutes
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class Test::Unit::TestCase
|
30
|
-
include ResourceFeeder::Rss, ResourceFeeder::Atom
|
31
|
-
|
32
|
-
def render_feed(xml)
|
33
|
-
@response = OpenStruct.new
|
34
|
-
@response.headers = {'Content-Type' => 'text/xml'}
|
35
|
-
@response.body = xml
|
36
|
-
end
|
37
|
-
|
38
|
-
def rss_feed_for_with_ostruct(resources, options = {})
|
39
|
-
render_feed rss_feed_for_without_ostruct(resources, options)
|
40
|
-
end
|
41
|
-
|
42
|
-
def atom_feed_for_with_ostruct(resources, options = {})
|
43
|
-
render_feed atom_feed_for_without_ostruct(resources, options)
|
44
|
-
end
|
45
|
-
|
46
|
-
alias_method_chain :rss_feed_for, :ostruct
|
47
|
-
alias_method_chain :atom_feed_for, :ostruct
|
48
|
-
|
49
|
-
def html_document
|
50
|
-
@html_document ||= HTML::Document.new(@response.body, false, true)
|
51
|
-
end
|
52
|
-
|
53
|
-
def user_posts_url
|
54
|
-
"http://example.com/posts"
|
55
|
-
end
|
56
|
-
|
57
|
-
def user_post_url(post)
|
58
|
-
"http://example.com/posts/#{post.id}"
|
59
|
-
end
|
60
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
WhiteList
|
2
|
-
=========
|
3
|
-
|
4
|
-
This White Listing helper will html encode all tags and strip all attributes that aren't specifically allowed.
|
5
|
-
It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any
|
6
|
-
tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out
|
7
|
-
the extensive test suite.
|
8
|
-
|
9
|
-
<%= white_list @article.body %>
|
10
|
-
|
11
|
-
You can add or remove tags/attributes if you want to customize it a bit.
|
12
|
-
|
13
|
-
add table tags
|
14
|
-
|
15
|
-
WhiteListHelper.tags += %w(table td th)
|
16
|
-
|
17
|
-
remove tags
|
18
|
-
|
19
|
-
WhiteListHelper.tags -= %w(div span)
|
20
|
-
|
21
|
-
clear any attributes that are allowed for <a> tags
|
22
|
-
|
23
|
-
WhiteListHelper.attributes['a'] = []
|
24
|
-
|
25
|
-
allow a new attribute for the <img> tag
|
26
|
-
|
27
|
-
WhiteListHelper.attributes['img'] += %w(style)
|
28
|
-
|
29
|
-
add new tag with attributes
|
30
|
-
|
31
|
-
WhiteListHelper.attributes['table'] = %w(cellpadding cellspacing)
|
32
|
-
|
33
|
-
change allowed attributes for all tags
|
34
|
-
|
35
|
-
WhiteListHelper.attributes[nil] = %w(id class style)
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
|
5
|
-
desc 'Default: run unit tests.'
|
6
|
-
task :default => :test
|
7
|
-
|
8
|
-
desc 'Test the white_list plugin.'
|
9
|
-
Rake::TestTask.new(:test) do |t|
|
10
|
-
t.libs << 'lib'
|
11
|
-
t.pattern = 'test/**/*_test.rb'
|
12
|
-
t.verbose = true
|
13
|
-
end
|
14
|
-
|
15
|
-
desc 'Generate documentation for the white_list plugin.'
|
16
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
-
rdoc.rdoc_dir = 'rdoc'
|
18
|
-
rdoc.title = 'WhiteList'
|
19
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
-
rdoc.rdoc_files.include('README')
|
21
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
|
3
|
-
|
4
|
-
class WhiteListTest < Test::Unit::TestCase
|
5
|
-
include WhiteListHelper
|
6
|
-
public :contains_bad_protocols?
|
7
|
-
|
8
|
-
(WhiteListHelper.tags + WhiteListHelper.attributes.keys).compact.each do |tag_name|
|
9
|
-
define_method "test_should_allow_#{tag_name}_tag" do
|
10
|
-
assert_white_listed "start <#{tag_name} id=\"1\" name=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", "start <#{tag_name} id='1'>foo <bad>bar</bad> baz</#{tag_name}> end"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_should_allow_anchors
|
15
|
-
assert_white_listed %(<a href="foo" onclick="bar"><script>baz</script></a>), "<a href='foo'><script>baz</script></a>"
|
16
|
-
end
|
17
|
-
|
18
|
-
WhiteListHelper.attributes['img'].each do |img_attr|
|
19
|
-
define_method "test_should_allow_image_#{img_attr}_attribute" do
|
20
|
-
assert_white_listed %(<img #{img_attr}="foo" onclick="bar" />), "<img #{img_attr}='foo' />"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_should_handle_non_html
|
25
|
-
assert_white_listed 'abc'
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_should_handle_blank_text
|
29
|
-
assert_white_listed nil
|
30
|
-
assert_white_listed ''
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_should_allow_custom_tags
|
34
|
-
text = "<u>foo</u>"
|
35
|
-
assert_equal(text, white_list(text, :tags => %w(u)))
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_should_allow_custom_tags_with_attributes
|
39
|
-
text = "<fieldset foo='bar'>foo</fieldset>"
|
40
|
-
assert_equal(text, white_list(text, :attributes => {'fieldset' => %w(foo)}))
|
41
|
-
end
|
42
|
-
|
43
|
-
[%w(img src), %w(a href)].each do |(tag, attr)|
|
44
|
-
define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do
|
45
|
-
assert_white_listed %(<#{tag} #{attr}="javascript:bang" id="1">boo</#{tag}>), %(<#{tag} id='1'>boo</#{tag}>)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_should_flag_bad_protocols
|
50
|
-
%w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto|
|
51
|
-
assert contains_bad_protocols?("#{proto}://bad")
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_should_accept_good_protocols
|
56
|
-
WhiteListHelper.protocols.each do |proto|
|
57
|
-
assert !contains_bad_protocols?("#{proto}://good")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_should_reject_hex_codes_in_protocol
|
62
|
-
assert contains_bad_protocols?("%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29")
|
63
|
-
assert_white_listed %(<a href="%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29">1</a>), "<a>1</a>"
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_should_block_script_tag
|
67
|
-
assert_white_listed %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), "<script src='http:' /></script>"
|
68
|
-
end
|
69
|
-
|
70
|
-
[%(<IMG SRC="javascript:alert('XSS');">),
|
71
|
-
%(<IMG SRC=javascript:alert('XSS')>),
|
72
|
-
%(<IMG SRC=JaVaScRiPt:alert('XSS')>),
|
73
|
-
%(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">),
|
74
|
-
%(<IMG SRC=javascript:alert("XSS")>),
|
75
|
-
%(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
|
76
|
-
%(<IMG SRC=javascript:alert('XSS')>),
|
77
|
-
%(<IMG SRC=javascript:alert('XSS')>),
|
78
|
-
%(<IMG SRC=javascript:alert('XSS')>),
|
79
|
-
%(<IMG SRC="jav\tascript:alert('XSS');">),
|
80
|
-
%(<IMG SRC="jav	ascript:alert('XSS');">),
|
81
|
-
%(<IMG SRC="jav
ascript:alert('XSS');">),
|
82
|
-
%(<IMG SRC="jav
ascript:alert('XSS');">),
|
83
|
-
%(<IMG SRC="  javascript:alert('XSS');">),
|
84
|
-
%(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i|
|
85
|
-
define_method "test_should_not_fall_for_xss_image_hack_#{i}" do
|
86
|
-
assert_white_listed img_hack, "<img>"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_should_sanitize_tag_broken_up_by_null
|
91
|
-
assert_white_listed %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "<scr>alert(\"XSS\")</scr>"
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_should_sanitize_invalid_script_tag
|
95
|
-
assert_white_listed %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), "<script /></script>"
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_should_sanitize_script_tag_with_multiple_open_brackets
|
99
|
-
assert_white_listed %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "<<script>alert(\"XSS\");//<</script>"
|
100
|
-
assert_white_listed %(<iframe src=http://ha.ckers.org/scriptlet.html\n<), "<iframe src='http:' /><"
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_should_sanitize_unclosed_script
|
104
|
-
assert_white_listed %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<script src='http:' /><b>"
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_should_sanitize_half_open_scripts
|
108
|
-
assert_white_listed %(<IMG SRC="javascript:alert('XSS')"), "<img>"
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_should_not_fall_for_ridiculous_hack
|
112
|
-
img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>)
|
113
|
-
assert_white_listed img_hack, "<img>"
|
114
|
-
end
|
115
|
-
|
116
|
-
protected
|
117
|
-
def assert_white_listed(text, expected = nil)
|
118
|
-
assert_equal((expected || text), white_list(text))
|
119
|
-
end
|
120
|
-
end
|