ensnare 0.1beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (341) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +10 -0
  3. data/README.md +77 -0
  4. data/Rakefile +40 -0
  5. data/app/assets/javascripts/application.js +10 -0
  6. data/app/assets/javascripts/ensnare/ZeroClipboard.js +474 -0
  7. data/app/assets/javascripts/ensnare/ZeroClipboard.min.js +9 -0
  8. data/app/assets/javascripts/ensnare/ZeroClipboard.swf +0 -0
  9. data/app/assets/javascripts/ensnare/application.js +20 -0
  10. data/app/assets/javascripts/ensnare/bootstrap-switch.js +382 -0
  11. data/app/assets/javascripts/ensnare/bootstrap_and_overrides.js +4 -0
  12. data/app/assets/javascripts/ensnare/clippy.js +18 -0
  13. data/app/assets/javascripts/ensnare/config_switch.js +19 -0
  14. data/app/assets/javascripts/ensnare/on_handler.js +9 -0
  15. data/app/assets/stylesheets/application.css +7 -0
  16. data/app/assets/stylesheets/bootstrap_and_overrides.css.less +30 -0
  17. data/app/assets/stylesheets/ensnare/application.css +13 -0
  18. data/app/assets/stylesheets/ensnare/bootstrap-switch.css +408 -0
  19. data/app/assets/stylesheets/ensnare/bootstrap_and_overrides.css +7 -0
  20. data/app/assets/stylesheets/ensnare/dashboard.css +4 -0
  21. data/app/assets/stylesheets/ensnare/toggle-switch.css +310 -0
  22. data/app/assets/stylesheets/ensnare/violation.css +4 -0
  23. data/app/controllers/ensnare/application_controller.rb +22 -0
  24. data/app/controllers/ensnare/configuration_controller.rb +15 -0
  25. data/app/controllers/ensnare/dashboard_controller.rb +32 -0
  26. data/app/controllers/ensnare/violations_controller.rb +36 -0
  27. data/app/helpers/ensnare/application_helper.rb +4 -0
  28. data/app/helpers/ensnare/dashboard_helper.rb +6 -0
  29. data/app/helpers/ensnare/violation_helper.rb +4 -0
  30. data/app/models/ensnare/violation.rb +6 -0
  31. data/app/views/ensnare/dashboard/configs.html.erb +1191 -0
  32. data/app/views/ensnare/dashboard/edit.html.erb +2 -0
  33. data/app/views/ensnare/dashboard/metrics.html.erb +38 -0
  34. data/app/views/ensnare/dashboard/metrics/_table.html.erb +17 -0
  35. data/app/views/ensnare/dashboard/mode.html.erb +75 -0
  36. data/app/views/ensnare/dashboard/violations.html.erb +32 -0
  37. data/app/views/ensnare/violations/captcha.html.erb +11 -0
  38. data/app/views/ensnare/violations/redirect.html.erb +2 -0
  39. data/app/views/ensnare/violations/show.html.erb +2 -0
  40. data/app/views/layouts/ensnare/application.html.erb +77 -0
  41. data/app/views/layouts/ensnare/captcha.html.erb +51 -0
  42. data/config/locales/en.bootstrap.yml +18 -0
  43. data/config/routes.rb +14 -0
  44. data/db/migrate/20131007205246_create_ensnare_violations.rb +10 -0
  45. data/db/migrate/20131007210137_rename_violation_type_field.rb +6 -0
  46. data/db/migrate/20131029010445_add_fields_to_violation.rb +8 -0
  47. data/db/migrate/20131031001835_add_name_to_ensnare_violation.rb +5 -0
  48. data/db/migrate/20131121163305_add_weight_to_violations.rb +5 -0
  49. data/lib/ensnare.rb +306 -0
  50. data/lib/ensnare/controllers/helpers.rb +143 -0
  51. data/lib/ensnare/engine.rb +30 -0
  52. data/lib/ensnare/form_tag_helper.rb +116 -0
  53. data/lib/ensnare/responses/block.rb +8 -0
  54. data/lib/ensnare/responses/captcha.rb +20 -0
  55. data/lib/ensnare/responses/flash_error.rb +11 -0
  56. data/lib/ensnare/responses/none.rb +10 -0
  57. data/lib/ensnare/responses/not_found.rb +9 -0
  58. data/lib/ensnare/responses/random_content.rb +11 -0
  59. data/lib/ensnare/responses/redirect.rb +8 -0
  60. data/lib/ensnare/responses/redirect_loop.rb +10 -0
  61. data/lib/ensnare/responses/response.rb +19 -0
  62. data/lib/ensnare/responses/server_error.rb +8 -0
  63. data/lib/ensnare/responses/throttle.rb +8 -0
  64. data/lib/ensnare/traps/cookie.rb +98 -0
  65. data/lib/ensnare/traps/parameter.rb +88 -0
  66. data/lib/ensnare/traps/reg_ex.rb +26 -0
  67. data/lib/ensnare/traps/routing_error.rb +25 -0
  68. data/lib/ensnare/traps/trap.rb +36 -0
  69. data/lib/ensnare/version.rb +3 -0
  70. data/lib/generators/ensnare/install_generator.rb +12 -0
  71. data/lib/generators/templates/ensnare.rb +44 -0
  72. data/lib/tasks/ensnare_tasks.rb +4 -0
  73. data/test/dummy/Gemfile +46 -0
  74. data/test/dummy/Gemfile.lock +149 -0
  75. data/test/dummy/README.rdoc +261 -0
  76. data/test/dummy/Rakefile +7 -0
  77. data/test/dummy/app/assets/images/rails.png +0 -0
  78. data/test/dummy/app/assets/javascripts/application.js +16 -0
  79. data/test/dummy/app/assets/javascripts/bootstrap.js +4 -0
  80. data/test/dummy/app/assets/javascripts/bootstrap.js.coffee +3 -0
  81. data/test/dummy/app/assets/javascripts/widgets.js.coffee +3 -0
  82. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  83. data/test/dummy/app/assets/stylesheets/bootstrap_and_overrides.css +7 -0
  84. data/test/dummy/app/assets/stylesheets/scaffolds.css.scss +69 -0
  85. data/test/dummy/app/assets/stylesheets/widgets.css.scss +3 -0
  86. data/test/dummy/app/controllers/application_controller.rb +12 -0
  87. data/test/dummy/app/controllers/widgets_controller.rb +94 -0
  88. data/test/dummy/app/helpers/application_helper.rb +2 -0
  89. data/test/dummy/app/helpers/widgets_helper.rb +2 -0
  90. data/test/dummy/app/models/user.rb +15 -0
  91. data/test/dummy/app/models/widget.rb +4 -0
  92. data/test/dummy/app/views/layouts/application.html.erb +108 -0
  93. data/test/dummy/app/views/widgets/_form.html.erb +25 -0
  94. data/test/dummy/app/views/widgets/edit.html.erb +6 -0
  95. data/test/dummy/app/views/widgets/index.html.erb +25 -0
  96. data/test/dummy/app/views/widgets/new.html.erb +5 -0
  97. data/test/dummy/app/views/widgets/show.html.erb +15 -0
  98. data/test/dummy/config.ru +4 -0
  99. data/test/dummy/config/application.rb +65 -0
  100. data/test/dummy/config/boot.rb +6 -0
  101. data/test/dummy/config/database.yml +25 -0
  102. data/test/dummy/config/environment.rb +5 -0
  103. data/test/dummy/config/environments/development.rb +41 -0
  104. data/test/dummy/config/environments/production.rb +67 -0
  105. data/test/dummy/config/environments/test.rb +37 -0
  106. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  107. data/test/dummy/config/initializers/captcha.rb +5 -0
  108. data/test/dummy/config/initializers/devise.rb +258 -0
  109. data/test/dummy/config/initializers/ensnare.rb +272 -0
  110. data/test/dummy/config/initializers/ensnare.sample +323 -0
  111. data/test/dummy/config/initializers/examples.example +323 -0
  112. data/test/dummy/config/initializers/inflections.rb +15 -0
  113. data/test/dummy/config/initializers/mime_types.rb +5 -0
  114. data/test/dummy/config/initializers/quiet_assets.rb +13 -0
  115. data/test/dummy/config/initializers/secret_token.rb +7 -0
  116. data/test/dummy/config/initializers/session_store.rb +8 -0
  117. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  118. data/test/dummy/config/locales/devise.en.yml +60 -0
  119. data/test/dummy/config/locales/en.bootstrap.yml +18 -0
  120. data/test/dummy/config/locales/en.yml +5 -0
  121. data/test/dummy/config/routes.rb +68 -0
  122. data/test/dummy/db/development.sqlite3 +0 -0
  123. data/test/dummy/db/migrate/20131007193540_create_widgets.rb +10 -0
  124. data/test/dummy/db/migrate/20131031153254_devise_create_users.rb +42 -0
  125. data/test/dummy/db/migrate/20140405051634_create_ensnare_violations.ensnare.rb +11 -0
  126. data/test/dummy/db/migrate/20140405051635_rename_violation_type_field.ensnare.rb +7 -0
  127. data/test/dummy/db/migrate/20140405051636_add_fields_to_violation.ensnare.rb +9 -0
  128. data/test/dummy/db/migrate/20140405051637_add_name_to_ensnare_violation.ensnare.rb +6 -0
  129. data/test/dummy/db/migrate/20140405051638_add_weight_to_violations.ensnare.rb +6 -0
  130. data/test/dummy/db/schema.rb +54 -0
  131. data/test/dummy/db/seeds.rb +7 -0
  132. data/test/dummy/db/test.sqlite3 +0 -0
  133. data/test/dummy/doc/README_FOR_APP +2 -0
  134. data/test/dummy/lib/ensnare/responses/custom.rb_sample +11 -0
  135. data/test/dummy/lib/ensnare/traps/custom.rb_sample +26 -0
  136. data/test/dummy/log/development.log +92903 -0
  137. data/test/dummy/log/production.log +158 -0
  138. data/test/dummy/public/404.html +26 -0
  139. data/test/dummy/public/422.html +26 -0
  140. data/test/dummy/public/500.html +25 -0
  141. data/test/dummy/public/favicon.ico +0 -0
  142. data/test/dummy/public/robots.txt +5 -0
  143. data/test/dummy/script/rails +6 -0
  144. data/test/dummy/test/fixtures/users.yml +11 -0
  145. data/test/dummy/test/fixtures/widgets.yml +9 -0
  146. data/test/dummy/test/functional/widgets_controller_test.rb +49 -0
  147. data/test/dummy/test/performance/browsing_test.rb +12 -0
  148. data/test/dummy/test/test_helper.rb +13 -0
  149. data/test/dummy/test/unit/helpers/widgets_helper_test.rb +4 -0
  150. data/test/dummy/test/unit/user_test.rb +7 -0
  151. data/test/dummy/test/unit/widget_test.rb +7 -0
  152. data/test/dummy/tmp/cache/assets/C10/FA0/sprockets%2F269fa26485a91206814a45af06210315 +0 -0
  153. data/test/dummy/tmp/cache/assets/C23/310/sprockets%2Fc79437284218b38e613366d14284ac07 +0 -0
  154. data/test/dummy/tmp/cache/assets/C40/710/sprockets%2F545779172fbf9cf79082774a07841659 +0 -0
  155. data/test/dummy/tmp/cache/assets/C48/0D0/sprockets%2F75b535a43e06025546821f95d011d85b +0 -0
  156. data/test/dummy/tmp/cache/assets/C4E/110/sprockets%2Fb806449c86337e3e06070c462280e90b +0 -0
  157. data/test/dummy/tmp/cache/assets/C57/BD0/sprockets%2Facd987410b744152d157762609194e8c +0 -0
  158. data/test/dummy/tmp/cache/assets/C5D/9E0/sprockets%2F0d79b66115628050357f99d36aa4876d +0 -0
  159. data/test/dummy/tmp/cache/assets/C80/840/sprockets%2F562c2d168da585f80579347d10790a0a +0 -0
  160. data/test/dummy/tmp/cache/assets/C84/DD0/sprockets%2F3e508585142de6585818df6a2290bf11 +0 -0
  161. data/test/dummy/tmp/cache/assets/C85/E00/sprockets%2Fcbe2d565923657893e41f9160d30e540 +0 -0
  162. data/test/dummy/tmp/cache/assets/C88/BC0/sprockets%2F341dd4748a8a73570a59264e9f9540b2 +0 -0
  163. data/test/dummy/tmp/cache/assets/C8D/F80/sprockets%2F81e191073a2f74b9eca460537339789f +0 -0
  164. data/test/dummy/tmp/cache/assets/C98/B10/sprockets%2F94976d41a9fc1279e0cd996c78087410 +0 -0
  165. data/test/dummy/tmp/cache/assets/C9F/190/sprockets%2Fb8f3f499dc494543381d55292e346e99 +0 -0
  166. data/test/dummy/tmp/cache/assets/CA4/1A0/sprockets%2F629131c0f22f0d55ed1725737a343bd7 +0 -0
  167. data/test/dummy/tmp/cache/assets/CAD/EB0/sprockets%2F481955f78ac093b746e0512b4a9c1b24 +0 -0
  168. data/test/dummy/tmp/cache/assets/CB0/8D0/sprockets%2Fba6342b6172d4ee18e951f667e237313 +0 -0
  169. data/test/dummy/tmp/cache/assets/CB4/DC0/sprockets%2F48af5bbf36e6f2720f4144f928129612 +0 -0
  170. data/test/dummy/tmp/cache/assets/CB7/5B0/sprockets%2F67a1cdb0edc3998371d944050583e358 +0 -0
  171. data/test/dummy/tmp/cache/assets/CB8/F00/sprockets%2F089f52a057d7a14247c7f93e8b59143b +0 -0
  172. data/test/dummy/tmp/cache/assets/CBD/0E0/sprockets%2F662f42b5efa6584377436f1d94318cd4 +0 -0
  173. data/test/dummy/tmp/cache/assets/CBF/4D0/sprockets%2F1462d4ee75c877880447a02b2f58e6b9 +0 -0
  174. data/test/dummy/tmp/cache/assets/CC3/220/sprockets%2F218c30380a6f2bae6b7402068da50f01 +0 -0
  175. data/test/dummy/tmp/cache/assets/CC7/200/sprockets%2F5366d8fff996ca22271713d1ca987379 +0 -0
  176. data/test/dummy/tmp/cache/assets/CCE/810/sprockets%2F90453c5b48e1f0a4f1a6836135c1c4b1 +0 -0
  177. data/test/dummy/tmp/cache/assets/CD4/E90/sprockets%2F5464e430cbb52421e1f9c23947fe31c1 +0 -0
  178. data/test/dummy/tmp/cache/assets/CD5/2C0/sprockets%2F166c056119ebdfb8b7104c97b424b423 +0 -0
  179. data/test/dummy/tmp/cache/assets/CD7/6F0/sprockets%2Fbd3936370d0f952ada5774e2230046ed +0 -0
  180. data/test/dummy/tmp/cache/assets/CD7/C90/sprockets%2F5382f60c349e1511eefc83803fa450c1 +0 -0
  181. data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  182. data/test/dummy/tmp/cache/assets/CDC/5C0/sprockets%2F9767868b3b77f9164f290797f1d8fe5c +0 -0
  183. data/test/dummy/tmp/cache/assets/CDE/570/sprockets%2F0e30065c6148a1ef8d5e42439e148f4d +0 -0
  184. data/test/dummy/tmp/cache/assets/CE0/CC0/sprockets%2F2b38c3fb549036de5c4666637a0c80c6 +0 -0
  185. data/test/dummy/tmp/cache/assets/CE0/F80/sprockets%2F487624acd392c0310f0c7434e88d48bf +0 -0
  186. data/test/dummy/tmp/cache/assets/CE4/570/sprockets%2F306a61edb38d739bb2f81b448b376818 +0 -0
  187. data/test/dummy/tmp/cache/assets/CE5/C70/sprockets%2F681ae890ae2f44aee1099119d04a7938 +0 -0
  188. data/test/dummy/tmp/cache/assets/CE5/CE0/sprockets%2F9d186abc5f6a106511502d60d98ff939 +0 -0
  189. data/test/dummy/tmp/cache/assets/CE6/B90/sprockets%2F5997a940521ec92b2ea92eb63c49a562 +0 -0
  190. data/test/dummy/tmp/cache/assets/CE6/DE0/sprockets%2F9889a2fbf25b223583561299dfca004e +0 -0
  191. data/test/dummy/tmp/cache/assets/CE7/6F0/sprockets%2F6ac42c22840f7d853b6184b6f94a65c8 +0 -0
  192. data/test/dummy/tmp/cache/assets/CE7/E70/sprockets%2F704fcbd6f72c99767550538053a0bc7d +0 -0
  193. data/test/dummy/tmp/cache/assets/CE8/6E0/sprockets%2F51f80f23e41678e790edd8710c6d75c0 +0 -0
  194. data/test/dummy/tmp/cache/assets/CE9/510/sprockets%2F0c8887733a9e311fd348f21029d6bef6 +0 -0
  195. data/test/dummy/tmp/cache/assets/CEA/BA0/sprockets%2F98e291b46a924814292e2daf17ad8c84 +0 -0
  196. data/test/dummy/tmp/cache/assets/CF4/140/sprockets%2F22a3157d204c1f8e417a25f01a2dbe45 +0 -0
  197. data/test/dummy/tmp/cache/assets/CF6/EE0/sprockets%2F9e92e631fb88a8e23180da66c77859f0 +0 -0
  198. data/test/dummy/tmp/cache/assets/CF7/8B0/sprockets%2F0f091833381aa52e100fb74924fdc1aa +0 -0
  199. data/test/dummy/tmp/cache/assets/CF9/AF0/sprockets%2Fe6cf7ff483a7c68902418a2f4b374889 +0 -0
  200. data/test/dummy/tmp/cache/assets/CFF/C60/sprockets%2F0889d12d44383c7e7a859966f686badf +0 -0
  201. data/test/dummy/tmp/cache/assets/D04/D90/sprockets%2F617b1ad4f3ced27a38b689309c3240a2 +0 -0
  202. data/test/dummy/tmp/cache/assets/D06/D60/sprockets%2Fa09118ec6cd7033eb762b64a1ae58274 +0 -0
  203. data/test/dummy/tmp/cache/assets/D07/8B0/sprockets%2Ff123328eedad10b6f547eba992560504 +0 -0
  204. data/test/dummy/tmp/cache/assets/D09/740/sprockets%2Fb4177155aa0b2a846458b4da378dbe56 +0 -0
  205. data/test/dummy/tmp/cache/assets/D0A/6F0/sprockets%2Fa394b21853c45302cad3b17f7de2489e +0 -0
  206. data/test/dummy/tmp/cache/assets/D0B/E00/sprockets%2Fce33d32f3235ad54031338e689a8bdc7 +0 -0
  207. data/test/dummy/tmp/cache/assets/D0C/3B0/sprockets%2Ff34ef114cb808f84780a11082ade91d7 +0 -0
  208. data/test/dummy/tmp/cache/assets/D0F/3E0/sprockets%2F6654975eaa53a225d976278fcb6baa00 +0 -0
  209. data/test/dummy/tmp/cache/assets/D0F/550/sprockets%2F9927550095e029ace0d4d5add6901ce5 +0 -0
  210. data/test/dummy/tmp/cache/assets/D10/790/sprockets%2F31d2271940e9d19a9a5fb42fc70f26d7 +0 -0
  211. data/test/dummy/tmp/cache/assets/D12/1F0/sprockets%2Fce0c803f16e21317768892d42f1a8efc +0 -0
  212. data/test/dummy/tmp/cache/assets/D12/8E0/sprockets%2F93656a1c9a1db15ff824a84f3867c3b0 +0 -0
  213. data/test/dummy/tmp/cache/assets/D14/380/sprockets%2F7d5975b3efc5ace265c437a91539101f +0 -0
  214. data/test/dummy/tmp/cache/assets/D14/890/sprockets%2F2cb018dd1879c96fa83d4909b04f21e5 +0 -0
  215. data/test/dummy/tmp/cache/assets/D16/1F0/sprockets%2Fb19e1a25f43ad7167231aee857288f6f +0 -0
  216. data/test/dummy/tmp/cache/assets/D18/150/sprockets%2F524feca5ed7674507bd2e517943f45c4 +0 -0
  217. data/test/dummy/tmp/cache/assets/D19/6F0/sprockets%2Fc63725cd8e7d8f30818f7a82a75cc331 +0 -0
  218. data/test/dummy/tmp/cache/assets/D1A/600/sprockets%2F56bf56fa14222faef68241a4866f9e28 +0 -0
  219. data/test/dummy/tmp/cache/assets/D1E/AF0/sprockets%2F38fb02a7c41a3f3956e1f8b783885af8 +0 -0
  220. data/test/dummy/tmp/cache/assets/D21/2A0/sprockets%2F1fa2a4758d368a4ed74af19d94958d53 +0 -0
  221. data/test/dummy/tmp/cache/assets/D23/C30/sprockets%2F30a075c86c0057f03ed03a1a6c1ac74f +0 -0
  222. data/test/dummy/tmp/cache/assets/D2C/3A0/sprockets%2F5fb3206e15e73cbac0463d4e0633b9c1 +0 -0
  223. data/test/dummy/tmp/cache/assets/D2D/B40/sprockets%2F214ba38cd9bae5351510b85c60b1cf66 +0 -0
  224. data/test/dummy/tmp/cache/assets/D31/410/sprockets%2F1fb41a8351cfe74b19081d3a0a8cd186 +0 -0
  225. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  226. data/test/dummy/tmp/cache/assets/D34/3C0/sprockets%2Fd6f33bf9ea577a425537e31a1b1436aa +0 -0
  227. data/test/dummy/tmp/cache/assets/D36/A50/sprockets%2F4c5a2303a78ff5007cba199ec980b41d +0 -0
  228. data/test/dummy/tmp/cache/assets/D38/300/sprockets%2F231189114e3e16c0af8cbbfb922a7c89 +0 -0
  229. data/test/dummy/tmp/cache/assets/D3A/320/sprockets%2Fb4e466a4108157e7bbdf8a80530e76ab +0 -0
  230. data/test/dummy/tmp/cache/assets/D3C/430/sprockets%2Fc1850205179d6bc0315cf87db4edd7a8 +0 -0
  231. data/test/dummy/tmp/cache/assets/D3C/600/sprockets%2F6cb9fa003e4ae915755dbc429d54b255 +0 -0
  232. data/test/dummy/tmp/cache/assets/D3D/970/sprockets%2F9e70fe2b22f4504ee45029b9d04ce46c +0 -0
  233. data/test/dummy/tmp/cache/assets/D3F/4A0/sprockets%2F9d1d25fb38006ddc0e6fcf42190d8583 +0 -0
  234. data/test/dummy/tmp/cache/assets/D3F/D70/sprockets%2Fa7d40ead3d8014db7e90ec643e323969 +0 -0
  235. data/test/dummy/tmp/cache/assets/D43/7F0/sprockets%2F05ba12f3e980c9658d979415aca6a3ce +0 -0
  236. data/test/dummy/tmp/cache/assets/D45/7E0/sprockets%2Fc24e2e08818f34b11af78c7b4467fb5f +0 -0
  237. data/test/dummy/tmp/cache/assets/D45/970/sprockets%2Ff0e7b8648d5a2519256c1eeb2d9f08d2 +0 -0
  238. data/test/dummy/tmp/cache/assets/D45/F90/sprockets%2F6b6e959a5f0990831a196b6bddb05f3b +0 -0
  239. data/test/dummy/tmp/cache/assets/D47/E90/sprockets%2Fa578fc0e68c5d167fc5c365e2c09a616 +0 -0
  240. data/test/dummy/tmp/cache/assets/D48/090/sprockets%2F7a07a493490b7ac1cc0466a9eed8e589 +0 -0
  241. data/test/dummy/tmp/cache/assets/D4A/820/sprockets%2Feb00ebb7f262bff8638844571e1a859f +0 -0
  242. data/test/dummy/tmp/cache/assets/D4B/160/sprockets%2F78835ac7e39b080e262f9a4b76cbd65d +0 -0
  243. data/test/dummy/tmp/cache/assets/D4B/320/sprockets%2F4a570986eef4f2707130eb8c9c36d9ad +0 -0
  244. data/test/dummy/tmp/cache/assets/D4C/7F0/sprockets%2F5c0e220ac801d18f4bd1bd65e043d20a +0 -0
  245. data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  246. data/test/dummy/tmp/cache/assets/D4F/E20/sprockets%2F2da45938fca5e6979baa57c61b43b689 +0 -0
  247. data/test/dummy/tmp/cache/assets/D51/C40/sprockets%2F9c881f9a0edd974bf6ff0f83a4308192 +0 -0
  248. data/test/dummy/tmp/cache/assets/D52/6A0/sprockets%2F8b5de085dffa4897817e72a1b75348cd +0 -0
  249. data/test/dummy/tmp/cache/assets/D54/210/sprockets%2F8d24b46f6838cc66ddb9c7b07d32e939 +0 -0
  250. data/test/dummy/tmp/cache/assets/D56/C20/sprockets%2F4ce9229c7c971ce590189cfea1e74d95 +0 -0
  251. data/test/dummy/tmp/cache/assets/D5A/310/sprockets%2F7f968e95238c9866f6ebd76a16b2aab6 +0 -0
  252. data/test/dummy/tmp/cache/assets/D5A/7B0/sprockets%2Fda913ea979b742f1f7418f488e32fe8f +0 -0
  253. data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  254. data/test/dummy/tmp/cache/assets/D5C/1F0/sprockets%2Fed34fbbec82818204a214b5114d3dce5 +0 -0
  255. data/test/dummy/tmp/cache/assets/D64/700/sprockets%2F76c71d55a65dae34d0f60d62ee3a63b0 +0 -0
  256. data/test/dummy/tmp/cache/assets/D64/DE0/sprockets%2F655e1ca6a735ac75093c0e01febce293 +0 -0
  257. data/test/dummy/tmp/cache/assets/D72/4B0/sprockets%2F34ba5dd43adc2c826b79ce9a944f8620 +0 -0
  258. data/test/dummy/tmp/cache/assets/D76/710/sprockets%2F6740efeff28c623e091100f28f7c9eaf +0 -0
  259. data/test/dummy/tmp/cache/assets/D77/3D0/sprockets%2F76515b80ab945bb46f93cdace3993c4e +0 -0
  260. data/test/dummy/tmp/cache/assets/D78/C60/sprockets%2F3ed4e68ec22d09a66c1ea96e6b733d66 +0 -0
  261. data/test/dummy/tmp/cache/assets/D92/5E0/sprockets%2F17d03aff61dbd220217eb7f159bb8df2 +0 -0
  262. data/test/dummy/tmp/cache/assets/D96/CE0/sprockets%2Fff431fe62bbb5f0e9d63c43c4010fd56 +0 -0
  263. data/test/dummy/tmp/cache/assets/D9C/CF0/sprockets%2Fde9afe6f38620c4144b5a5fd1dc36f23 +0 -0
  264. data/test/dummy/tmp/cache/assets/D9C/EA0/sprockets%2Ff1cdf6c71079c7b373b1b842bf4e9a3a +0 -0
  265. data/test/dummy/tmp/cache/assets/D9D/590/sprockets%2F93ee64febc21345494bfbd0a8aad6446 +0 -0
  266. data/test/dummy/tmp/cache/assets/D9E/490/sprockets%2Fe231e8b6ec488aecaf61d84bb542e029 +0 -0
  267. data/test/dummy/tmp/cache/assets/D9E/6A0/sprockets%2F0a9e2c29287a00d9b9cc94cd9b3af63a +0 -0
  268. data/test/dummy/tmp/cache/assets/DA0/110/sprockets%2F29a7ddee7ded49b2613bb26f5d0980a3 +0 -0
  269. data/test/dummy/tmp/cache/assets/DA2/580/sprockets%2F35d3674fac89e6235b3fa6b251fbc3ff +0 -0
  270. data/test/dummy/tmp/cache/assets/DA2/780/sprockets%2F83886a2d2dba19d6cf5a2ea7fe7213d7 +0 -0
  271. data/test/dummy/tmp/cache/assets/DA3/9C0/sprockets%2F7f2d6495f1f675acc353e0a37adc94ae +0 -0
  272. data/test/dummy/tmp/cache/assets/DA6/B80/sprockets%2F60bbf1fc573c8bc35c8da9082888cb6c +0 -0
  273. data/test/dummy/tmp/cache/assets/DA6/EB0/sprockets%2F83015053ed9a581994cafcbbf9e7e6ab +0 -0
  274. data/test/dummy/tmp/cache/assets/DA7/0C0/sprockets%2Fc9194b0b488f53a9afc0540ced96ad9e +0 -0
  275. data/test/dummy/tmp/cache/assets/DA7/6D0/sprockets%2F28ce714e9b9d6aa16c4604bc9b5afd79 +0 -0
  276. data/test/dummy/tmp/cache/assets/DA9/490/sprockets%2F9815ad0a7dab6fbdfb2856654298acf7 +0 -0
  277. data/test/dummy/tmp/cache/assets/DAC/E40/sprockets%2Fec3c6d68d0e246ed889fe31471dc44fc +0 -0
  278. data/test/dummy/tmp/cache/assets/DAE/050/sprockets%2F6a3d58d879f5afbf0ad526425fe76a5f +0 -0
  279. data/test/dummy/tmp/cache/assets/DB8/040/sprockets%2F218aaca004d507da6f207ce9de821bea +0 -0
  280. data/test/dummy/tmp/cache/assets/DBB/E80/sprockets%2Fa01bf17ca00dc2b43f749abe69cad680 +0 -0
  281. data/test/dummy/tmp/cache/assets/DBD/170/sprockets%2Fc229df8cfb1c041769d0bb3c8eb310ac +0 -0
  282. data/test/dummy/tmp/cache/assets/DBF/770/sprockets%2F89c90a5f9259fc5b1b6ed69efe7c88d2 +0 -0
  283. data/test/dummy/tmp/cache/assets/DBF/850/sprockets%2Fb37d146f03d1ab72bd81afa3b7c295bf +0 -0
  284. data/test/dummy/tmp/cache/assets/DC3/E90/sprockets%2F63fce83ccf6fed1a634c00ec9623ba30 +0 -0
  285. data/test/dummy/tmp/cache/assets/DC4/1B0/sprockets%2Fedae9235cb5ca2fc97c2d335ba27a660 +0 -0
  286. data/test/dummy/tmp/cache/assets/DC7/2B0/sprockets%2Fda49c151b0b2be5bf6e8e135bd6f80d6 +0 -0
  287. data/test/dummy/tmp/cache/assets/DC9/C70/sprockets%2Fba5f2321c2ee8c42d0ff498a12e5bf7e +0 -0
  288. data/test/dummy/tmp/cache/assets/DCA/DC0/sprockets%2F7ed2addf814bfd28c3bad7790e005d53 +0 -0
  289. data/test/dummy/tmp/cache/assets/DCB/320/sprockets%2F672cc04c39b0a37cbe89cecbf3580ad7 +0 -0
  290. data/test/dummy/tmp/cache/assets/DCB/AE0/sprockets%2Fd14638ac9aaefa36ca75c1d66cb727e3 +0 -0
  291. data/test/dummy/tmp/cache/assets/DCC/1D0/sprockets%2Ff6defe1375c5acb57e141263b70fe5eb +0 -0
  292. data/test/dummy/tmp/cache/assets/DD1/DB0/sprockets%2Fc7a35f025c7fb33a2d9ce83ce4bd4f86 +0 -0
  293. data/test/dummy/tmp/cache/assets/DD2/5B0/sprockets%2F91c620bad817c7ffa64d5ea8b446db6f +0 -0
  294. data/test/dummy/tmp/cache/assets/DD2/D60/sprockets%2Fcc373f8a8e1d94ed2154dc37ca0f3ff6 +0 -0
  295. data/test/dummy/tmp/cache/assets/DD5/8E0/sprockets%2F0dde6f938e5addbdab55f6e7037e1482 +0 -0
  296. data/test/dummy/tmp/cache/assets/DD5/B80/sprockets%2Fdd3beb4c76fbf877171fd66192ebc4b2 +0 -0
  297. data/test/dummy/tmp/cache/assets/DD7/F30/sprockets%2Fe5fedf2dc39b7a678447c63ee2601ebc +0 -0
  298. data/test/dummy/tmp/cache/assets/DDB/200/sprockets%2F9dd434d9f9a3f7f4b35d90a0ddd6fb19 +0 -0
  299. data/test/dummy/tmp/cache/assets/DDC/1F0/sprockets%2F7533abdaee852b1c7bb05cabe3b2040a +0 -0
  300. data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  301. data/test/dummy/tmp/cache/assets/DDD/190/sprockets%2F85d9f2c43cee7e82bdf893e0d35ac66a +0 -0
  302. data/test/dummy/tmp/cache/assets/DDD/1E0/sprockets%2F951cfc59ce1918fcb37c28fa20e9ebf7 +0 -0
  303. data/test/dummy/tmp/cache/assets/DDE/590/sprockets%2F2e7b6f67b665649ced381dfe37ce2abe +0 -0
  304. data/test/dummy/tmp/cache/assets/DDE/660/sprockets%2Ff64ad0798dfc7f6da9fcd83b53c8c250 +0 -0
  305. data/test/dummy/tmp/cache/assets/DE8/2A0/sprockets%2F37ceb226c01db0bd317e3f3fcfcf1c51 +0 -0
  306. data/test/dummy/tmp/cache/assets/DE8/440/sprockets%2F5559ecfd0ee508d816e4dc889cd8fe3b +0 -0
  307. data/test/dummy/tmp/cache/assets/DEE/730/sprockets%2F8121bbae4961aeba50bdb2cbd939c09f +0 -0
  308. data/test/dummy/tmp/cache/assets/DEF/AB0/sprockets%2Ff8c08dc2009dc1c91a4da29cc852badb +0 -0
  309. data/test/dummy/tmp/cache/assets/DF1/9C0/sprockets%2F7bbd18d10dc4ea3f5d6b137a5b0c9e7b +0 -0
  310. data/test/dummy/tmp/cache/assets/DF8/6B0/sprockets%2F3b2dfa4e62529eeedd6de03ab7b26b19 +0 -0
  311. data/test/dummy/tmp/cache/assets/DFA/CE0/sprockets%2F11f1769f11ddfe50ae1ec399fafa1cf3 +0 -0
  312. data/test/dummy/tmp/cache/assets/DFE/C50/sprockets%2F0af9ec26a81ea5fa1e72f6de4f7a8e03 +0 -0
  313. data/test/dummy/tmp/cache/assets/DFF/900/sprockets%2Fd6d6cf5ff58edce3840dc45621fb1a1d +0 -0
  314. data/test/dummy/tmp/cache/assets/E02/C30/sprockets%2Fecc53a781b3bf1fbcc94fc77c951c5c5 +0 -0
  315. data/test/dummy/tmp/cache/assets/E04/440/sprockets%2F28fe8df46cdf880c8aa0cced70bb7570 +0 -0
  316. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  317. data/test/dummy/tmp/cache/assets/E08/200/sprockets%2Fed91cd00ed3e395eef48f19c62de6e1d +0 -0
  318. data/test/dummy/tmp/cache/assets/E10/340/sprockets%2F7ebd866bfd5a89bfdbf6d928b1d7341d +0 -0
  319. data/test/dummy/tmp/cache/assets/E19/2A0/sprockets%2F10fcfbe6ebae11a40c8eac41939a1b9a +0 -0
  320. data/test/dummy/tmp/cache/assets/E23/A10/sprockets%2F03c4303cddb0cfd8cc9e67aa76c70aee +0 -0
  321. data/test/dummy/tmp/cache/assets/E24/670/sprockets%2Fb857c29efff63c768fbb48ef8e79aae7 +0 -0
  322. data/test/dummy/tmp/cache/assets/E2E/550/sprockets%2Ffb7d8bb50347f4edae6b56ca4bdf07b7 +0 -0
  323. data/test/dummy/tmp/cache/assets/E3B/080/sprockets%2F09e2a090befacdae0db10cafb1893a0a +0 -0
  324. data/test/dummy/tmp/cache/assets/E3E/DE0/sprockets%2Fa977ff5dc4e348f89fe35af4bd2aae3c +0 -0
  325. data/test/dummy/tmp/cache/assets/E45/C30/sprockets%2F69ccc9abc9b338aeee9ee4f1958fb64c +0 -0
  326. data/test/dummy/tmp/cache/assets/E83/1F0/sprockets%2F936cdaaa3e9ff0aafac3bc95ea45a3c6 +0 -0
  327. data/test/dummy/tmp/cache/assets/E85/370/sprockets%2Fca34a37aca7a3f4fe4b2d9ad46ecccc9 +0 -0
  328. data/test/dummy/tmp/cache/assets/E89/CE0/sprockets%2F86a2fd89bf33cbbacf438bb6ef0f3aca +0 -0
  329. data/test/dummy/tmp/cache/assets/F45/590/sprockets%2Fedcf9d1288bc0cfabaccf35fa6ecceca +0 -0
  330. data/test/dummy/tmp/cache/sass/867224f66ea2bfec241b4cee6d1fd9626cb72b7e/scaffolds.css.scssc +0 -0
  331. data/test/dummy/tmp/cache/sass/867224f66ea2bfec241b4cee6d1fd9626cb72b7e/widgets.css.scssc +0 -0
  332. data/test/ensnare_test.rb +7 -0
  333. data/test/fixtures/ensnare/violations.yml +9 -0
  334. data/test/functional/ensnare/dashboard_controller_test.rb +16 -0
  335. data/test/functional/ensnare/violation_controller_test.rb +11 -0
  336. data/test/integration/navigation_test.rb +10 -0
  337. data/test/test_helper.rb +15 -0
  338. data/test/unit/ensnare/violation_test.rb +9 -0
  339. data/test/unit/helpers/ensnare/dashboard_helper_test.rb +6 -0
  340. data/test/unit/helpers/ensnare/violation_helper_test.rb +6 -0
  341. metadata +692 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d1e3115c5a5432afbbc925629012706253bcfc9d
