savage-beast 0.1.0

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.
Files changed (265) hide show
  1. data/.gitignore +2 -0
  2. data/README.rdoc +42 -0
  3. data/Rakefile +25 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/application.rb +6 -0
  6. data/app/controllers/beast_application_controller.rb +3 -0
  7. data/app/controllers/forums_controller.rb +64 -0
  8. data/app/controllers/moderators_controller.rb +10 -0
  9. data/app/controllers/monitorships_controller.rb +22 -0
  10. data/app/controllers/posts_controller.rb +134 -0
  11. data/app/controllers/topics_controller.rb +110 -0
  12. data/app/helpers/count_helper.rb +13 -0
  13. data/app/helpers/forums_helper.rb +15 -0
  14. data/app/helpers/moderators_helper.rb +2 -0
  15. data/app/helpers/monitorships_helper.rb +2 -0
  16. data/app/helpers/posts_helper.rb +3 -0
  17. data/app/helpers/topics_helper.rb +3 -0
  18. data/app/models/forum.rb +26 -0
  19. data/app/models/moderatorship.rb +6 -0
  20. data/app/models/monitorship.rb +5 -0
  21. data/app/models/monitorships_sweeper.rb +9 -0
  22. data/app/models/post.rb +33 -0
  23. data/app/models/posts_sweeper.rb +12 -0
  24. data/app/models/topic.rb +94 -0
  25. data/app/views/forums/_form.html.erb +21 -0
  26. data/app/views/forums/edit.html.erb +12 -0
  27. data/app/views/forums/index.html.erb +77 -0
  28. data/app/views/forums/new.html.erb +10 -0
  29. data/app/views/forums/show.html.erb +94 -0
  30. data/app/views/layouts/_head.html.erb +34 -0
  31. data/app/views/layouts/_post.rss.builder +9 -0
  32. data/app/views/layouts/application.html.erb +29 -0
  33. data/app/views/layouts/beast.html.erb +29 -0
  34. data/app/views/monitorships/create.js.rjs +4 -0
  35. data/app/views/monitorships/destroy.js.rjs +4 -0
  36. data/app/views/posts/_edit.html.erb +38 -0
  37. data/app/views/posts/edit.html.erb +14 -0
  38. data/app/views/posts/edit.js.rjs +6 -0
  39. data/app/views/posts/index.html.erb +53 -0
  40. data/app/views/posts/index.rss.builder +20 -0
  41. data/app/views/posts/monitored.html.erb +55 -0
  42. data/app/views/posts/monitored.rss.builder +15 -0
  43. data/app/views/posts/update.js.rjs +3 -0
  44. data/app/views/topics/_form.html.erb +28 -0
  45. data/app/views/topics/edit.html.erb +10 -0
  46. data/app/views/topics/index.html.erb +2 -0
  47. data/app/views/topics/new.html.erb +18 -0
  48. data/app/views/topics/show.html.erb +183 -0
  49. data/app/views/topics/show.rss.builder +16 -0
  50. data/config/routes.rb +18 -0
  51. data/generators/beast/beast_generator.rb +88 -0
  52. data/generators/beast/templates/migrations/create_savage_tables.rb +73 -0
  53. data/generators/beast/templates/public/images/clearbits/_readme.txt +12 -0
  54. data/generators/beast/templates/public/images/clearbits/add.gif +0 -0
  55. data/generators/beast/templates/public/images/clearbits/addressbook.gif +0 -0
  56. data/generators/beast/templates/public/images/clearbits/alert.gif +0 -0
  57. data/generators/beast/templates/public/images/clearbits/apple.gif +0 -0
  58. data/generators/beast/templates/public/images/clearbits/arrow1_e.gif +0 -0
  59. data/generators/beast/templates/public/images/clearbits/arrow1_n.gif +0 -0
  60. data/generators/beast/templates/public/images/clearbits/arrow1_ne.gif +0 -0
  61. data/generators/beast/templates/public/images/clearbits/arrow1_nw.gif +0 -0
  62. data/generators/beast/templates/public/images/clearbits/arrow1_s.gif +0 -0
  63. data/generators/beast/templates/public/images/clearbits/arrow1_se.gif +0 -0
  64. data/generators/beast/templates/public/images/clearbits/arrow1_sw.gif +0 -0
  65. data/generators/beast/templates/public/images/clearbits/arrow1_w.gif +0 -0
  66. data/generators/beast/templates/public/images/clearbits/arrow2_e.gif +0 -0
  67. data/generators/beast/templates/public/images/clearbits/arrow2_n.gif +0 -0
  68. data/generators/beast/templates/public/images/clearbits/arrow2_ne.gif +0 -0
  69. data/generators/beast/templates/public/images/clearbits/arrow2_nw.gif +0 -0
  70. data/generators/beast/templates/public/images/clearbits/arrow2_s.gif +0 -0
  71. data/generators/beast/templates/public/images/clearbits/arrow2_se.gif +0 -0
  72. data/generators/beast/templates/public/images/clearbits/arrow2_sw.gif +0 -0
  73. data/generators/beast/templates/public/images/clearbits/arrow2_w.gif +0 -0
  74. data/generators/beast/templates/public/images/clearbits/arrow3_e.gif +0 -0
  75. data/generators/beast/templates/public/images/clearbits/arrow3_n.gif +0 -0
  76. data/generators/beast/templates/public/images/clearbits/arrow3_ne.gif +0 -0
  77. data/generators/beast/templates/public/images/clearbits/arrow3_nw.gif +0 -0
  78. data/generators/beast/templates/public/images/clearbits/arrow3_s.gif +0 -0
  79. data/generators/beast/templates/public/images/clearbits/arrow3_se.gif +0 -0
  80. data/generators/beast/templates/public/images/clearbits/arrow3_sw.gif +0 -0
  81. data/generators/beast/templates/public/images/clearbits/arrow3_w.gif +0 -0
  82. data/generators/beast/templates/public/images/clearbits/ascii.gif +0 -0
  83. data/generators/beast/templates/public/images/clearbits/back.gif +0 -0
  84. data/generators/beast/templates/public/images/clearbits/bg_blank.gif +0 -0
  85. data/generators/beast/templates/public/images/clearbits/bg_circle.gif +0 -0
  86. data/generators/beast/templates/public/images/clearbits/bg_rounded.gif +0 -0
  87. data/generators/beast/templates/public/images/clearbits/bg_rounded_ne.gif +0 -0
  88. data/generators/beast/templates/public/images/clearbits/bg_rounded_nw.gif +0 -0
  89. data/generators/beast/templates/public/images/clearbits/bg_rounded_se.gif +0 -0
  90. data/generators/beast/templates/public/images/clearbits/bg_rounded_sw.gif +0 -0
  91. data/generators/beast/templates/public/images/clearbits/bigsmile.gif +0 -0
  92. data/generators/beast/templates/public/images/clearbits/binary.gif +0 -0
  93. data/generators/beast/templates/public/images/clearbits/blah.gif +0 -0
  94. data/generators/beast/templates/public/images/clearbits/bstop.gif +0 -0
  95. data/generators/beast/templates/public/images/clearbits/buy.gif +0 -0
  96. data/generators/beast/templates/public/images/clearbits/calday.gif +0 -0
  97. data/generators/beast/templates/public/images/clearbits/calendar.gif +0 -0
  98. data/generators/beast/templates/public/images/clearbits/camera.gif +0 -0
  99. data/generators/beast/templates/public/images/clearbits/cart.gif +0 -0
  100. data/generators/beast/templates/public/images/clearbits/cd.gif +0 -0
  101. data/generators/beast/templates/public/images/clearbits/cellphone.gif +0 -0
  102. data/generators/beast/templates/public/images/clearbits/chat.gif +0 -0
  103. data/generators/beast/templates/public/images/clearbits/check.gif +0 -0
  104. data/generators/beast/templates/public/images/clearbits/close.gif +0 -0
  105. data/generators/beast/templates/public/images/clearbits/comment.gif +0 -0
  106. data/generators/beast/templates/public/images/clearbits/cube.gif +0 -0
  107. data/generators/beast/templates/public/images/clearbits/day.gif +0 -0
  108. data/generators/beast/templates/public/images/clearbits/denied.gif +0 -0
  109. data/generators/beast/templates/public/images/clearbits/document.gif +0 -0
  110. data/generators/beast/templates/public/images/clearbits/download.gif +0 -0
  111. data/generators/beast/templates/public/images/clearbits/edit.gif +0 -0
  112. data/generators/beast/templates/public/images/clearbits/eject.gif +0 -0
  113. data/generators/beast/templates/public/images/clearbits/equalizer.gif +0 -0
  114. data/generators/beast/templates/public/images/clearbits/first.gif +0 -0
  115. data/generators/beast/templates/public/images/clearbits/flag.gif +0 -0
  116. data/generators/beast/templates/public/images/clearbits/flash.gif +0 -0
  117. data/generators/beast/templates/public/images/clearbits/folder.gif +0 -0
  118. data/generators/beast/templates/public/images/clearbits/forward.gif +0 -0
  119. data/generators/beast/templates/public/images/clearbits/frown.gif +0 -0
  120. data/generators/beast/templates/public/images/clearbits/ftp.gif +0 -0
  121. data/generators/beast/templates/public/images/clearbits/graph.gif +0 -0
  122. data/generators/beast/templates/public/images/clearbits/heart.gif +0 -0
  123. data/generators/beast/templates/public/images/clearbits/home.gif +0 -0
  124. data/generators/beast/templates/public/images/clearbits/html.gif +0 -0
  125. data/generators/beast/templates/public/images/clearbits/ipod.gif +0 -0
  126. data/generators/beast/templates/public/images/clearbits/last.gif +0 -0
  127. data/generators/beast/templates/public/images/clearbits/lock.gif +0 -0
  128. data/generators/beast/templates/public/images/clearbits/loop.gif +0 -0
  129. data/generators/beast/templates/public/images/clearbits/mail.gif +0 -0
  130. data/generators/beast/templates/public/images/clearbits/man.gif +0 -0
  131. data/generators/beast/templates/public/images/clearbits/manman.gif +0 -0
  132. data/generators/beast/templates/public/images/clearbits/music.gif +0 -0
  133. data/generators/beast/templates/public/images/clearbits/mute.gif +0 -0
  134. data/generators/beast/templates/public/images/clearbits/mute_centered.gif +0 -0
  135. data/generators/beast/templates/public/images/clearbits/newwindow.gif +0 -0
  136. data/generators/beast/templates/public/images/clearbits/next.gif +0 -0
  137. data/generators/beast/templates/public/images/clearbits/night.gif +0 -0
  138. data/generators/beast/templates/public/images/clearbits/open.gif +0 -0
  139. data/generators/beast/templates/public/images/clearbits/pause.gif +0 -0
  140. data/generators/beast/templates/public/images/clearbits/phone.gif +0 -0
  141. data/generators/beast/templates/public/images/clearbits/play.gif +0 -0
  142. data/generators/beast/templates/public/images/clearbits/previous.gif +0 -0
  143. data/generators/beast/templates/public/images/clearbits/quicktime.gif +0 -0
  144. data/generators/beast/templates/public/images/clearbits/redo.gif +0 -0
  145. data/generators/beast/templates/public/images/clearbits/reload.gif +0 -0
  146. data/generators/beast/templates/public/images/clearbits/sad.gif +0 -0
  147. data/generators/beast/templates/public/images/clearbits/save.gif +0 -0
  148. data/generators/beast/templates/public/images/clearbits/scream.gif +0 -0
  149. data/generators/beast/templates/public/images/clearbits/search.gif +0 -0
  150. data/generators/beast/templates/public/images/clearbits/seconds.gif +0 -0
  151. data/generators/beast/templates/public/images/clearbits/smile.gif +0 -0
  152. data/generators/beast/templates/public/images/clearbits/smirk.gif +0 -0
  153. data/generators/beast/templates/public/images/clearbits/star.gif +0 -0
  154. data/generators/beast/templates/public/images/clearbits/stop.gif +0 -0
  155. data/generators/beast/templates/public/images/clearbits/subtract.gif +0 -0
  156. data/generators/beast/templates/public/images/clearbits/switch.gif +0 -0
  157. data/generators/beast/templates/public/images/clearbits/target.gif +0 -0
  158. data/generators/beast/templates/public/images/clearbits/tcp.gif +0 -0
  159. data/generators/beast/templates/public/images/clearbits/time.gif +0 -0
  160. data/generators/beast/templates/public/images/clearbits/toggle.gif +0 -0
  161. data/generators/beast/templates/public/images/clearbits/tongue.gif +0 -0
  162. data/generators/beast/templates/public/images/clearbits/tools.gif +0 -0
  163. data/generators/beast/templates/public/images/clearbits/trackback.gif +0 -0
  164. data/generators/beast/templates/public/images/clearbits/trash.gif +0 -0
  165. data/generators/beast/templates/public/images/clearbits/tv.gif +0 -0
  166. data/generators/beast/templates/public/images/clearbits/type.gif +0 -0
  167. data/generators/beast/templates/public/images/clearbits/undo.gif +0 -0
  168. data/generators/beast/templates/public/images/clearbits/unlock.gif +0 -0
  169. data/generators/beast/templates/public/images/clearbits/upload.gif +0 -0
  170. data/generators/beast/templates/public/images/clearbits/user.gif +0 -0
  171. data/generators/beast/templates/public/images/clearbits/video.gif +0 -0
  172. data/generators/beast/templates/public/images/clearbits/volume_high.gif +0 -0
  173. data/generators/beast/templates/public/images/clearbits/volume_low.gif +0 -0
  174. data/generators/beast/templates/public/images/clearbits/wifi.gif +0 -0
  175. data/generators/beast/templates/public/images/clearbits/window.gif +0 -0
  176. data/generators/beast/templates/public/images/clearbits/woman.gif +0 -0
  177. data/generators/beast/templates/public/images/clearbits/womanman.gif +0 -0
  178. data/generators/beast/templates/public/images/clearbits/work.gif +0 -0
  179. data/generators/beast/templates/public/images/clearbits/zoomin.gif +0 -0
  180. data/generators/beast/templates/public/images/clearbits/zoomout.gif +0 -0
  181. data/generators/beast/templates/public/images/feed-icon.png +0 -0
  182. data/generators/beast/templates/public/images/rails.png +0 -0
  183. data/generators/beast/templates/public/images/reply_background.png +0 -0
  184. data/generators/beast/templates/public/images/small_circle.gif +0 -0
  185. data/generators/beast/templates/public/images/spinner.gif +0 -0
  186. data/generators/beast/templates/public/images/spinner_black.gif +0 -0
  187. data/generators/beast/templates/public/images/spinner_bounce.gif +0 -0
  188. data/generators/beast/templates/public/javascripts/beast.js +80 -0
  189. data/generators/beast/templates/public/stylesheets/display.css +941 -0
  190. data/lang/en.yml +206 -0
  191. data/lib/beast.rb +79 -0
  192. data/lib/savage_beast/application_helper.rb +91 -0
  193. data/lib/savage_beast/authentication_system.rb +47 -0
  194. data/lib/savage_beast/user_init.rb +79 -0
  195. data/lib/tasks/capistrano.rake +90 -0
  196. data/lib/tasks/deploy_edge.rake +44 -0
  197. data/lib/tasks/savage_beast.rake +133 -0
  198. data/po/beast.pot +712 -0
  199. data/po/nl/beast.po +700 -0
  200. data/tested_plugins/acts_as_list/README +23 -0
  201. data/tested_plugins/acts_as_list/init.rb +3 -0
  202. data/tested_plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
  203. data/tested_plugins/acts_as_list/test/list_test.rb +332 -0
  204. data/tested_plugins/gibberish/LICENSE +18 -0
  205. data/tested_plugins/gibberish/README +118 -0
  206. data/tested_plugins/gibberish/Rakefile +14 -0
  207. data/tested_plugins/gibberish/init.rb +3 -0
  208. data/tested_plugins/gibberish/lang/es.yml +3 -0
  209. data/tested_plugins/gibberish/lang/fr.yml +3 -0
  210. data/tested_plugins/gibberish/lib/gibberish.rb +8 -0
  211. data/tested_plugins/gibberish/lib/gibberish/localize.rb +88 -0
  212. data/tested_plugins/gibberish/lib/gibberish/string_ext.rb +17 -0
  213. data/tested_plugins/gibberish/test/gibberish_test.rb +203 -0
  214. data/tested_plugins/gibberish/test/lang/es.yml +1 -0
  215. data/tested_plugins/gibberish/test/lang/fr.yml +1 -0
  216. data/tested_plugins/mislav-will_paginate/CHANGELOG.rdoc +110 -0
  217. data/tested_plugins/mislav-will_paginate/LICENSE +18 -0
  218. data/tested_plugins/mislav-will_paginate/README.rdoc +107 -0
  219. data/tested_plugins/mislav-will_paginate/Rakefile +53 -0
  220. data/tested_plugins/mislav-will_paginate/examples/apple-circle.gif +0 -0
  221. data/tested_plugins/mislav-will_paginate/examples/index.haml +69 -0
  222. data/tested_plugins/mislav-will_paginate/examples/index.html +92 -0
  223. data/tested_plugins/mislav-will_paginate/examples/pagination.css +90 -0
  224. data/tested_plugins/mislav-will_paginate/examples/pagination.sass +91 -0
  225. data/tested_plugins/mislav-will_paginate/init.rb +1 -0
  226. data/tested_plugins/mislav-will_paginate/lib/will_paginate.rb +78 -0
  227. data/tested_plugins/mislav-will_paginate/lib/will_paginate/array.rb +16 -0
  228. data/tested_plugins/mislav-will_paginate/lib/will_paginate/collection.rb +146 -0
  229. data/tested_plugins/mislav-will_paginate/lib/will_paginate/core_ext.rb +32 -0
  230. data/tested_plugins/mislav-will_paginate/lib/will_paginate/finder.rb +264 -0
  231. data/tested_plugins/mislav-will_paginate/lib/will_paginate/named_scope.rb +170 -0
  232. data/tested_plugins/mislav-will_paginate/lib/will_paginate/named_scope_patch.rb +37 -0
  233. data/tested_plugins/mislav-will_paginate/lib/will_paginate/version.rb +9 -0
  234. data/tested_plugins/mislav-will_paginate/lib/will_paginate/view_helpers.rb +402 -0
  235. data/tested_plugins/mislav-will_paginate/test/boot.rb +21 -0
  236. data/tested_plugins/mislav-will_paginate/test/collection_test.rb +143 -0
  237. data/tested_plugins/mislav-will_paginate/test/console +8 -0
  238. data/tested_plugins/mislav-will_paginate/test/database.yml +22 -0
  239. data/tested_plugins/mislav-will_paginate/test/finder_test.rb +476 -0
  240. data/tested_plugins/mislav-will_paginate/test/fixtures/admin.rb +3 -0
  241. data/tested_plugins/mislav-will_paginate/test/fixtures/developer.rb +14 -0
  242. data/tested_plugins/mislav-will_paginate/test/fixtures/developers_projects.yml +13 -0
  243. data/tested_plugins/mislav-will_paginate/test/fixtures/project.rb +15 -0
  244. data/tested_plugins/mislav-will_paginate/test/fixtures/projects.yml +6 -0
  245. data/tested_plugins/mislav-will_paginate/test/fixtures/replies.yml +29 -0
  246. data/tested_plugins/mislav-will_paginate/test/fixtures/reply.rb +7 -0
  247. data/tested_plugins/mislav-will_paginate/test/fixtures/schema.rb +38 -0
  248. data/tested_plugins/mislav-will_paginate/test/fixtures/topic.rb +10 -0
  249. data/tested_plugins/mislav-will_paginate/test/fixtures/topics.yml +30 -0
  250. data/tested_plugins/mislav-will_paginate/test/fixtures/user.rb +2 -0
  251. data/tested_plugins/mislav-will_paginate/test/fixtures/users.yml +35 -0
  252. data/tested_plugins/mislav-will_paginate/test/helper.rb +40 -0
  253. data/tested_plugins/mislav-will_paginate/test/lib/activerecord_test_case.rb +43 -0
  254. data/tested_plugins/mislav-will_paginate/test/lib/activerecord_test_connector.rb +75 -0
  255. data/tested_plugins/mislav-will_paginate/test/lib/load_fixtures.rb +11 -0
  256. data/tested_plugins/mislav-will_paginate/test/lib/view_test_process.rb +178 -0
  257. data/tested_plugins/mislav-will_paginate/test/tasks.rake +59 -0
  258. data/tested_plugins/mislav-will_paginate/test/view_test.rb +365 -0
  259. data/tested_plugins/white_list/README +29 -0
  260. data/tested_plugins/white_list/Rakefile +22 -0
  261. data/tested_plugins/white_list/init.rb +2 -0
  262. data/tested_plugins/white_list/lib/white_list_helper.rb +97 -0
  263. data/tested_plugins/white_list/test/white_list_test.rb +132 -0
  264. data/tested_plugins/white_list_formatted_content/init.rb +27 -0
  265. metadata +322 -0
