ensnare 0.1beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +10 -0
- data/README.md +77 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/application.js +10 -0
- data/app/assets/javascripts/ensnare/ZeroClipboard.js +474 -0
- data/app/assets/javascripts/ensnare/ZeroClipboard.min.js +9 -0
- data/app/assets/javascripts/ensnare/ZeroClipboard.swf +0 -0
- data/app/assets/javascripts/ensnare/application.js +20 -0
- data/app/assets/javascripts/ensnare/bootstrap-switch.js +382 -0
- data/app/assets/javascripts/ensnare/bootstrap_and_overrides.js +4 -0
- data/app/assets/javascripts/ensnare/clippy.js +18 -0
- data/app/assets/javascripts/ensnare/config_switch.js +19 -0
- data/app/assets/javascripts/ensnare/on_handler.js +9 -0
- data/app/assets/stylesheets/application.css +7 -0
- data/app/assets/stylesheets/bootstrap_and_overrides.css.less +30 -0
- data/app/assets/stylesheets/ensnare/application.css +13 -0
- data/app/assets/stylesheets/ensnare/bootstrap-switch.css +408 -0
- data/app/assets/stylesheets/ensnare/bootstrap_and_overrides.css +7 -0
- data/app/assets/stylesheets/ensnare/dashboard.css +4 -0
- data/app/assets/stylesheets/ensnare/toggle-switch.css +310 -0
- data/app/assets/stylesheets/ensnare/violation.css +4 -0
- data/app/controllers/ensnare/application_controller.rb +22 -0
- data/app/controllers/ensnare/configuration_controller.rb +15 -0
- data/app/controllers/ensnare/dashboard_controller.rb +32 -0
- data/app/controllers/ensnare/violations_controller.rb +36 -0
- data/app/helpers/ensnare/application_helper.rb +4 -0
- data/app/helpers/ensnare/dashboard_helper.rb +6 -0
- data/app/helpers/ensnare/violation_helper.rb +4 -0
- data/app/models/ensnare/violation.rb +6 -0
- data/app/views/ensnare/dashboard/configs.html.erb +1191 -0
- data/app/views/ensnare/dashboard/edit.html.erb +2 -0
- data/app/views/ensnare/dashboard/metrics.html.erb +38 -0
- data/app/views/ensnare/dashboard/metrics/_table.html.erb +17 -0
- data/app/views/ensnare/dashboard/mode.html.erb +75 -0
- data/app/views/ensnare/dashboard/violations.html.erb +32 -0
- data/app/views/ensnare/violations/captcha.html.erb +11 -0
- data/app/views/ensnare/violations/redirect.html.erb +2 -0
- data/app/views/ensnare/violations/show.html.erb +2 -0
- data/app/views/layouts/ensnare/application.html.erb +77 -0
- data/app/views/layouts/ensnare/captcha.html.erb +51 -0
- data/config/locales/en.bootstrap.yml +18 -0
- data/config/routes.rb +14 -0
- data/db/migrate/20131007205246_create_ensnare_violations.rb +10 -0
- data/db/migrate/20131007210137_rename_violation_type_field.rb +6 -0
- data/db/migrate/20131029010445_add_fields_to_violation.rb +8 -0
- data/db/migrate/20131031001835_add_name_to_ensnare_violation.rb +5 -0
- data/db/migrate/20131121163305_add_weight_to_violations.rb +5 -0
- data/lib/ensnare.rb +306 -0
- data/lib/ensnare/controllers/helpers.rb +143 -0
- data/lib/ensnare/engine.rb +30 -0
- data/lib/ensnare/form_tag_helper.rb +116 -0
- data/lib/ensnare/responses/block.rb +8 -0
- data/lib/ensnare/responses/captcha.rb +20 -0
- data/lib/ensnare/responses/flash_error.rb +11 -0
- data/lib/ensnare/responses/none.rb +10 -0
- data/lib/ensnare/responses/not_found.rb +9 -0
- data/lib/ensnare/responses/random_content.rb +11 -0
- data/lib/ensnare/responses/redirect.rb +8 -0
- data/lib/ensnare/responses/redirect_loop.rb +10 -0
- data/lib/ensnare/responses/response.rb +19 -0
- data/lib/ensnare/responses/server_error.rb +8 -0
- data/lib/ensnare/responses/throttle.rb +8 -0
- data/lib/ensnare/traps/cookie.rb +98 -0
- data/lib/ensnare/traps/parameter.rb +88 -0
- data/lib/ensnare/traps/reg_ex.rb +26 -0
- data/lib/ensnare/traps/routing_error.rb +25 -0
- data/lib/ensnare/traps/trap.rb +36 -0
- data/lib/ensnare/version.rb +3 -0
- data/lib/generators/ensnare/install_generator.rb +12 -0
- data/lib/generators/templates/ensnare.rb +44 -0
- data/lib/tasks/ensnare_tasks.rb +4 -0
- data/test/dummy/Gemfile +46 -0
- data/test/dummy/Gemfile.lock +149 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/images/rails.png +0 -0
- data/test/dummy/app/assets/javascripts/application.js +16 -0
- data/test/dummy/app/assets/javascripts/bootstrap.js +4 -0
- data/test/dummy/app/assets/javascripts/bootstrap.js.coffee +3 -0
- data/test/dummy/app/assets/javascripts/widgets.js.coffee +3 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/bootstrap_and_overrides.css +7 -0
- data/test/dummy/app/assets/stylesheets/scaffolds.css.scss +69 -0
- data/test/dummy/app/assets/stylesheets/widgets.css.scss +3 -0
- data/test/dummy/app/controllers/application_controller.rb +12 -0
- data/test/dummy/app/controllers/widgets_controller.rb +94 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/widgets_helper.rb +2 -0
- data/test/dummy/app/models/user.rb +15 -0
- data/test/dummy/app/models/widget.rb +4 -0
- data/test/dummy/app/views/layouts/application.html.erb +108 -0
- data/test/dummy/app/views/widgets/_form.html.erb +25 -0
- data/test/dummy/app/views/widgets/edit.html.erb +6 -0
- data/test/dummy/app/views/widgets/index.html.erb +25 -0
- data/test/dummy/app/views/widgets/new.html.erb +5 -0
- data/test/dummy/app/views/widgets/show.html.erb +15 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +65 -0
- data/test/dummy/config/boot.rb +6 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/captcha.rb +5 -0
- data/test/dummy/config/initializers/devise.rb +258 -0
- data/test/dummy/config/initializers/ensnare.rb +272 -0
- data/test/dummy/config/initializers/ensnare.sample +323 -0
- data/test/dummy/config/initializers/examples.example +323 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/quiet_assets.rb +13 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/devise.en.yml +60 -0
- data/test/dummy/config/locales/en.bootstrap.yml +18 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +68 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20131007193540_create_widgets.rb +10 -0
- data/test/dummy/db/migrate/20131031153254_devise_create_users.rb +42 -0
- data/test/dummy/db/migrate/20140405051634_create_ensnare_violations.ensnare.rb +11 -0
- data/test/dummy/db/migrate/20140405051635_rename_violation_type_field.ensnare.rb +7 -0
- data/test/dummy/db/migrate/20140405051636_add_fields_to_violation.ensnare.rb +9 -0
- data/test/dummy/db/migrate/20140405051637_add_name_to_ensnare_violation.ensnare.rb +6 -0
- data/test/dummy/db/migrate/20140405051638_add_weight_to_violations.ensnare.rb +6 -0
- data/test/dummy/db/schema.rb +54 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/doc/README_FOR_APP +2 -0
- data/test/dummy/lib/ensnare/responses/custom.rb_sample +11 -0
- data/test/dummy/lib/ensnare/traps/custom.rb_sample +26 -0
- data/test/dummy/log/development.log +92903 -0
- data/test/dummy/log/production.log +158 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/users.yml +11 -0
- data/test/dummy/test/fixtures/widgets.yml +9 -0
- data/test/dummy/test/functional/widgets_controller_test.rb +49 -0
- data/test/dummy/test/performance/browsing_test.rb +12 -0
- data/test/dummy/test/test_helper.rb +13 -0
- data/test/dummy/test/unit/helpers/widgets_helper_test.rb +4 -0
- data/test/dummy/test/unit/user_test.rb +7 -0
- data/test/dummy/test/unit/widget_test.rb +7 -0
- data/test/dummy/tmp/cache/assets/C10/FA0/sprockets%2F269fa26485a91206814a45af06210315 +0 -0
- data/test/dummy/tmp/cache/assets/C23/310/sprockets%2Fc79437284218b38e613366d14284ac07 +0 -0
- data/test/dummy/tmp/cache/assets/C40/710/sprockets%2F545779172fbf9cf79082774a07841659 +0 -0
- data/test/dummy/tmp/cache/assets/C48/0D0/sprockets%2F75b535a43e06025546821f95d011d85b +0 -0
- data/test/dummy/tmp/cache/assets/C4E/110/sprockets%2Fb806449c86337e3e06070c462280e90b +0 -0
- data/test/dummy/tmp/cache/assets/C57/BD0/sprockets%2Facd987410b744152d157762609194e8c +0 -0
- data/test/dummy/tmp/cache/assets/C5D/9E0/sprockets%2F0d79b66115628050357f99d36aa4876d +0 -0
- data/test/dummy/tmp/cache/assets/C80/840/sprockets%2F562c2d168da585f80579347d10790a0a +0 -0
- data/test/dummy/tmp/cache/assets/C84/DD0/sprockets%2F3e508585142de6585818df6a2290bf11 +0 -0
- data/test/dummy/tmp/cache/assets/C85/E00/sprockets%2Fcbe2d565923657893e41f9160d30e540 +0 -0
- data/test/dummy/tmp/cache/assets/C88/BC0/sprockets%2F341dd4748a8a73570a59264e9f9540b2 +0 -0
- data/test/dummy/tmp/cache/assets/C8D/F80/sprockets%2F81e191073a2f74b9eca460537339789f +0 -0
- data/test/dummy/tmp/cache/assets/C98/B10/sprockets%2F94976d41a9fc1279e0cd996c78087410 +0 -0
- data/test/dummy/tmp/cache/assets/C9F/190/sprockets%2Fb8f3f499dc494543381d55292e346e99 +0 -0
- data/test/dummy/tmp/cache/assets/CA4/1A0/sprockets%2F629131c0f22f0d55ed1725737a343bd7 +0 -0
- data/test/dummy/tmp/cache/assets/CAD/EB0/sprockets%2F481955f78ac093b746e0512b4a9c1b24 +0 -0
- data/test/dummy/tmp/cache/assets/CB0/8D0/sprockets%2Fba6342b6172d4ee18e951f667e237313 +0 -0
- data/test/dummy/tmp/cache/assets/CB4/DC0/sprockets%2F48af5bbf36e6f2720f4144f928129612 +0 -0
- data/test/dummy/tmp/cache/assets/CB7/5B0/sprockets%2F67a1cdb0edc3998371d944050583e358 +0 -0
- data/test/dummy/tmp/cache/assets/CB8/F00/sprockets%2F089f52a057d7a14247c7f93e8b59143b +0 -0
- data/test/dummy/tmp/cache/assets/CBD/0E0/sprockets%2F662f42b5efa6584377436f1d94318cd4 +0 -0
- data/test/dummy/tmp/cache/assets/CBF/4D0/sprockets%2F1462d4ee75c877880447a02b2f58e6b9 +0 -0
- data/test/dummy/tmp/cache/assets/CC3/220/sprockets%2F218c30380a6f2bae6b7402068da50f01 +0 -0
- data/test/dummy/tmp/cache/assets/CC7/200/sprockets%2F5366d8fff996ca22271713d1ca987379 +0 -0
- data/test/dummy/tmp/cache/assets/CCE/810/sprockets%2F90453c5b48e1f0a4f1a6836135c1c4b1 +0 -0
- data/test/dummy/tmp/cache/assets/CD4/E90/sprockets%2F5464e430cbb52421e1f9c23947fe31c1 +0 -0
- data/test/dummy/tmp/cache/assets/CD5/2C0/sprockets%2F166c056119ebdfb8b7104c97b424b423 +0 -0
- data/test/dummy/tmp/cache/assets/CD7/6F0/sprockets%2Fbd3936370d0f952ada5774e2230046ed +0 -0
- data/test/dummy/tmp/cache/assets/CD7/C90/sprockets%2F5382f60c349e1511eefc83803fa450c1 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CDC/5C0/sprockets%2F9767868b3b77f9164f290797f1d8fe5c +0 -0
- data/test/dummy/tmp/cache/assets/CDE/570/sprockets%2F0e30065c6148a1ef8d5e42439e148f4d +0 -0
- data/test/dummy/tmp/cache/assets/CE0/CC0/sprockets%2F2b38c3fb549036de5c4666637a0c80c6 +0 -0
- data/test/dummy/tmp/cache/assets/CE0/F80/sprockets%2F487624acd392c0310f0c7434e88d48bf +0 -0
- data/test/dummy/tmp/cache/assets/CE4/570/sprockets%2F306a61edb38d739bb2f81b448b376818 +0 -0
- data/test/dummy/tmp/cache/assets/CE5/C70/sprockets%2F681ae890ae2f44aee1099119d04a7938 +0 -0
- data/test/dummy/tmp/cache/assets/CE5/CE0/sprockets%2F9d186abc5f6a106511502d60d98ff939 +0 -0
- data/test/dummy/tmp/cache/assets/CE6/B90/sprockets%2F5997a940521ec92b2ea92eb63c49a562 +0 -0
- data/test/dummy/tmp/cache/assets/CE6/DE0/sprockets%2F9889a2fbf25b223583561299dfca004e +0 -0
- data/test/dummy/tmp/cache/assets/CE7/6F0/sprockets%2F6ac42c22840f7d853b6184b6f94a65c8 +0 -0
- data/test/dummy/tmp/cache/assets/CE7/E70/sprockets%2F704fcbd6f72c99767550538053a0bc7d +0 -0
- data/test/dummy/tmp/cache/assets/CE8/6E0/sprockets%2F51f80f23e41678e790edd8710c6d75c0 +0 -0
- data/test/dummy/tmp/cache/assets/CE9/510/sprockets%2F0c8887733a9e311fd348f21029d6bef6 +0 -0
- data/test/dummy/tmp/cache/assets/CEA/BA0/sprockets%2F98e291b46a924814292e2daf17ad8c84 +0 -0
- data/test/dummy/tmp/cache/assets/CF4/140/sprockets%2F22a3157d204c1f8e417a25f01a2dbe45 +0 -0
- data/test/dummy/tmp/cache/assets/CF6/EE0/sprockets%2F9e92e631fb88a8e23180da66c77859f0 +0 -0
- data/test/dummy/tmp/cache/assets/CF7/8B0/sprockets%2F0f091833381aa52e100fb74924fdc1aa +0 -0
- data/test/dummy/tmp/cache/assets/CF9/AF0/sprockets%2Fe6cf7ff483a7c68902418a2f4b374889 +0 -0
- data/test/dummy/tmp/cache/assets/CFF/C60/sprockets%2F0889d12d44383c7e7a859966f686badf +0 -0
- data/test/dummy/tmp/cache/assets/D04/D90/sprockets%2F617b1ad4f3ced27a38b689309c3240a2 +0 -0
- data/test/dummy/tmp/cache/assets/D06/D60/sprockets%2Fa09118ec6cd7033eb762b64a1ae58274 +0 -0
- data/test/dummy/tmp/cache/assets/D07/8B0/sprockets%2Ff123328eedad10b6f547eba992560504 +0 -0
- data/test/dummy/tmp/cache/assets/D09/740/sprockets%2Fb4177155aa0b2a846458b4da378dbe56 +0 -0
- data/test/dummy/tmp/cache/assets/D0A/6F0/sprockets%2Fa394b21853c45302cad3b17f7de2489e +0 -0
- data/test/dummy/tmp/cache/assets/D0B/E00/sprockets%2Fce33d32f3235ad54031338e689a8bdc7 +0 -0
- data/test/dummy/tmp/cache/assets/D0C/3B0/sprockets%2Ff34ef114cb808f84780a11082ade91d7 +0 -0
- data/test/dummy/tmp/cache/assets/D0F/3E0/sprockets%2F6654975eaa53a225d976278fcb6baa00 +0 -0
- data/test/dummy/tmp/cache/assets/D0F/550/sprockets%2F9927550095e029ace0d4d5add6901ce5 +0 -0
- data/test/dummy/tmp/cache/assets/D10/790/sprockets%2F31d2271940e9d19a9a5fb42fc70f26d7 +0 -0
- data/test/dummy/tmp/cache/assets/D12/1F0/sprockets%2Fce0c803f16e21317768892d42f1a8efc +0 -0
- data/test/dummy/tmp/cache/assets/D12/8E0/sprockets%2F93656a1c9a1db15ff824a84f3867c3b0 +0 -0
- data/test/dummy/tmp/cache/assets/D14/380/sprockets%2F7d5975b3efc5ace265c437a91539101f +0 -0
- data/test/dummy/tmp/cache/assets/D14/890/sprockets%2F2cb018dd1879c96fa83d4909b04f21e5 +0 -0
- data/test/dummy/tmp/cache/assets/D16/1F0/sprockets%2Fb19e1a25f43ad7167231aee857288f6f +0 -0
- data/test/dummy/tmp/cache/assets/D18/150/sprockets%2F524feca5ed7674507bd2e517943f45c4 +0 -0
- data/test/dummy/tmp/cache/assets/D19/6F0/sprockets%2Fc63725cd8e7d8f30818f7a82a75cc331 +0 -0
- data/test/dummy/tmp/cache/assets/D1A/600/sprockets%2F56bf56fa14222faef68241a4866f9e28 +0 -0
- data/test/dummy/tmp/cache/assets/D1E/AF0/sprockets%2F38fb02a7c41a3f3956e1f8b783885af8 +0 -0
- data/test/dummy/tmp/cache/assets/D21/2A0/sprockets%2F1fa2a4758d368a4ed74af19d94958d53 +0 -0
- data/test/dummy/tmp/cache/assets/D23/C30/sprockets%2F30a075c86c0057f03ed03a1a6c1ac74f +0 -0
- data/test/dummy/tmp/cache/assets/D2C/3A0/sprockets%2F5fb3206e15e73cbac0463d4e0633b9c1 +0 -0
- data/test/dummy/tmp/cache/assets/D2D/B40/sprockets%2F214ba38cd9bae5351510b85c60b1cf66 +0 -0
- data/test/dummy/tmp/cache/assets/D31/410/sprockets%2F1fb41a8351cfe74b19081d3a0a8cd186 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D34/3C0/sprockets%2Fd6f33bf9ea577a425537e31a1b1436aa +0 -0
- data/test/dummy/tmp/cache/assets/D36/A50/sprockets%2F4c5a2303a78ff5007cba199ec980b41d +0 -0
- data/test/dummy/tmp/cache/assets/D38/300/sprockets%2F231189114e3e16c0af8cbbfb922a7c89 +0 -0
- data/test/dummy/tmp/cache/assets/D3A/320/sprockets%2Fb4e466a4108157e7bbdf8a80530e76ab +0 -0
- data/test/dummy/tmp/cache/assets/D3C/430/sprockets%2Fc1850205179d6bc0315cf87db4edd7a8 +0 -0
- data/test/dummy/tmp/cache/assets/D3C/600/sprockets%2F6cb9fa003e4ae915755dbc429d54b255 +0 -0
- data/test/dummy/tmp/cache/assets/D3D/970/sprockets%2F9e70fe2b22f4504ee45029b9d04ce46c +0 -0
- data/test/dummy/tmp/cache/assets/D3F/4A0/sprockets%2F9d1d25fb38006ddc0e6fcf42190d8583 +0 -0
- data/test/dummy/tmp/cache/assets/D3F/D70/sprockets%2Fa7d40ead3d8014db7e90ec643e323969 +0 -0
- data/test/dummy/tmp/cache/assets/D43/7F0/sprockets%2F05ba12f3e980c9658d979415aca6a3ce +0 -0
- data/test/dummy/tmp/cache/assets/D45/7E0/sprockets%2Fc24e2e08818f34b11af78c7b4467fb5f +0 -0
- data/test/dummy/tmp/cache/assets/D45/970/sprockets%2Ff0e7b8648d5a2519256c1eeb2d9f08d2 +0 -0
- data/test/dummy/tmp/cache/assets/D45/F90/sprockets%2F6b6e959a5f0990831a196b6bddb05f3b +0 -0
- data/test/dummy/tmp/cache/assets/D47/E90/sprockets%2Fa578fc0e68c5d167fc5c365e2c09a616 +0 -0
- data/test/dummy/tmp/cache/assets/D48/090/sprockets%2F7a07a493490b7ac1cc0466a9eed8e589 +0 -0
- data/test/dummy/tmp/cache/assets/D4A/820/sprockets%2Feb00ebb7f262bff8638844571e1a859f +0 -0
- data/test/dummy/tmp/cache/assets/D4B/160/sprockets%2F78835ac7e39b080e262f9a4b76cbd65d +0 -0
- data/test/dummy/tmp/cache/assets/D4B/320/sprockets%2F4a570986eef4f2707130eb8c9c36d9ad +0 -0
- data/test/dummy/tmp/cache/assets/D4C/7F0/sprockets%2F5c0e220ac801d18f4bd1bd65e043d20a +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D4F/E20/sprockets%2F2da45938fca5e6979baa57c61b43b689 +0 -0
- data/test/dummy/tmp/cache/assets/D51/C40/sprockets%2F9c881f9a0edd974bf6ff0f83a4308192 +0 -0
- data/test/dummy/tmp/cache/assets/D52/6A0/sprockets%2F8b5de085dffa4897817e72a1b75348cd +0 -0
- data/test/dummy/tmp/cache/assets/D54/210/sprockets%2F8d24b46f6838cc66ddb9c7b07d32e939 +0 -0
- data/test/dummy/tmp/cache/assets/D56/C20/sprockets%2F4ce9229c7c971ce590189cfea1e74d95 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/310/sprockets%2F7f968e95238c9866f6ebd76a16b2aab6 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/7B0/sprockets%2Fda913ea979b742f1f7418f488e32fe8f +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D5C/1F0/sprockets%2Fed34fbbec82818204a214b5114d3dce5 +0 -0
- data/test/dummy/tmp/cache/assets/D64/700/sprockets%2F76c71d55a65dae34d0f60d62ee3a63b0 +0 -0
- data/test/dummy/tmp/cache/assets/D64/DE0/sprockets%2F655e1ca6a735ac75093c0e01febce293 +0 -0
- data/test/dummy/tmp/cache/assets/D72/4B0/sprockets%2F34ba5dd43adc2c826b79ce9a944f8620 +0 -0
- data/test/dummy/tmp/cache/assets/D76/710/sprockets%2F6740efeff28c623e091100f28f7c9eaf +0 -0
- data/test/dummy/tmp/cache/assets/D77/3D0/sprockets%2F76515b80ab945bb46f93cdace3993c4e +0 -0
- data/test/dummy/tmp/cache/assets/D78/C60/sprockets%2F3ed4e68ec22d09a66c1ea96e6b733d66 +0 -0
- data/test/dummy/tmp/cache/assets/D92/5E0/sprockets%2F17d03aff61dbd220217eb7f159bb8df2 +0 -0
- data/test/dummy/tmp/cache/assets/D96/CE0/sprockets%2Fff431fe62bbb5f0e9d63c43c4010fd56 +0 -0
- data/test/dummy/tmp/cache/assets/D9C/CF0/sprockets%2Fde9afe6f38620c4144b5a5fd1dc36f23 +0 -0
- data/test/dummy/tmp/cache/assets/D9C/EA0/sprockets%2Ff1cdf6c71079c7b373b1b842bf4e9a3a +0 -0
- data/test/dummy/tmp/cache/assets/D9D/590/sprockets%2F93ee64febc21345494bfbd0a8aad6446 +0 -0
- data/test/dummy/tmp/cache/assets/D9E/490/sprockets%2Fe231e8b6ec488aecaf61d84bb542e029 +0 -0
- data/test/dummy/tmp/cache/assets/D9E/6A0/sprockets%2F0a9e2c29287a00d9b9cc94cd9b3af63a +0 -0
- data/test/dummy/tmp/cache/assets/DA0/110/sprockets%2F29a7ddee7ded49b2613bb26f5d0980a3 +0 -0
- data/test/dummy/tmp/cache/assets/DA2/580/sprockets%2F35d3674fac89e6235b3fa6b251fbc3ff +0 -0
- data/test/dummy/tmp/cache/assets/DA2/780/sprockets%2F83886a2d2dba19d6cf5a2ea7fe7213d7 +0 -0
- data/test/dummy/tmp/cache/assets/DA3/9C0/sprockets%2F7f2d6495f1f675acc353e0a37adc94ae +0 -0
- data/test/dummy/tmp/cache/assets/DA6/B80/sprockets%2F60bbf1fc573c8bc35c8da9082888cb6c +0 -0
- data/test/dummy/tmp/cache/assets/DA6/EB0/sprockets%2F83015053ed9a581994cafcbbf9e7e6ab +0 -0
- data/test/dummy/tmp/cache/assets/DA7/0C0/sprockets%2Fc9194b0b488f53a9afc0540ced96ad9e +0 -0
- data/test/dummy/tmp/cache/assets/DA7/6D0/sprockets%2F28ce714e9b9d6aa16c4604bc9b5afd79 +0 -0
- data/test/dummy/tmp/cache/assets/DA9/490/sprockets%2F9815ad0a7dab6fbdfb2856654298acf7 +0 -0
- data/test/dummy/tmp/cache/assets/DAC/E40/sprockets%2Fec3c6d68d0e246ed889fe31471dc44fc +0 -0
- data/test/dummy/tmp/cache/assets/DAE/050/sprockets%2F6a3d58d879f5afbf0ad526425fe76a5f +0 -0
- data/test/dummy/tmp/cache/assets/DB8/040/sprockets%2F218aaca004d507da6f207ce9de821bea +0 -0
- data/test/dummy/tmp/cache/assets/DBB/E80/sprockets%2Fa01bf17ca00dc2b43f749abe69cad680 +0 -0
- data/test/dummy/tmp/cache/assets/DBD/170/sprockets%2Fc229df8cfb1c041769d0bb3c8eb310ac +0 -0
- data/test/dummy/tmp/cache/assets/DBF/770/sprockets%2F89c90a5f9259fc5b1b6ed69efe7c88d2 +0 -0
- data/test/dummy/tmp/cache/assets/DBF/850/sprockets%2Fb37d146f03d1ab72bd81afa3b7c295bf +0 -0
- data/test/dummy/tmp/cache/assets/DC3/E90/sprockets%2F63fce83ccf6fed1a634c00ec9623ba30 +0 -0
- data/test/dummy/tmp/cache/assets/DC4/1B0/sprockets%2Fedae9235cb5ca2fc97c2d335ba27a660 +0 -0
- data/test/dummy/tmp/cache/assets/DC7/2B0/sprockets%2Fda49c151b0b2be5bf6e8e135bd6f80d6 +0 -0
- data/test/dummy/tmp/cache/assets/DC9/C70/sprockets%2Fba5f2321c2ee8c42d0ff498a12e5bf7e +0 -0
- data/test/dummy/tmp/cache/assets/DCA/DC0/sprockets%2F7ed2addf814bfd28c3bad7790e005d53 +0 -0
- data/test/dummy/tmp/cache/assets/DCB/320/sprockets%2F672cc04c39b0a37cbe89cecbf3580ad7 +0 -0
- data/test/dummy/tmp/cache/assets/DCB/AE0/sprockets%2Fd14638ac9aaefa36ca75c1d66cb727e3 +0 -0
- data/test/dummy/tmp/cache/assets/DCC/1D0/sprockets%2Ff6defe1375c5acb57e141263b70fe5eb +0 -0
- data/test/dummy/tmp/cache/assets/DD1/DB0/sprockets%2Fc7a35f025c7fb33a2d9ce83ce4bd4f86 +0 -0
- data/test/dummy/tmp/cache/assets/DD2/5B0/sprockets%2F91c620bad817c7ffa64d5ea8b446db6f +0 -0
- data/test/dummy/tmp/cache/assets/DD2/D60/sprockets%2Fcc373f8a8e1d94ed2154dc37ca0f3ff6 +0 -0
- data/test/dummy/tmp/cache/assets/DD5/8E0/sprockets%2F0dde6f938e5addbdab55f6e7037e1482 +0 -0
- data/test/dummy/tmp/cache/assets/DD5/B80/sprockets%2Fdd3beb4c76fbf877171fd66192ebc4b2 +0 -0
- data/test/dummy/tmp/cache/assets/DD7/F30/sprockets%2Fe5fedf2dc39b7a678447c63ee2601ebc +0 -0
- data/test/dummy/tmp/cache/assets/DDB/200/sprockets%2F9dd434d9f9a3f7f4b35d90a0ddd6fb19 +0 -0
- data/test/dummy/tmp/cache/assets/DDC/1F0/sprockets%2F7533abdaee852b1c7bb05cabe3b2040a +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/DDD/190/sprockets%2F85d9f2c43cee7e82bdf893e0d35ac66a +0 -0
- data/test/dummy/tmp/cache/assets/DDD/1E0/sprockets%2F951cfc59ce1918fcb37c28fa20e9ebf7 +0 -0
- data/test/dummy/tmp/cache/assets/DDE/590/sprockets%2F2e7b6f67b665649ced381dfe37ce2abe +0 -0
- data/test/dummy/tmp/cache/assets/DDE/660/sprockets%2Ff64ad0798dfc7f6da9fcd83b53c8c250 +0 -0
- data/test/dummy/tmp/cache/assets/DE8/2A0/sprockets%2F37ceb226c01db0bd317e3f3fcfcf1c51 +0 -0
- data/test/dummy/tmp/cache/assets/DE8/440/sprockets%2F5559ecfd0ee508d816e4dc889cd8fe3b +0 -0
- data/test/dummy/tmp/cache/assets/DEE/730/sprockets%2F8121bbae4961aeba50bdb2cbd939c09f +0 -0
- data/test/dummy/tmp/cache/assets/DEF/AB0/sprockets%2Ff8c08dc2009dc1c91a4da29cc852badb +0 -0
- data/test/dummy/tmp/cache/assets/DF1/9C0/sprockets%2F7bbd18d10dc4ea3f5d6b137a5b0c9e7b +0 -0
- data/test/dummy/tmp/cache/assets/DF8/6B0/sprockets%2F3b2dfa4e62529eeedd6de03ab7b26b19 +0 -0
- data/test/dummy/tmp/cache/assets/DFA/CE0/sprockets%2F11f1769f11ddfe50ae1ec399fafa1cf3 +0 -0
- data/test/dummy/tmp/cache/assets/DFE/C50/sprockets%2F0af9ec26a81ea5fa1e72f6de4f7a8e03 +0 -0
- data/test/dummy/tmp/cache/assets/DFF/900/sprockets%2Fd6d6cf5ff58edce3840dc45621fb1a1d +0 -0
- data/test/dummy/tmp/cache/assets/E02/C30/sprockets%2Fecc53a781b3bf1fbcc94fc77c951c5c5 +0 -0
- data/test/dummy/tmp/cache/assets/E04/440/sprockets%2F28fe8df46cdf880c8aa0cced70bb7570 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E08/200/sprockets%2Fed91cd00ed3e395eef48f19c62de6e1d +0 -0
- data/test/dummy/tmp/cache/assets/E10/340/sprockets%2F7ebd866bfd5a89bfdbf6d928b1d7341d +0 -0
- data/test/dummy/tmp/cache/assets/E19/2A0/sprockets%2F10fcfbe6ebae11a40c8eac41939a1b9a +0 -0
- data/test/dummy/tmp/cache/assets/E23/A10/sprockets%2F03c4303cddb0cfd8cc9e67aa76c70aee +0 -0
- data/test/dummy/tmp/cache/assets/E24/670/sprockets%2Fb857c29efff63c768fbb48ef8e79aae7 +0 -0
- data/test/dummy/tmp/cache/assets/E2E/550/sprockets%2Ffb7d8bb50347f4edae6b56ca4bdf07b7 +0 -0
- data/test/dummy/tmp/cache/assets/E3B/080/sprockets%2F09e2a090befacdae0db10cafb1893a0a +0 -0
- data/test/dummy/tmp/cache/assets/E3E/DE0/sprockets%2Fa977ff5dc4e348f89fe35af4bd2aae3c +0 -0
- data/test/dummy/tmp/cache/assets/E45/C30/sprockets%2F69ccc9abc9b338aeee9ee4f1958fb64c +0 -0
- data/test/dummy/tmp/cache/assets/E83/1F0/sprockets%2F936cdaaa3e9ff0aafac3bc95ea45a3c6 +0 -0
- data/test/dummy/tmp/cache/assets/E85/370/sprockets%2Fca34a37aca7a3f4fe4b2d9ad46ecccc9 +0 -0
- data/test/dummy/tmp/cache/assets/E89/CE0/sprockets%2F86a2fd89bf33cbbacf438bb6ef0f3aca +0 -0
- data/test/dummy/tmp/cache/assets/F45/590/sprockets%2Fedcf9d1288bc0cfabaccf35fa6ecceca +0 -0
- data/test/dummy/tmp/cache/sass/867224f66ea2bfec241b4cee6d1fd9626cb72b7e/scaffolds.css.scssc +0 -0
- data/test/dummy/tmp/cache/sass/867224f66ea2bfec241b4cee6d1fd9626cb72b7e/widgets.css.scssc +0 -0
- data/test/ensnare_test.rb +7 -0
- data/test/fixtures/ensnare/violations.yml +9 -0
- data/test/functional/ensnare/dashboard_controller_test.rb +16 -0
- data/test/functional/ensnare/violation_controller_test.rb +11 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/ensnare/violation_test.rb +9 -0
- data/test/unit/helpers/ensnare/dashboard_helper_test.rb +6 -0
- data/test/unit/helpers/ensnare/violation_helper_test.rb +6 -0
- 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
|
+
})();
|