4
+ data.tar.gz: c610f3efc84682a77e9d7bf3a332bda56601ab52
5
+ SHA512:
6
+ metadata.gz: cbd0bed27b880395f1424329493639c0e747ee34ac5f7785dce4abc07ba5fe549b3c931d33ba6590189f3198b21f7e2dc8f103a6aff4aeab489c4edbd3df17a2
7
+ data.tar.gz: bf65c723644c6311cf370e2de5b88da486da76b776e44422b96db685bdec8537de0e0f6f1a18e7efb4efeb8c2fce71a4608ed91920481f72f77e20d7efb481ea
data/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Copyright (c) 2014, Andy Hoernecke and Scott Behrens
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ Ensnare
2
+ =======
3
+ Ensnare is packaged as a gem plugin for Ruby on Rails and was developed to allow configuring and deploying a basic malicious behavior detection and response scheme in less than ten minutes.
4
+
5
+ Ensnare uses a combination of [Honey Traps](https://github.com/ahoernecke/Ensnare/wiki#honey-traps) to entice malicious users, and a configurable suite of [Trap Responses](https://github.com/ahoernecke/Ensnare/wiki#response-types) to confuse, allude, delay, or stop an attacker.
6
+
7
+ Already heard about the tool and want to try it out? Do it!
8
+
9
+ #Install#
10
+
11
+ Add the gem to your project's Gemfile:
12
+ ```ruby
13
+ gem 'ensnare', :git => 'git@github.com:ahoernecke/Ensnare.git'
14
+ ```
15
+ Install the gem:
16
+ ```shell
17
+ bundle install
18
+ ```
19
+ Run the migrations for Ensnare:
20
+ ```shell
21
+ rake ensnare:install:migrations
22
+ rake db:migrate
23
+ ```
24
+ Enable parameter tampering for your application by changing the mass_assignment_sanitizer:
25
+ ```shell
26
+ vi config/environments/<ENVIRONMENT>.rb
27
+ ```
28
+ Set config.active_record.mass_assignment_sanitizer to logger:
29
+ ```ruby
30
+ config.active_record.mass_assignment_sanitizer = :logger
31
+ ```
32
+ Enable Ensnare in your application_controller.rb file:
33
+ ```shell
34
+ vi app/controllers/application_controller.rb
35
+ ```
36
+ Append the following filter below *protect_from_forgery* in your application_controller.rb file:
37
+ ```ruby
38
+ before_filter :ensnare
39
+ ```
40
+ Add the following to the end of your routes.rb file:
41
+ ```ruby
42
+ mount Ensnare::Engine => "/ensnare", :as => "ensnare_engine"
43
+ match "*_", :to => "ensnare::violations#routing_error"
44
+ ```
45
+ Create an Ensnare config file:
46
+ ```shell
47
+ rails g ensnare:install
48
+ ```
49
+ Take a look at the example ensnare.rb file:
50
+ ```shell
51
+ vi config/initializes/ensanre.rb
52
+ ```
53
+ After you start your application, take a look at the dashboard:
54
+
55
+ http://your-application.com/ensnare/dashboard
56
+
57
+ **Optional**
58
+
59
+ To prevent unnecessary users from accessing the dashboard, add the following to the `config/initalizers/ensanre.rb` file:
60
+ ```ruby
61
+ config.dashboard_user_method = :current_user
62
+ config.dashboard_authorization_method = :admin?
63
+ ```
64
+ *NOTE:* you need to have a method defined to check if the user is the admin.
65
+
66
+ #Bugs#
67
+
68
+ Issue with Bootstrap and Dashboard (stylesheet mismatch in firefox).
69
+
70
+ #Resources#
71
+
72
+ http://books.google.com/books?id=flC9dFFLWIsC&pg=PT111&lpg=PT111&dq=honey+trap+mod+security&source=bl&ots=zKxJvehMpA&sig=E9qKn7L4siEk01caEF6wqofbbm8&hl=en&sa=X&ei=_iRUUoCRJKPiiwK8y4HIBA&ved=0CFUQ6AEwBg#v=onepage&q=honey trap mod security&f=false
73
+
74
+ ##Contact##
75
+ Created by [Andy Hoernecke](https://github.com/ahoernecke) and [Scott Behrens](https://github.com/sbehrens).
76
+
77
+ Feel free to reach out to us if you have questions or want to contribute to the project!
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Ensnare'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,10 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require twitter/bootstrap
10
+ //= require_tree .
@@ -0,0 +1,474 @@
1
+ /*!
2
+ * ZeroClipboard
3
+ * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
4
+ * Copyright (c) 2013 Jon Rohan, James M. Greene
5
+ * Licensed MIT
6
+ * http://zeroclipboard.org/
7
+ * v1.2.3
8
+ */
9
+ (function() {
10
+ "use strict";
11
+ var _camelizeCssPropName = function() {
12
+ var matcherRegex = /\-([a-z])/g, replacerFn = function(match, group) {
13
+ return group.toUpperCase();
14
+ };
15
+ return function(prop) {
16
+ return prop.replace(matcherRegex, replacerFn);
17
+ };
18
+ }();
19
+ var _getStyle = function(el, prop) {
20
+ var value, camelProp, tagName, possiblePointers, i, len;
21
+ if (window.getComputedStyle) {
22
+ value = window.getComputedStyle(el, null).getPropertyValue(prop);
23
+ } else {
24
+ camelProp = _camelizeCssPropName(prop);
25
+ if (el.currentStyle) {
26
+ value = el.currentStyle[camelProp];
27
+ } else {
28
+ value = el.style[camelProp];
29
+ }
30
+ }
31
+ if (prop === "cursor") {
32
+ if (!value || value === "auto") {
33
+ tagName = el.tagName.toLowerCase();
34
+ possiblePointers = [ "a" ];
35
+ for (i = 0, len = possiblePointers.length; i < len; i++) {
36
+ if (tagName === possiblePointers[i]) {
37
+ return "pointer";
38
+ }
39
+ }
40
+ }
41
+ }
42
+ return value;
43
+ };
44
+ var _elementMouseOver = function(event) {
45
+ if (!ZeroClipboard.prototype._singleton) return;
46
+ if (!event) {
47
+ event = window.event;
48
+ }
49
+ var target;
50
+ if (this !== window) {
51
+ target = this;
52
+ } else if (event.target) {
53
+ target = event.target;
54
+ } else if (event.srcElement) {
55
+ target = event.srcElement;
56
+ }
57
+ ZeroClipboard.prototype._singleton.setCurrent(target);
58
+ };
59
+ var _addEventHandler = function(element, method, func) {
60
+ if (element.addEventListener) {
61
+ element.addEventListener(method, func, false);
62
+ } else if (element.attachEvent) {
63
+ element.attachEvent("on" + method, func);
64
+ }
65
+ };
66
+ var _removeEventHandler = function(element, method, func) {
67
+ if (element.removeEventListener) {
68
+ element.removeEventListener(method, func, false);
69
+ } else if (element.detachEvent) {
70
+ element.detachEvent("on" + method, func);
71
+ }
72
+ };
73
+ var _addClass = function(element, value) {
74
+ if (element.addClass) {
75
+ element.addClass(value);
76
+ return element;
77
+ }
78
+ if (value && typeof value === "string") {
79
+ var classNames = (value || "").split(/\s+/);
80
+ if (element.nodeType === 1) {
81
+ if (!element.className) {
82
+ element.className = value;
83
+ } else {
84
+ var className = " " + element.className + " ", setClass = element.className;
85
+ for (var c = 0, cl = classNames.length; c < cl; c++) {
86
+ if (className.indexOf(" " + classNames[c] + " ") < 0) {
87
+ setClass += " " + classNames[c];
88
+ }
89
+ }
90
+ element.className = setClass.replace(/^\s+|\s+$/g, "");
91
+ }
92
+ }
93
+ }
94
+ return element;
95
+ };
96
+ var _removeClass = function(element, value) {
97
+ if (element.removeClass) {
98
+ element.removeClass(value);
99
+ return element;
100
+ }
101
+ if (value && typeof value === "string" || value === undefined) {
102
+ var classNames = (value || "").split(/\s+/);
103
+ if (element.nodeType === 1 && element.className) {
104
+ if (value) {
105
+ var className = (" " + element.className + " ").replace(/[\n\t]/g, " ");
106
+ for (var c = 0, cl = classNames.length; c < cl; c++) {
107
+ className = className.replace(" " + classNames[c] + " ", " ");
108
+ }
109
+ element.className = className.replace(/^\s+|\s+$/g, "");
110
+ } else {
111
+ element.className = "";
112
+ }
113
+ }
114
+ }
115
+ return element;
116
+ };
117
+ var _getZoomFactor = function() {
118
+ var rect, physicalWidth, logicalWidth, zoomFactor = 1;
119
+ if (typeof document.body.getBoundingClientRect === "function") {
120
+ rect = document.body.getBoundingClientRect();
121
+ physicalWidth = rect.right - rect.left;
122
+ logicalWidth = document.body.offsetWidth;
123
+ zoomFactor = Math.round(physicalWidth / logicalWidth * 100) / 100;
124
+ }
125
+ return zoomFactor;
126
+ };
127
+ var _getDOMObjectPosition = function(obj) {
128
+ var info = {
129
+ left: 0,
130
+ top: 0,
131
+ width: 0,
132
+ height: 0,
133
+ zIndex: 999999999
134
+ };
135
+ var zi = _getStyle(obj, "z-index");
136
+ if (zi && zi !== "auto") {
137
+ info.zIndex = parseInt(zi, 10);
138
+ }
139
+ if (obj.getBoundingClientRect) {
140
+ var rect = obj.getBoundingClientRect();
141
+ var pageXOffset, pageYOffset, zoomFactor;
142
+ if ("pageXOffset" in window && "pageYOffset" in window) {
143
+ pageXOffset = window.pageXOffset;
144
+ pageYOffset = window.pageYOffset;
145
+ } else {
146
+ zoomFactor = _getZoomFactor();
147
+ pageXOffset = Math.round(document.documentElement.scrollLeft / zoomFactor);
148
+ pageYOffset = Math.round(document.documentElement.scrollTop / zoomFactor);
149
+ }
150
+ var leftBorderWidth = document.documentElement.clientLeft || 0;
151
+ var topBorderWidth = document.documentElement.clientTop || 0;
152
+ info.left = rect.left + pageXOffset - leftBorderWidth;
153
+ info.top = rect.top + pageYOffset - topBorderWidth;
154
+ info.width = "width" in rect ? rect.width : rect.right - rect.left;
155
+ info.height = "height" in rect ? rect.height : rect.bottom - rect.top;
156
+ }
157
+ return info;
158
+ };
159
+ var _noCache = function(path, options) {
160
+ var useNoCache = !(options && options.useNoCache === false);
161
+ if (useNoCache) {
162
+ return (path.indexOf("?") === -1 ? "?" : "&") + "nocache=" + new Date().getTime();
163
+ } else {
164
+ return "";
165
+ }
166
+ };
167
+ var _vars = function(options) {
168
+ var str = [];
169
+ var origins = [];
170
+ if (options.trustedOrigins) {
171
+ if (typeof options.trustedOrigins === "string") {
172
+ origins.push(options.trustedOrigins);
173
+ } else if (typeof options.trustedOrigins === "object" && "length" in options.trustedOrigins) {
174
+ origins = origins.concat(options.trustedOrigins);
175
+ }
176
+ }
177
+ if (options.trustedDomains) {
178
+ if (typeof options.trustedDomains === "string") {
179
+ origins.push(options.trustedDomains);
180
+ } else if (typeof options.trustedDomains === "object" && "length" in options.trustedDomains) {
181
+ origins = origins.concat(options.trustedDomains);
182
+ }
183
+ }
184
+ if (origins.length) {
185
+ str.push("trustedOrigins=" + encodeURIComponent(origins.join(",")));
186
+ }
187
+ if (typeof options.amdModuleId === "string" && options.amdModuleId) {
188
+ str.push("amdModuleId=" + encodeURIComponent(options.amdModuleId));
189
+ }
190
+ if (typeof options.cjsModuleId === "string" && options.cjsModuleId) {
191
+ str.push("cjsModuleId=" + encodeURIComponent(options.cjsModuleId));
192
+ }
193
+ return str.join("&");
194
+ };
195
+ var _inArray = function(elem, array) {
196
+ if (array.indexOf) {
197
+ return array.indexOf(elem);
198
+ }
199
+ for (var i = 0, length = array.length; i < length; i++) {
200
+ if (array[i] === elem) {
201
+ return i;
202
+ }
203
+ }
204
+ return -1;
205
+ };
206
+ var _prepGlue = function(elements) {
207
+ if (typeof elements === "string") throw new TypeError("ZeroClipboard doesn't accept query strings.");
208
+ if (!elements.length) return [ elements ];
209
+ return elements;
210
+ };
211
+ var _dispatchCallback = function(func, element, instance, args, async) {
212
+ if (async) {
213
+ window.setTimeout(function() {
214
+ func.call(element, instance, args);
215
+ }, 0);
216
+ } else {
217
+ func.call(element, instance, args);
218
+ }
219
+ };
220
+ var ZeroClipboard = function(elements, options) {
221
+ if (elements) (ZeroClipboard.prototype._singleton || this).glue(elements);
222
+ if (ZeroClipboard.prototype._singleton) return ZeroClipboard.prototype._singleton;
223
+ ZeroClipboard.prototype._singleton = this;
224
+ this.options = {};
225
+ for (var kd in _defaults) this.options[kd] = _defaults[kd];
226
+ for (var ko in options) this.options[ko] = options[ko];
227
+ this.handlers = {};
228
+ if (ZeroClipboard.detectFlashSupport()) _bridge();
229
+ };
230
+ var currentElement, gluedElements = [];
231
+ ZeroClipboard.prototype.setCurrent = function(element) {
232
+ currentElement = element;
233
+ this.reposition();
234
+ var titleAttr = element.getAttribute("title");
235
+ if (titleAttr) {
236
+ this.setTitle(titleAttr);
237
+ }
238
+ var useHandCursor = this.options.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
239
+ _setHandCursor.call(this, useHandCursor);
240
+ return this;
241
+ };
242
+ ZeroClipboard.prototype.setText = function(newText) {
243
+ if (newText && newText !== "") {
244
+ this.options.text = newText;
245
+ if (this.ready()) this.flashBridge.setText(newText);
246
+ }
247
+ return this;
248
+ };
249
+ ZeroClipboard.prototype.setTitle = function(newTitle) {
250
+ if (newTitle && newTitle !== "") this.htmlBridge.setAttribute("title", newTitle);
251
+ return this;
252
+ };
253
+ ZeroClipboard.prototype.setSize = function(width, height) {
254
+ if (this.ready()) this.flashBridge.setSize(width, height);
255
+ return this;
256
+ };
257
+ ZeroClipboard.prototype.setHandCursor = function(enabled) {
258
+ enabled = typeof enabled === "boolean" ? enabled : !!enabled;
259
+ _setHandCursor.call(this, enabled);
260
+ this.options.forceHandCursor = enabled;
261
+ return this;
262
+ };
263
+ var _setHandCursor = function(enabled) {
264
+ if (this.ready()) this.flashBridge.setHandCursor(enabled);
265
+ };
266
+ ZeroClipboard.version = "1.2.3";
267
+ var _defaults = {
268
+ moviePath: "ZeroClipboard.swf",
269
+ trustedOrigins: null,
270
+ text: null,
271
+ hoverClass: "zeroclipboard-is-hover",
272
+ activeClass: "zeroclipboard-is-active",
273
+ allowScriptAccess: "sameDomain",
274
+ useNoCache: true,
275
+ forceHandCursor: false
276
+ };
277
+ ZeroClipboard.setDefaults = function(options) {
278
+ for (var ko in options) _defaults[ko] = options[ko];
279
+ };
280
+ ZeroClipboard.destroy = function() {
281
+ ZeroClipboard.prototype._singleton.unglue(gluedElements);
282
+ var bridge = ZeroClipboard.prototype._singleton.htmlBridge;
283
+ bridge.parentNode.removeChild(bridge);
284
+ delete ZeroClipboard.prototype._singleton;
285
+ };
286
+ ZeroClipboard.detectFlashSupport = function() {
287
+ var hasFlash = false;
288
+ if (typeof ActiveXObject === "function") {
289
+ try {
290
+ if (new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) {
291
+ hasFlash = true;
292
+ }
293
+ } catch (error) {}
294
+ }
295
+ if (!hasFlash && navigator.mimeTypes["application/x-shockwave-flash"]) {
296
+ hasFlash = true;
297
+ }
298
+ return hasFlash;
299
+ };
300
+ var _amdModuleId = null;
301
+ var _cjsModuleId = null;
302
+ var _bridge = function() {
303
+ var flashBridge, len;
304
+ var client = ZeroClipboard.prototype._singleton;
305
+ var container = document.getElementById("global-zeroclipboard-html-bridge");
306
+ if (!container) {
307
+ var opts = {};
308
+ for (var ko in client.options) opts[ko] = client.options[ko];
309
+ opts.amdModuleId = _amdModuleId;
310
+ opts.cjsModuleId = _cjsModuleId;
311
+ var flashvars = _vars(opts);
312
+ var html = ' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="' + client.options.moviePath + _noCache(client.options.moviePath, client.options) + '"/> <param name="allowScriptAccess" value="' + client.options.allowScriptAccess + '"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="' + flashvars + '"/> <embed src="' + client.options.moviePath + _noCache(client.options.moviePath, client.options) + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + flashvars + '" scale="exactfit"> </embed> </object>';
313
+ container = document.createElement("div");
314
+ container.id = "global-zeroclipboard-html-bridge";
315
+ container.setAttribute("class", "global-zeroclipboard-container");
316
+ container.setAttribute("data-clipboard-ready", false);
317
+ container.style.position = "absolute";
318
+ container.style.left = "-9999px";
319
+ container.style.top = "-9999px";
320
+ container.style.width = "15px";
321
+ container.style.height = "15px";
322
+ container.style.zIndex = "9999";
323
+ container.innerHTML = html;
324
+ document.body.appendChild(container);
325
+ }
326
+ client.htmlBridge = container;
327
+ flashBridge = document["global-zeroclipboard-flash-bridge"];
328
+ if (flashBridge && (len = flashBridge.length)) {
329
+ flashBridge = flashBridge[len - 1];
330
+ }
331
+ client.flashBridge = flashBridge || container.children[0].lastElementChild;
332
+ };
333
+ ZeroClipboard.prototype.resetBridge = function() {
334
+ this.htmlBridge.style.left = "-9999px";
335
+ this.htmlBridge.style.top = "-9999px";
336
+ this.htmlBridge.removeAttribute("title");
337
+ this.htmlBridge.removeAttribute("data-clipboard-text");
338
+ _removeClass(currentElement, this.options.activeClass);
339
+ currentElement = null;
340
+ this.options.text = null;
341
+ return this;
342
+ };
343
+ ZeroClipboard.prototype.ready = function() {
344
+ var ready = this.htmlBridge.getAttribute("data-clipboard-ready");
345
+ return ready === "true" || ready === true;
346
+ };
347
+ ZeroClipboard.prototype.reposition = function() {
348
+ if (!currentElement) return false;
349
+ var pos = _getDOMObjectPosition(currentElement);
350
+ this.htmlBridge.style.top = pos.top + "px";
351
+ this.htmlBridge.style.left = pos.left + "px";
352
+ this.htmlBridge.style.width = pos.width + "px";
353
+ this.htmlBridge.style.height = pos.height + "px";
354
+ this.htmlBridge.style.zIndex = pos.zIndex + 1;
355
+ this.setSize(pos.width, pos.height);
356
+ return this;
357
+ };
358
+ ZeroClipboard.dispatch = function(eventName, args) {
359
+ ZeroClipboard.prototype._singleton.receiveEvent(eventName, args);
360
+ };
361
+ ZeroClipboard.prototype.on = function(eventName, func) {
362
+ var events = eventName.toString().split(/\s/g);
363
+ for (var i = 0; i < events.length; i++) {
364
+ eventName = events[i].toLowerCase().replace(/^on/, "");
365
+ if (!this.handlers[eventName]) this.handlers[eventName] = func;
366
+ }
367
+ if (this.handlers.noflash && !ZeroClipboard.detectFlashSupport()) {
368
+ this.receiveEvent("onNoFlash", null);
369
+ }
370
+ return this;
371
+ };
372
+ ZeroClipboard.prototype.addEventListener = ZeroClipboard.prototype.on;
373
+ ZeroClipboard.prototype.off = function(eventName, func) {
374
+ var events = eventName.toString().split(/\s/g);
375
+ for (var i = 0; i < events.length; i++) {
376
+ eventName = events[i].toLowerCase().replace(/^on/, "");
377
+ for (var event in this.handlers) {
378
+ if (event === eventName && this.handlers[event] === func) {
379
+ delete this.handlers[event];
380
+ }
381
+ }
382
+ }
383
+ return this;
384
+ };
385
+ ZeroClipboard.prototype.removeEventListener = ZeroClipboard.prototype.off;
386
+ ZeroClipboard.prototype.receiveEvent = function(eventName, args) {
387
+ eventName = eventName.toString().toLowerCase().replace(/^on/, "");
388
+ var element = currentElement;
389
+ var performCallbackAsync = true;
390
+ switch (eventName) {
391
+ case "load":
392
+ if (args && parseFloat(args.flashVersion.replace(",", ".").replace(/[^0-9\.]/gi, "")) < 10) {
393
+ this.receiveEvent("onWrongFlash", {
394
+ flashVersion: args.flashVersion
395
+ });
396
+ return;
397
+ }
398
+ this.htmlBridge.setAttribute("data-clipboard-ready", true);
399
+ break;
400
+
401
+ case "mouseover":
402
+ _addClass(element, this.options.hoverClass);
403
+ break;
404
+
405
+ case "mouseout":
406
+ _removeClass(element, this.options.hoverClass);
407
+ this.resetBridge();
408
+ break;
409
+
410
+ case "mousedown":
411
+ _addClass(element, this.options.activeClass);
412
+ break;
413
+
414
+ case "mouseup":
415
+ _removeClass(element, this.options.activeClass);
416
+ break;
417
+
418
+ case "datarequested":
419
+ var targetId = element.getAttribute("data-clipboard-target"), targetEl = !targetId ? null : document.getElementById(targetId);
420
+ if (targetEl) {
421
+ var textContent = targetEl.value || targetEl.textContent || targetEl.innerText;
422
+ if (textContent) this.setText(textContent);
423
+ } else {
424
+ var defaultText = element.getAttribute("data-clipboard-text");
425
+ if (defaultText) this.setText(defaultText);
426
+ }
427
+ performCallbackAsync = false;
428
+ break;
429
+
430
+ case "complete":
431
+ this.options.text = null;
432
+ break;
433
+ }
434
+ if (this.handlers[eventName]) {
435
+ var func = this.handlers[eventName];
436
+ if (typeof func === "string" && typeof window[func] === "function") {
437
+ func = window[func];
438
+ }
439
+ if (typeof func === "function") {
440
+ _dispatchCallback(func, element, this, args, performCallbackAsync);
441
+ }
442
+ }
443
+ };
444
+ ZeroClipboard.prototype.glue = function(elements) {
445
+ elements = _prepGlue(elements);
446
+ for (var i = 0; i < elements.length; i++) {
447
+ if (_inArray(elements[i], gluedElements) == -1) {
448
+ gluedElements.push(elements[i]);
449
+ _addEventHandler(elements[i], "mouseover", _elementMouseOver);
450
+ }
451
+ }
452
+ return this;
453
+ };
454
+ ZeroClipboard.prototype.unglue = function(elements) {
455
+ elements = _prepGlue(elements);
456
+ for (var i = 0; i < elements.length; i++) {
457
+ _removeEventHandler(elements[i], "mouseover", _elementMouseOver);
458
+ var arrayIndex = _inArray(elements[i], gluedElements);
459
+ if (arrayIndex != -1) gluedElements.splice(arrayIndex, 1);
460
+ }
461
+ return this;
462
+ };
463
+ if (typeof define === "function" && define.amd) {
464
+ define([ "require", "exports", "module" ], function(require, exports, module) {
465
+ _amdModuleId = module && module.id || null;
466
+ return ZeroClipboard;
467
+ });
468
+ } else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports) {
469
+ _cjsModuleId = module.id || null;
470
+ module.exports = ZeroClipboard;
471
+ } else {
472
+ window.ZeroClipboard = ZeroClipboard;
473
+ }
474
+ })();