@@ -0,0 +1,22 @@
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
@@ -0,0 +1,2 @@
1
+ require 'white_list_helper'
2
+ ActionView::Base.send :include, WhiteListHelper
@@ -0,0 +1,97 @@
1
+ module WhiteListHelper
2
+ @@protocol_attributes = Set.new %w(src href)
3
+ @@protocol_separator = /:|(&#0*58)|(&#x70)|(%|&#37;)3A/
4
+ mattr_reader :protocol_attributes, :protocol_separator
5
+
6
+ def self.contains_bad_protocols?(white_listed_protocols, value)
7
+ value =~ protocol_separator && !white_listed_protocols.include?(value.split(protocol_separator).first)
8
+ end
9
+
10
+ klass = class << self; self; end
11
+ klass_methods = []
12
+ inst_methods = []
13
+ [:bad_tags, :tags, :attributes, :protocols].each do |attr|
14
+ # Add class methods to the module itself
15
+ klass_methods << <<-EOS
16
+ def #{attr}=(value) @@#{attr} = Set.new(value) end
17
+ def #{attr}() @@#{attr} end
18
+ EOS
19
+
20
+ # prefix the instance methods with white_listed_*
21
+ inst_methods << "def white_listed_#{attr}() ::WhiteListHelper.#{attr} end"
22
+ end
23
+
24
+ klass.class_eval klass_methods.join("\n"), __FILE__, __LINE__
25
+ class_eval inst_methods.join("\n"), __FILE__, __LINE__
26
+
27
+ # This White Listing helper will html encode all tags and strip all attributes that aren't specifically allowed.
28
+ # It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any
29
+ # tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out
30
+ # the extensive test suite.
31
+ #
32
+ # <%= white_list @article.body %>
33
+ #
34
+ # You can add or remove tags/attributes if you want to customize it a bit.
35
+ #
36
+ # Add table tags
37
+ #
38
+ # WhiteListHelper.tags.merge %w(table td th)
39
+ #
40
+ # Remove tags
41
+ #
42
+ # WhiteListHelper.tags.delete 'div'
43
+ #
44
+ # Change allowed attributes
45
+ #
46
+ # WhiteListHelper.attributes.merge %w(id class style)
47
+ #
48
+ # white_list accepts a block for custom tag escaping. Shown below is the default block that white_list uses if none is given.
49
+ # The block is called for all bad tags, and every text node. node is an instance of HTML::Node (either HTML::Tag or HTML::Text).
50
+ # bad is nil for text nodes inside good tags, or is the tag name of the bad tag.
51
+ #
52
+ # <%= white_list(@article.body) { |node, bad| white_listed_bad_tags.include?(bad) ? nil : node.to_s.gsub(/</, '&lt;') } %>
53
+ #
54
+ def white_list(html, options = {}, &block)
55
+ return html if html.blank? || !html.include?('<')
56
+ attrs = Set.new(options[:attributes]).merge(white_listed_attributes)
57
+ tags = Set.new(options[:tags] ).merge(white_listed_tags)
58
+ block ||= lambda { |node, bad| white_listed_bad_tags.include?(bad) ? nil : node.to_s.gsub(/</, '&lt;') }
59
+ returning [] do |new_text|
60
+ tokenizer = HTML::Tokenizer.new(html)
61
+ bad = nil
62
+ while token = tokenizer.next
63
+ node = HTML::Node.parse(nil, 0, 0, token, false)
64
+ new_text << case node
65
+ when HTML::Tag
66
+ node.attributes.keys.each do |attr_name|
67
+ value = node.attributes[attr_name].to_s
68
+ if !attrs.include?(attr_name) || (protocol_attributes.include?(attr_name) && contains_bad_protocols?(value))
69
+ node.attributes.delete(attr_name)
70
+ else
71
+ node.attributes[attr_name] = CGI::escapeHTML(value)
72
+ end
73
+ end if node.attributes
74
+ if tags.include?(node.name)
75
+ bad = nil
76
+ node
77
+ else
78
+ bad = node.name
79
+ block.call node, bad
80
+ end
81
+ else
82
+ block.call node, bad
83
+ end
84
+ end
85
+ end.join
86
+ end
87
+
88
+ protected
89
+ def contains_bad_protocols?(value)
90
+ WhiteListHelper.contains_bad_protocols?(white_listed_protocols, value)
91
+ end
92
+ end
93
+
94
+ WhiteListHelper.bad_tags = %w(script)
95
+ WhiteListHelper.tags = %w(strong em b i p code pre tt output samp kbd var sub sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dt dd abbr acronym a img blockquote del ins fieldset legend)
96
+ WhiteListHelper.attributes = %w(href src width height alt cite datetime title class)
97
+ WhiteListHelper.protocols = %w(ed2k ftp http https irc mailto news gopher nntp telnet webcal xmpp callto feed)
@@ -0,0 +1,132 @@
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.each do |tag_name|
9
+ define_method "test_should_allow_#{tag_name}_tag" do
10
+ assert_white_listed "start <#{tag_name} title=\"1\" name=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo &lt;bad>bar&lt;/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"></a>)
16
+ end
17
+
18
+ %w(src width height alt).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 => ['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" title="1">boo</#{tag}>), %(<#{tag} title="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="&#37;6A&#37;61&#37;76&#37;61&#37;73&#37;63&#37;72&#37;69&#37;70&#37;74&#37;3A&#37;61&#37;6C&#37;65&#37;72&#37;74&#37;28&#37;22&#37;58&#37;53&#37;53&#37;22&#37;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>), ""
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(&quot;XSS&quot;)>),
75
+ %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
76
+ %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>),
77
+ %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>),
78
+ %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>),
79
+ %(<IMG SRC="jav\tascript:alert('XSS');">),
80
+ %(<IMG SRC="jav&#x09;ascript:alert('XSS');">),
81
+ %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">),
82
+ %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">),
83
+ %(<IMG SRC=" &#14; 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>), "&lt;scr>alert(\"XSS\")&lt;/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>), ""
96
+ end
97
+
98
+ def test_should_sanitize_script_tag_with_multiple_open_brackets
99
+ assert_white_listed %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;"
100
+ assert_white_listed %(<iframe src=http://ha.ckers.org/scriptlet.html\n<), %(&lt;iframe src="http:" />&lt;)
101
+ end
102
+
103
+ def test_should_sanitize_unclosed_script
104
+ assert_white_listed %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<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
+ def test_should_allow_custom_block
117
+ html = %(<SCRIPT type="javascript">foo</SCRIPT><img>blah</img><blink>blah</blink>)
118
+ safe = white_list html do |node, bad|
119
+ bad == 'script' ? nil : node
120
+ end
121
+ assert_equal "<img>blah</img><blink>blah</blink>", safe
122
+ end
123
+
124
+ def test_should_sanitize_attributes
125
+ assert_white_listed %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>)
126
+ end
127
+
128
+ protected
129
+ def assert_white_listed(text, expected = nil)
130
+ assert_equal((expected || text), white_list(text))
131
+ end
132
+ end
@@ -0,0 +1,27 @@
1
+ ActiveRecord::Base.class_eval do
2
+ include ActionView::Helpers::TagHelper, ActionView::Helpers::TextHelper, WhiteListHelper
3
+ def self.format_attribute(attr_name)
4
+ class << self; include ActionView::Helpers::TagHelper, ActionView::Helpers::TextHelper, WhiteListHelper; end
5
+ define_method(:body) { read_attribute attr_name }
6
+ define_method(:body_html) { read_attribute "#{attr_name}_html" }
7
+ define_method(:body_html=) { |value| write_attribute "#{attr_name}_html", value }
8
+ before_save :format_content
9
+ end
10
+
11
+ def dom_id
12
+ [self.class.name.downcase.pluralize.dasherize, id] * '-'
13
+ end
14
+
15
+ protected
16
+ def format_content
17
+ body.strip! if body.respond_to?(:strip!)
18
+ self.body_html = body.blank? ? '' : body_html_with_formatting
19
+ end
20
+
21
+ def body_html_with_formatting
22
+ body_html = auto_link(body) { |text| truncate(text, 50) }
23
+ textilized = RedCloth.new(body_html, [ :hard_breaks ])
24
+ textilized.hard_breaks = true if textilized.respond_to?("hard_breaks=")
25
+ white_list(textilized.to_html)
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,322 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: savage-beast
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rick Olson
8
+ - Josh Goebel
9
+ - Bill Harding
10
+ - Pavel Valodzka
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2009-11-14 00:00:00 +02:00
16
+ default_executable:
17
+ dependencies: []
18
+
19
+ description: Rails 2.3 compatible version Savage Beast with i18n support
20
+ email: pavel@valodzka.name
21
+ executables: []
22
+
23
+ extensions: []
24
+
25
+ extra_rdoc_files:
26
+ - README.rdoc
27
+ files:
28
+ - .gitignore
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - app/controllers/application.rb
33
+ - app/controllers/beast_application_controller.rb
34
+ - app/controllers/forums_controller.rb
35
+ - app/controllers/moderators_controller.rb
36
+ - app/controllers/monitorships_controller.rb
37
+ - app/controllers/posts_controller.rb
38
+ - app/controllers/topics_controller.rb
39
+ - app/helpers/count_helper.rb
40
+ - app/helpers/forums_helper.rb
41
+ - app/helpers/moderators_helper.rb
42
+ - app/helpers/monitorships_helper.rb
43
+ - app/helpers/posts_helper.rb
44
+ - app/helpers/topics_helper.rb
45
+ - app/models/forum.rb
46
+ - app/models/moderatorship.rb
47
+ - app/models/monitorship.rb
48
+ - app/models/monitorships_sweeper.rb
49
+ - app/models/post.rb
50
+ - app/models/posts_sweeper.rb
51
+ - app/models/topic.rb
52
+ - app/views/forums/_form.html.erb
53
+ - app/views/forums/edit.html.erb
54
+ - app/views/forums/index.html.erb
55
+ - app/views/forums/new.html.erb
56
+ - app/views/forums/show.html.erb
57
+ - app/views/layouts/_head.html.erb
58
+ - app/views/layouts/_post.rss.builder
59
+ - app/views/layouts/application.html.erb
60
+ - app/views/layouts/beast.html.erb
61
+ - app/views/monitorships/create.js.rjs
62
+ - app/views/monitorships/destroy.js.rjs
63
+ - app/views/posts/_edit.html.erb
64
+ - app/views/posts/edit.html.erb
65
+ - app/views/posts/edit.js.rjs
66
+ - app/views/posts/index.html.erb
67
+ - app/views/posts/index.rss.builder
68
+ - app/views/posts/monitored.html.erb
69
+ - app/views/posts/monitored.rss.builder
70
+ - app/views/posts/update.js.rjs
71
+ - app/views/topics/_form.html.erb
72
+ - app/views/topics/edit.html.erb
73
+ - app/views/topics/index.html.erb
74
+ - app/views/topics/new.html.erb
75
+ - app/views/topics/show.html.erb
76
+ - app/views/topics/show.rss.builder
77
+ - config/routes.rb
78
+ - generators/beast/beast_generator.rb
79
+ - generators/beast/templates/migrations/create_savage_tables.rb
80
+ - generators/beast/templates/public/images/clearbits/_readme.txt
81
+ - generators/beast/templates/public/images/clearbits/add.gif
82
+ - generators/beast/templates/public/images/clearbits/addressbook.gif
83
+ - generators/beast/templates/public/images/clearbits/alert.gif
84
+ - generators/beast/templates/public/images/clearbits/apple.gif
85
+ - generators/beast/templates/public/images/clearbits/arrow1_e.gif
86
+ - generators/beast/templates/public/images/clearbits/arrow1_n.gif
87
+ - generators/beast/templates/public/images/clearbits/arrow1_ne.gif
88
+ - generators/beast/templates/public/images/clearbits/arrow1_nw.gif
89
+ - generators/beast/templates/public/images/clearbits/arrow1_s.gif
90
+ - generators/beast/templates/public/images/clearbits/arrow1_se.gif
91
+ - generators/beast/templates/public/images/clearbits/arrow1_sw.gif
92
+ - generators/beast/templates/public/images/clearbits/arrow1_w.gif
93
+ - generators/beast/templates/public/images/clearbits/arrow2_e.gif
94
+ - generators/beast/templates/public/images/clearbits/arrow2_n.gif
95
+ - generators/beast/templates/public/images/clearbits/arrow2_ne.gif
96
+ - generators/beast/templates/public/images/clearbits/arrow2_nw.gif
97
+ - generators/beast/templates/public/images/clearbits/arrow2_s.gif
98
+ - generators/beast/templates/public/images/clearbits/arrow2_se.gif
99
+ - generators/beast/templates/public/images/clearbits/arrow2_sw.gif
100
+ - generators/beast/templates/public/images/clearbits/arrow2_w.gif
101
+ - generators/beast/templates/public/images/clearbits/arrow3_e.gif
102
+ - generators/beast/templates/public/images/clearbits/arrow3_n.gif
103
+ - generators/beast/templates/public/images/clearbits/arrow3_ne.gif
104
+ - generators/beast/templates/public/images/clearbits/arrow3_nw.gif
105
+ - generators/beast/templates/public/images/clearbits/arrow3_s.gif
106
+ - generators/beast/templates/public/images/clearbits/arrow3_se.gif
107
+ - generators/beast/templates/public/images/clearbits/arrow3_sw.gif
108
+ - generators/beast/templates/public/images/clearbits/arrow3_w.gif
109
+ - generators/beast/templates/public/images/clearbits/ascii.gif
110
+ - generators/beast/templates/public/images/clearbits/back.gif
111
+ - generators/beast/templates/public/images/clearbits/bg_blank.gif
112
+ - generators/beast/templates/public/images/clearbits/bg_circle.gif
113
+ - generators/beast/templates/public/images/clearbits/bg_rounded.gif
114
+ - generators/beast/templates/public/images/clearbits/bg_rounded_ne.gif
115
+ - generators/beast/templates/public/images/clearbits/bg_rounded_nw.gif
116
+ - generators/beast/templates/public/images/clearbits/bg_rounded_se.gif
117
+ - generators/beast/templates/public/images/clearbits/bg_rounded_sw.gif
118
+ - generators/beast/templates/public/images/clearbits/bigsmile.gif
119
+ - generators/beast/templates/public/images/clearbits/binary.gif
120
+ - generators/beast/templates/public/images/clearbits/blah.gif
121
+ - generators/beast/templates/public/images/clearbits/bstop.gif
122
+ - generators/beast/templates/public/images/clearbits/buy.gif
123
+ - generators/beast/templates/public/images/clearbits/calday.gif
124
+ - generators/beast/templates/public/images/clearbits/calendar.gif
125
+ - generators/beast/templates/public/images/clearbits/camera.gif
126
+ - generators/beast/templates/public/images/clearbits/cart.gif
127
+ - generators/beast/templates/public/images/clearbits/cd.gif
128
+ - generators/beast/templates/public/images/clearbits/cellphone.gif
129
+ - generators/beast/templates/public/images/clearbits/chat.gif
130
+ - generators/beast/templates/public/images/clearbits/check.gif
131
+ - generators/beast/templates/public/images/clearbits/close.gif
132
+ - generators/beast/templates/public/images/clearbits/comment.gif
133
+ - generators/beast/templates/public/images/clearbits/cube.gif
134
+ - generators/beast/templates/public/images/clearbits/day.gif
135
+ - generators/beast/templates/public/images/clearbits/denied.gif
136
+ - generators/beast/templates/public/images/clearbits/document.gif
137
+ - generators/beast/templates/public/images/clearbits/download.gif
138
+ - generators/beast/templates/public/images/clearbits/edit.gif
139
+ - generators/beast/templates/public/images/clearbits/eject.gif
140
+ - generators/beast/templates/public/images/clearbits/equalizer.gif
141
+ - generators/beast/templates/public/images/clearbits/first.gif
142
+ - generators/beast/templates/public/images/clearbits/flag.gif
143
+ - generators/beast/templates/public/images/clearbits/flash.gif
144
+ - generators/beast/templates/public/images/clearbits/folder.gif
145
+ - generators/beast/templates/public/images/clearbits/forward.gif
146
+ - generators/beast/templates/public/images/clearbits/frown.gif
147
+ - generators/beast/templates/public/images/clearbits/ftp.gif
148
+ - generators/beast/templates/public/images/clearbits/graph.gif
149
+ - generators/beast/templates/public/images/clearbits/heart.gif
150
+ - generators/beast/templates/public/images/clearbits/home.gif
151
+ - generators/beast/templates/public/images/clearbits/html.gif
152
+ - generators/beast/templates/public/images/clearbits/ipod.gif
153
+ - generators/beast/templates/public/images/clearbits/last.gif
154
+ - generators/beast/templates/public/images/clearbits/lock.gif
155
+ - generators/beast/templates/public/images/clearbits/loop.gif
156
+ - generators/beast/templates/public/images/clearbits/mail.gif
157
+ - generators/beast/templates/public/images/clearbits/man.gif
158
+ - generators/beast/templates/public/images/clearbits/manman.gif
159
+ - generators/beast/templates/public/images/clearbits/music.gif
160
+ - generators/beast/templates/public/images/clearbits/mute.gif
161
+ - generators/beast/templates/public/images/clearbits/mute_centered.gif
162
+ - generators/beast/templates/public/images/clearbits/newwindow.gif
163
+ - generators/beast/templates/public/images/clearbits/next.gif
164
+ - generators/beast/templates/public/images/clearbits/night.gif
165
+ - generators/beast/templates/public/images/clearbits/open.gif
166
+ - generators/beast/templates/public/images/clearbits/pause.gif
167
+ - generators/beast/templates/public/images/clearbits/phone.gif
168
+ - generators/beast/templates/public/images/clearbits/play.gif
169
+ - generators/beast/templates/public/images/clearbits/previous.gif
170
+ - generators/beast/templates/public/images/clearbits/quicktime.gif
171
+ - generators/beast/templates/public/images/clearbits/redo.gif
172
+ - generators/beast/templates/public/images/clearbits/reload.gif
173
+ - generators/beast/templates/public/images/clearbits/sad.gif
174
+ - generators/beast/templates/public/images/clearbits/save.gif
175
+ - generators/beast/templates/public/images/clearbits/scream.gif
176
+ - generators/beast/templates/public/images/clearbits/search.gif
177
+ - generators/beast/templates/public/images/clearbits/seconds.gif
178
+ - generators/beast/templates/public/images/clearbits/smile.gif
179
+ - generators/beast/templates/public/images/clearbits/smirk.gif
180
+ - generators/beast/templates/public/images/clearbits/star.gif
181
+ - generators/beast/templates/public/images/clearbits/stop.gif
182
+ - generators/beast/templates/public/images/clearbits/subtract.gif
183
+ - generators/beast/templates/public/images/clearbits/switch.gif
184
+ - generators/beast/templates/public/images/clearbits/target.gif
185
+ - generators/beast/templates/public/images/clearbits/tcp.gif
186
+ - generators/beast/templates/public/images/clearbits/time.gif
187
+ - generators/beast/templates/public/images/clearbits/toggle.gif
188
+ - generators/beast/templates/public/images/clearbits/tongue.gif
189
+ - generators/beast/templates/public/images/clearbits/tools.gif
190
+ - generators/beast/templates/public/images/clearbits/trackback.gif
191
+ - generators/beast/templates/public/images/clearbits/trash.gif
192
+ - generators/beast/templates/public/images/clearbits/tv.gif
193
+ - generators/beast/templates/public/images/clearbits/type.gif
194
+ - generators/beast/templates/public/images/clearbits/undo.gif
195
+ - generators/beast/templates/public/images/clearbits/unlock.gif
196
+ - generators/beast/templates/public/images/clearbits/upload.gif
197
+ - generators/beast/templates/public/images/clearbits/user.gif
198
+ - generators/beast/templates/public/images/clearbits/video.gif
199
+ - generators/beast/templates/public/images/clearbits/volume_high.gif
200
+ - generators/beast/templates/public/images/clearbits/volume_low.gif
201
+ - generators/beast/templates/public/images/clearbits/wifi.gif
202
+ - generators/beast/templates/public/images/clearbits/window.gif
203
+ - generators/beast/templates/public/images/clearbits/woman.gif
204
+ - generators/beast/templates/public/images/clearbits/womanman.gif
205
+ - generators/beast/templates/public/images/clearbits/work.gif
206
+ - generators/beast/templates/public/images/clearbits/zoomin.gif
207
+ - generators/beast/templates/public/images/clearbits/zoomout.gif
208
+ - generators/beast/templates/public/images/feed-icon.png
209
+ - generators/beast/templates/public/images/rails.png
210
+ - generators/beast/templates/public/images/reply_background.png
211
+ - generators/beast/templates/public/images/small_circle.gif
212
+ - generators/beast/templates/public/images/spinner.gif
213
+ - generators/beast/templates/public/images/spinner_black.gif
214
+ - generators/beast/templates/public/images/spinner_bounce.gif
215
+ - generators/beast/templates/public/javascripts/beast.js
216
+ - generators/beast/templates/public/stylesheets/display.css
217
+ - lang/en.yml
218
+ - lib/beast.rb
219
+ - lib/savage_beast/application_helper.rb
220
+ - lib/savage_beast/authentication_system.rb
221
+ - lib/savage_beast/user_init.rb
222
+ - lib/tasks/capistrano.rake
223
+ - lib/tasks/deploy_edge.rake
224
+ - lib/tasks/savage_beast.rake
225
+ - po/beast.pot
226
+ - po/nl/beast.po
227
+ - tested_plugins/acts_as_list/README
228
+ - tested_plugins/acts_as_list/init.rb
229
+ - tested_plugins/acts_as_list/lib/active_record/acts/list.rb
230
+ - tested_plugins/acts_as_list/test/list_test.rb
231
+ - tested_plugins/gibberish/LICENSE
232
+ - tested_plugins/gibberish/README
233
+ - tested_plugins/gibberish/Rakefile
234
+ - tested_plugins/gibberish/init.rb
235
+ - tested_plugins/gibberish/lang/es.yml
236
+ - tested_plugins/gibberish/lang/fr.yml
237
+ - tested_plugins/gibberish/lib/gibberish.rb
238
+ - tested_plugins/gibberish/lib/gibberish/localize.rb
239
+ - tested_plugins/gibberish/lib/gibberish/string_ext.rb
240
+ - tested_plugins/gibberish/test/gibberish_test.rb
241
+ - tested_plugins/gibberish/test/lang/es.yml
242
+ - tested_plugins/gibberish/test/lang/fr.yml
243
+ - tested_plugins/mislav-will_paginate/CHANGELOG.rdoc
244
+ - tested_plugins/mislav-will_paginate/LICENSE
245
+ - tested_plugins/mislav-will_paginate/README.rdoc
246
+ - tested_plugins/mislav-will_paginate/Rakefile
247
+ - tested_plugins/mislav-will_paginate/examples/apple-circle.gif
248
+ - tested_plugins/mislav-will_paginate/examples/index.haml
249
+ - tested_plugins/mislav-will_paginate/examples/index.html
250
+ - tested_plugins/mislav-will_paginate/examples/pagination.css
251
+ - tested_plugins/mislav-will_paginate/examples/pagination.sass
252
+ - tested_plugins/mislav-will_paginate/init.rb
253
+ - tested_plugins/mislav-will_paginate/lib/will_paginate.rb
254
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/array.rb
255
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/collection.rb
256
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/core_ext.rb
257
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/finder.rb
258
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/named_scope.rb
259
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/named_scope_patch.rb
260
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/version.rb
261
+ - tested_plugins/mislav-will_paginate/lib/will_paginate/view_helpers.rb
262
+ - tested_plugins/mislav-will_paginate/test/boot.rb
263
+ - tested_plugins/mislav-will_paginate/test/collection_test.rb
264
+ - tested_plugins/mislav-will_paginate/test/console
265
+ - tested_plugins/mislav-will_paginate/test/database.yml
266
+ - tested_plugins/mislav-will_paginate/test/finder_test.rb
267
+ - tested_plugins/mislav-will_paginate/test/fixtures/admin.rb
268
+ - tested_plugins/mislav-will_paginate/test/fixtures/developer.rb
269
+ - tested_plugins/mislav-will_paginate/test/fixtures/developers_projects.yml
270
+ - tested_plugins/mislav-will_paginate/test/fixtures/project.rb
271
+ - tested_plugins/mislav-will_paginate/test/fixtures/projects.yml
272
+ - tested_plugins/mislav-will_paginate/test/fixtures/replies.yml
273
+ - tested_plugins/mislav-will_paginate/test/fixtures/reply.rb
274
+ - tested_plugins/mislav-will_paginate/test/fixtures/schema.rb
275
+ - tested_plugins/mislav-will_paginate/test/fixtures/topic.rb
276
+ - tested_plugins/mislav-will_paginate/test/fixtures/topics.yml
277
+ - tested_plugins/mislav-will_paginate/test/fixtures/user.rb
278
+ - tested_plugins/mislav-will_paginate/test/fixtures/users.yml
279
+ - tested_plugins/mislav-will_paginate/test/helper.rb
280
+ - tested_plugins/mislav-will_paginate/test/lib/activerecord_test_case.rb
281
+ - tested_plugins/mislav-will_paginate/test/lib/activerecord_test_connector.rb
282
+ - tested_plugins/mislav-will_paginate/test/lib/load_fixtures.rb
283
+ - tested_plugins/mislav-will_paginate/test/lib/view_test_process.rb
284
+ - tested_plugins/mislav-will_paginate/test/tasks.rake
285
+ - tested_plugins/mislav-will_paginate/test/view_test.rb
286
+ - tested_plugins/mislav-will_paginate/will_paginate.gemspec
287
+ - tested_plugins/white_list/README
288
+ - tested_plugins/white_list/Rakefile
289
+ - tested_plugins/white_list/init.rb
290
+ - tested_plugins/white_list/lib/white_list_helper.rb
291
+ - tested_plugins/white_list/test/white_list_test.rb
292
+ - tested_plugins/white_list_formatted_content/init.rb
293
+ has_rdoc: true
294
+ homepage: http://github.com/valodzka/savage-beast
295
+ licenses: []
296
+
297
+ post_install_message:
298
+ rdoc_options:
299
+ - --charset=UTF-8
300
+ require_paths:
301
+ - lib
302
+ required_ruby_version: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: "0"
307
+ version:
308
+ required_rubygems_version: !ruby/object:Gem::Requirement
309
+ requirements:
310
+ - - ">="
311
+ - !ruby/object:Gem::Version
312
+ version: "0"
313
+ version:
314
+ requirements: []
315
+
316
+ rubyforge_project:
317
+ rubygems_version: 1.3.5
318
+ signing_key:
319
+ specification_version: 3
320
+ summary: Rails forum plugin
321
+ test_files: []
322
+