handcart 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +247 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/handcart/application.js +16 -0
  6. data/app/assets/stylesheets/handcart/application.css +15 -0
  7. data/app/assets/stylesheets/handcart/layout.css.scss +21 -0
  8. data/app/controllers/handcart/application_controller.rb +4 -0
  9. data/app/controllers/handcart/ip_addresses_controller.rb +56 -0
  10. data/app/controllers/handcart/subdomains_controller.rb +55 -0
  11. data/app/helpers/handcart/application_helper.rb +14 -0
  12. data/app/helpers/handcart/url_helper.rb +16 -0
  13. data/app/models/handcart/concerns/handcarts.rb +30 -0
  14. data/app/models/handcart/domain_constraint.rb +20 -0
  15. data/app/models/handcart/ip_address.rb +18 -0
  16. data/app/models/handcart/setting_constraint.rb +26 -0
  17. data/app/models/handcart/subdomain.rb +36 -0
  18. data/app/views/handcart/ip_addresses/_form.html.haml +12 -0
  19. data/app/views/handcart/ip_addresses/edit.html.haml +3 -0
  20. data/app/views/handcart/ip_addresses/index.html.haml +36 -0
  21. data/app/views/handcart/ip_addresses/new.html.haml +3 -0
  22. data/app/views/handcart/ip_addresses/show.html.haml +20 -0
  23. data/app/views/handcart/subdomains/_form.html.haml +9 -0
  24. data/app/views/handcart/subdomains/edit.html.haml +3 -0
  25. data/app/views/handcart/subdomains/index.html.haml +31 -0
  26. data/app/views/handcart/subdomains/new.html.haml +3 -0
  27. data/app/views/handcart/subdomains/show.html.haml +20 -0
  28. data/app/views/layouts/handcart/_navbar.html.haml +15 -0
  29. data/app/views/layouts/handcart/application.html.haml +60 -0
  30. data/config/handcart.json +6 -0
  31. data/config/locales/en.yml +61 -0
  32. data/config/routes.rb +5 -0
  33. data/db/migrate/20131009165427_create_handcart_subdomains.rb +9 -0
  34. data/db/migrate/20131203000934_create_handcart_ip_addresses.rb +12 -0
  35. data/lib/handcart.rb +67 -0
  36. data/lib/handcart/acts_as_handcart.rb +16 -0
  37. data/lib/handcart/controller_additions.rb +152 -0
  38. data/lib/handcart/engine.rb +27 -0
  39. data/lib/handcart/ip_authorization.rb +27 -0
  40. data/lib/handcart/simple_form.rb +179 -0
  41. data/lib/handcart/strategies/base_ip_strategy.rb +21 -0
  42. data/lib/handcart/strategies/containment_strategy.rb +16 -0
  43. data/lib/handcart/strategies/inclusion_strategy.rb +17 -0
  44. data/lib/handcart/templates/rspec/controller/controller_spec.rb +17 -0
  45. data/lib/handcart/templates/rspec/scaffold/routing_spec.rb +40 -0
  46. data/lib/handcart/version.rb +3 -0
  47. data/spec/controllers/handcart/ip_addresses_controller_spec.rb +134 -0
  48. data/spec/controllers/handcart/subdomains_controller_spec.rb +138 -0
  49. data/spec/dummy/README.rdoc +28 -0
  50. data/spec/dummy/Rakefile +6 -0
  51. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  52. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  53. data/spec/dummy/app/assets/stylesheets/layout.css.scss +4 -0
  54. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  55. data/spec/dummy/app/controllers/custom_constraints_controller.rb +2 -0
  56. data/spec/dummy/app/controllers/ip_addresses_controller.rb +7 -0
  57. data/spec/dummy/app/controllers/master/companies_controller.rb +51 -0
  58. data/spec/dummy/app/controllers/master/dashboard_controller.rb +4 -0
  59. data/spec/dummy/app/controllers/master_controller.rb +2 -0
  60. data/spec/dummy/app/controllers/public_controller.rb +12 -0
  61. data/spec/dummy/app/controllers/subdomain_controller.rb +8 -0
  62. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  63. data/spec/dummy/app/models/company.rb +7 -0
  64. data/spec/dummy/app/views/ip_addresses/index.html.haml +12 -0
  65. data/spec/dummy/app/views/ip_addresses/show.html.haml +1 -0
  66. data/spec/dummy/app/views/layouts/_navbar.html.haml +11 -0
  67. data/spec/dummy/app/views/layouts/application.html.haml +53 -0
  68. data/spec/dummy/app/views/layouts/public.html.haml +41 -0
  69. data/spec/dummy/app/views/master/companies/_form.html.haml +19 -0
  70. data/spec/dummy/app/views/master/companies/edit.html.haml +7 -0
  71. data/spec/dummy/app/views/master/companies/index.html.haml +25 -0
  72. data/spec/dummy/app/views/master/companies/new.html.haml +5 -0
  73. data/spec/dummy/app/views/master/companies/show.html.haml +12 -0
  74. data/spec/dummy/app/views/master/dashboard/index.html.haml +2 -0
  75. data/spec/dummy/app/views/public/forbidden.html.haml +3 -0
  76. data/spec/dummy/app/views/public/index.html.haml +2 -0
  77. data/spec/dummy/app/views/subdomain/index.html.haml +2 -0
  78. data/spec/dummy/bin/bundle +3 -0
  79. data/spec/dummy/bin/rails +4 -0
  80. data/spec/dummy/bin/rake +4 -0
  81. data/spec/dummy/config.ru +4 -0
  82. data/spec/dummy/config/application.rb +40 -0
  83. data/spec/dummy/config/boot.rb +5 -0
  84. data/spec/dummy/config/database.yml +26 -0
  85. data/spec/dummy/config/environment.rb +5 -0
  86. data/spec/dummy/config/environments/development.rb +29 -0
  87. data/spec/dummy/config/environments/production.rb +80 -0
  88. data/spec/dummy/config/environments/test.rb +36 -0
  89. data/spec/dummy/config/handcart.json +6 -0
  90. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  91. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  92. data/spec/dummy/config/initializers/handcart.rb +16 -0
  93. data/spec/dummy/config/initializers/inflections.rb +16 -0
  94. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  95. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  96. data/spec/dummy/config/initializers/session_store.rb +3 -0
  97. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  98. data/spec/dummy/config/locales/en.yml +12 -0
  99. data/spec/dummy/config/routes.rb +23 -0
  100. data/spec/dummy/db/migrate/20131010194534_create_companies.rb +10 -0
  101. data/spec/dummy/db/migrate/20131016183624_add_active_to_companies.rb +5 -0
  102. data/spec/dummy/db/schema.rb +41 -0
  103. data/spec/dummy/log/development.log +14 -0
  104. data/spec/dummy/log/test.log +786 -0
  105. data/spec/dummy/public/404.html +58 -0
  106. data/spec/dummy/public/422.html +58 -0
  107. data/spec/dummy/public/500.html +57 -0
  108. data/spec/dummy/spec/models/company_spec.rb +36 -0
  109. data/spec/dummy/spec/routing/custom_constraints_routing_spec.rb +37 -0
  110. data/spec/dummy/tmp/cache/assets/development/sass/27d34b7cbcb5b92ab03220c4d4b91379cc64c2c0/layout.css.scssc +0 -0
  111. data/spec/dummy/tmp/cache/assets/development/sass/dc98e44780f42e6521ebbf14c4db22f6a78c41ef/layout.css.scssc +0 -0
  112. data/spec/dummy/tmp/cache/assets/development/sprockets/05974a1f812cf4a61bb242d48722fd19 +0 -0
  113. data/spec/dummy/tmp/cache/assets/development/sprockets/063a74a7c73c9501ee373ef00111f159 +0 -0
  114. data/spec/dummy/tmp/cache/assets/development/sprockets/073d2b13ed9366ce539940749eb3844d +0 -0
  115. data/spec/dummy/tmp/cache/assets/development/sprockets/0d76367ded60510a66afc3dea891e76a +0 -0
  116. data/spec/dummy/tmp/cache/assets/development/sprockets/106c3f4e1fc71e9dc70abae55d432886 +0 -0
  117. data/spec/dummy/tmp/cache/assets/development/sprockets/13ae4613233656a42188d4d3ddbb7fc1 +0 -0
  118. data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  119. data/spec/dummy/tmp/cache/assets/development/sprockets/18c826ba1d6dac1633cae2da25c0402a +0 -0
  120. data/spec/dummy/tmp/cache/assets/development/sprockets/247df6a90ce931f763db1ade5227d4b1 +0 -0
  121. data/spec/dummy/tmp/cache/assets/development/sprockets/2860df473a6cf4c483cd6f251fea3ae0 +0 -0
  122. data/spec/dummy/tmp/cache/assets/development/sprockets/2a99072e783dcef4637b38221531ea61 +0 -0
  123. data/spec/dummy/tmp/cache/assets/development/sprockets/2ab4b3177ab6c9d837c0905b61eedad5 +0 -0
  124. data/spec/dummy/tmp/cache/assets/development/sprockets/2b84c9cc30f71e24310dd1a4381caae8 +0 -0
  125. data/spec/dummy/tmp/cache/assets/development/sprockets/2bebf0981bc585e24939ca8ffe10081c +0 -0
  126. data/spec/dummy/tmp/cache/assets/development/sprockets/2c45a1517014fd239c930e48a71a93f0 +0 -0
  127. data/spec/dummy/tmp/cache/assets/development/sprockets/2d5147f4ea70131b4e330cab38aeb1a1 +0 -0
  128. data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  129. data/spec/dummy/tmp/cache/assets/development/sprockets/3124588878c79981009129f32d5fe408 +0 -0
  130. data/spec/dummy/tmp/cache/assets/development/sprockets/33325c558d8db2071bf8a938517e5af2 +0 -0
  131. data/spec/dummy/tmp/cache/assets/development/sprockets/350c8c72b1dbd7a84f85424b5cd4def1 +0 -0
  132. data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  133. data/spec/dummy/tmp/cache/assets/development/sprockets/3a3d69c38e3b3d20e94420ebebd05a69 +0 -0
  134. data/spec/dummy/tmp/cache/assets/development/sprockets/3b1656b46a35a6120c3407b930d468ba +0 -0
  135. data/spec/dummy/tmp/cache/assets/development/sprockets/3c0fc39d9b84afb4937545b620cd2d72 +0 -0
  136. data/spec/dummy/tmp/cache/assets/development/sprockets/3fa878a57cb0b42be266336564609b18 +0 -0
  137. data/spec/dummy/tmp/cache/assets/development/sprockets/40f26b5e75d0f747e691c0b38529fb59 +0 -0
  138. data/spec/dummy/tmp/cache/assets/development/sprockets/42aa8e53e39d8f5247f1b3e89cb00adc +0 -0
  139. data/spec/dummy/tmp/cache/assets/development/sprockets/42e1f4c72bf58cf112dd11eae8ee768b +0 -0
  140. data/spec/dummy/tmp/cache/assets/development/sprockets/433be3db83a4d9f93f5d1fa2ae3bde4e +0 -0
  141. data/spec/dummy/tmp/cache/assets/development/sprockets/4b6f9f46d7a2e230321d7f8df06ea470 +0 -0
  142. data/spec/dummy/tmp/cache/assets/development/sprockets/4c17c77b444339bb3ab293047da0ff0d +0 -0
  143. data/spec/dummy/tmp/cache/assets/development/sprockets/4ee93c096bb850d38032eb457afebf69 +0 -0
  144. data/spec/dummy/tmp/cache/assets/development/sprockets/4f25edc4354919ba67721f488ba10e12 +0 -0
  145. data/spec/dummy/tmp/cache/assets/development/sprockets/58fb821d4a4a44fdb2a89d4f487a8390 +0 -0
  146. data/spec/dummy/tmp/cache/assets/development/sprockets/5f97a76ac644497413f4c8dc547ddea6 +0 -0
  147. data/spec/dummy/tmp/cache/assets/development/sprockets/6076ab56e9c62fd04155d6f6c43e575e +0 -0
  148. data/spec/dummy/tmp/cache/assets/development/sprockets/60b75d9635ed84e08a0b9a245d8a3202 +0 -0
  149. data/spec/dummy/tmp/cache/assets/development/sprockets/64ad9f343408809fdfb1df851186853d +0 -0
  150. data/spec/dummy/tmp/cache/assets/development/sprockets/6e79870e51ea835a6847f8c65e23e14b +0 -0
  151. data/spec/dummy/tmp/cache/assets/development/sprockets/6e9d2e7aafa45c939731291fa453b8c2 +0 -0
  152. data/spec/dummy/tmp/cache/assets/development/sprockets/78f915513059378e161ceb6f2d14fbd9 +0 -0
  153. data/spec/dummy/tmp/cache/assets/development/sprockets/8102cf6724f489a310fe3a6b764bb2e9 +0 -0
  154. data/spec/dummy/tmp/cache/assets/development/sprockets/81108a1123b15b10c7f7f2e0d1207267 +0 -0
  155. data/spec/dummy/tmp/cache/assets/development/sprockets/81b3dcc0aa61577b08de13ba5633dbc4 +0 -0
  156. data/spec/dummy/tmp/cache/assets/development/sprockets/83e686634b5ac6d4b183677ed2edda8b +0 -0
  157. data/spec/dummy/tmp/cache/assets/development/sprockets/8581aae276f167a9b7b2158641b0bf87 +0 -0
  158. data/spec/dummy/tmp/cache/assets/development/sprockets/94cb3819408e525700729fbd473432c8 +0 -0
  159. data/spec/dummy/tmp/cache/assets/development/sprockets/99eb5e50b6d0e5d0d6b6c37cbde33864 +0 -0
  160. data/spec/dummy/tmp/cache/assets/development/sprockets/a7c86e9a777f7789dd1c78d26a662a87 +0 -0
  161. data/spec/dummy/tmp/cache/assets/development/sprockets/a9e19eb45005fa24bc8b90b6a374089f +0 -0
  162. data/spec/dummy/tmp/cache/assets/development/sprockets/ac4492393938e58cede2b6277afb0bc6 +0 -0
  163. data/spec/dummy/tmp/cache/assets/development/sprockets/ad1d96635f4dae7eb22d1984947d7440 +0 -0
  164. data/spec/dummy/tmp/cache/assets/development/sprockets/af718c632887ccb6c1c35c4b65c61293 +0 -0
  165. data/spec/dummy/tmp/cache/assets/development/sprockets/b2f45720a78d375468b99bb25f121c4e +0 -0
  166. data/spec/dummy/tmp/cache/assets/development/sprockets/b559f2694561fc6c44e3319f507de1e7 +0 -0
  167. data/spec/dummy/tmp/cache/assets/development/sprockets/b6e8c6ba59755a8fe132457f81065f96 +0 -0
  168. data/spec/dummy/tmp/cache/assets/development/sprockets/b796b57f310287a7a619afa9d5b99952 +0 -0
  169. data/spec/dummy/tmp/cache/assets/development/sprockets/b7c36a1c00d7804d9e827d704c0dd811 +0 -0
  170. data/spec/dummy/tmp/cache/assets/development/sprockets/bc28a210f3df576c74059aff8233eae3 +0 -0
  171. data/spec/dummy/tmp/cache/assets/development/sprockets/bc414fbd5123e40c4f5e69f4c294f489 +0 -0
  172. data/spec/dummy/tmp/cache/assets/development/sprockets/c0181c32e0ed10ec8fa3049f9a80f551 +0 -0
  173. data/spec/dummy/tmp/cache/assets/development/sprockets/c17130f66131c854d6f8c2196902b596 +0 -0
  174. data/spec/dummy/tmp/cache/assets/development/sprockets/c4c0e10aa5c21ece42c0bfe998a5d8c0 +0 -0
  175. data/spec/dummy/tmp/cache/assets/development/sprockets/c63bcc000975adbdf423db3ad43eb93f +0 -0
  176. data/spec/dummy/tmp/cache/assets/development/sprockets/c962f9220062a6407dfc7d9447565273 +0 -0
  177. data/spec/dummy/tmp/cache/assets/development/sprockets/cb8b538b6fce61b500edebe63156bf62 +0 -0
  178. data/spec/dummy/tmp/cache/assets/development/sprockets/cfcef2015b7df990ed90006632877389 +0 -0
  179. data/spec/dummy/tmp/cache/assets/development/sprockets/cff56d2d0a8b8a25d4b0388d242be9c8 +0 -0
  180. data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  181. data/spec/dummy/tmp/cache/assets/development/sprockets/d32fc7356f764b22ecbcebbcb9b47ee1 +0 -0
  182. data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  183. data/spec/dummy/tmp/cache/assets/development/sprockets/d776667bae72eb3d582da5803fc931ca +0 -0
  184. data/spec/dummy/tmp/cache/assets/development/sprockets/dfc307d14a0cf64cf8c3a4e94fdbcfb9 +0 -0
  185. data/spec/dummy/tmp/cache/assets/development/sprockets/e4b6570b82329477bc7043183b64b105 +0 -0
  186. data/spec/dummy/tmp/cache/assets/development/sprockets/eff1316ad12dd5b8f4cbf0ba9e448229 +0 -0
  187. data/spec/dummy/tmp/cache/assets/development/sprockets/f2348b747b81ca6e3a24d5bd0b7023c4 +0 -0
  188. data/spec/dummy/tmp/cache/assets/development/sprockets/f6f921309fcc78b6850abcf2418279fe +0 -0
  189. data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  190. data/spec/dummy/tmp/cache/assets/development/sprockets/f7e1dbf50c19c9d439de52caa4296164 +0 -0
  191. data/spec/dummy/tmp/cache/assets/development/sprockets/ff2adfc3ed446b68ac2d0077e8af34e2 +0 -0
  192. data/spec/factories/companies.rb +7 -0
  193. data/spec/factories/handcart_ip_addresses.rb +8 -0
  194. data/spec/factories/handcart_subdomains.rb +5 -0
  195. data/spec/models/handcart/base_ip_strategy_spec.rb +23 -0
  196. data/spec/models/handcart/containment_strategy_spec.rb +23 -0
  197. data/spec/models/handcart/domain_constraint_spec.rb +38 -0
  198. data/spec/models/handcart/engine_spec.rb +14 -0
  199. data/spec/models/handcart/handcart_spec.rb +38 -0
  200. data/spec/models/handcart/inclusion_strategy_spec.rb +29 -0
  201. data/spec/models/handcart/ip_address_spec.rb +51 -0
  202. data/spec/models/handcart/ip_authorization_spec.rb +17 -0
  203. data/spec/models/handcart/subdomain_spec.rb +153 -0
  204. data/spec/routing/handcart/ip_addresses_routing_spec.rb +38 -0
  205. data/spec/routing/handcart/subdomains_routing_spec.rb +38 -0
  206. data/spec/spec_helper.rb +65 -0
  207. data/spec/support/subdomains.rb +26 -0
  208. metadata +565 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27d609f5f8801213d67ddae823d59976c0016abf
4
+ data.tar.gz: 01bce062c8bee95eb38ecbe931a1c4ce160e663b
5
+ SHA512:
6
+ metadata.gz: 633fd074412c2d921ab93775d34e00c61602bca5a2655a5c8da97cd2de17f10e4827242310017373fd201a81833993226bc6f75b9ca6507f0a4279bcf03d34ec
7
+ data.tar.gz: 9c708debf635ce439e11c5358333d9987b40235cc649f6b63fd23949dc3e1d3167696164ade139158018421a67f1d3dced27c8dbfe6b231446246b37bc090639
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Mark Holmberg
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,247 @@
1
+ ## Handcart
2
+
3
+ #### A rails gem for managing subdomains in Ruby on Rails.
4
+
5
+ ### Installation
6
+
7
+ ```ruby
8
+ gem 'handcart'
9
+ ```
10
+
11
+ ### Copy Migrations
12
+
13
+ Handcart requires that you copy over its migrations in the following manner:
14
+
15
+ ```ruby
16
+ rake handcart:install:migrations
17
+ ```
18
+
19
+ ### Configuration
20
+
21
+ Handcart can be configured via an initializer file in the following fashion:
22
+
23
+ ```ruby
24
+ # config/initializers/handcart.rb
25
+
26
+ Handcart.setup do |config|
27
+ # You shouldn't need to change this, but the option is available
28
+ config.subdomain_class = "Handcart::Subdomain"
29
+
30
+ # This MUST be set in order for Handcart to work properly.
31
+ # Set it to the value of the class which will call `acts_as_handcart`
32
+ config.handcart_class = "Company"
33
+
34
+ # This will allow you to prevent certain subdomains from being created
35
+ config.reserved_subdomains = ["www", "ftp", "ssh", "pop3", "staging", "master"]
36
+
37
+ # Set this to provide a custom route to the show action for the model which
38
+ # invokes the call to `acts_as_handcart`.
39
+ config.handcart_show_path = "companies"
40
+
41
+ # Set the strategy to use for IP Authorization
42
+ config.ip_authorization_strategy = :inclusion
43
+
44
+ # What Rails environments enable IP blocking and blacklisting
45
+ config.global_ip_blocking_enabled_environments = ["development", "production"]
46
+
47
+ # What Rails environments enable IP forwarding and forbidden redirects
48
+ config.global_ip_forwarding_enabled_environments = ["development", "staging", "production"]
49
+ end
50
+ ```
51
+
52
+ ### Handcart Activation
53
+
54
+ If the thing which `acts_as_handcart` responds to the method `active?`, Handcart will detect that
55
+ and will not match the routing for the subdomain constraints for that handcart until that method returns true.
56
+ This allows your model to require activation before it will actually go live.
57
+
58
+ ### Extended Configuration
59
+
60
+ Handcart has support for default domain constraints using a JSON configuration file. Place the following
61
+ file inside the `config/` folder of your application:
62
+
63
+ ```ruby
64
+ # config/handcart.json
65
+
66
+ {
67
+ "development" : { "domain_constraint" : "dummy.dev" },
68
+ "test" : { "domain_constraint" : "dummy.test" },
69
+ "staging" : { "domain_constraint" : "dummy.dev" },
70
+ "production" : { "domain_constraint" : "dummy.dev" }
71
+ }
72
+ ```
73
+
74
+ You can then use the default constraint provided by this JSON configuration file by doing the following inside your routes
75
+
76
+ ```ruby
77
+ # config/routes.rb
78
+
79
+ constraints Handcart::DomainConstraint.default_constraint do
80
+ # My Routes here...
81
+ end
82
+ ```
83
+
84
+ ### Advanced Routing Constraints
85
+
86
+ Handcart provides the ability to configure advanced routing constraints. This will allow you to match
87
+ routes only if certain conditions are met. See the following example:
88
+
89
+ ```ruby
90
+ constraints(Handcart::Subdomain) do
91
+ resources :custom_constraints, only: [:index], constraints: Handcart::SettingConstraint.new(:enables?, :custom_constraints)
92
+ match '/', to: 'subdomain#index', via: [:get], as: :subdomain_root
93
+ end
94
+ ```
95
+
96
+ The advanced routing constraint show in this example will only match the route `/custom_constraints` if the Handcart (Company) can call
97
+ `enables?(:custom_constraints)` and returns true. This allows you to check to ensure that routes are match on a per Handcart basis.
98
+
99
+ ### Mount the Engine
100
+
101
+ Handcart needs to be mounted inside the routes file. Add the following line where appropriate:
102
+
103
+ ```ruby
104
+ mount Handcart::Engine => "/handcart"
105
+ ```
106
+
107
+ ### Setup Handcart Model
108
+
109
+ Handcart needs to know what model is the thing that is being subdomained, i.e. a School or a Company.
110
+
111
+ ```ruby
112
+ # app/models/company.rb
113
+
114
+ class Company < ActiveRecord::Base
115
+ acts_as_handcart
116
+ end
117
+ ```
118
+
119
+ ### Provided Helpers
120
+
121
+ Handcart gives you a few helper methods which can be used in the controller or views
122
+
123
+ * current_subdomain
124
+
125
+ This helper will allow you to fetch the current subdomain (assuming you're on one).
126
+
127
+ * current_handcart
128
+
129
+ This helper will allow you to fetch the current thing that is being subdomained. In the case
130
+ of the company model above, current_handcart would return the company.
131
+
132
+ * handcart_show_path(handcart)
133
+
134
+ This is a special route generated by Handcart which will allow the backend to link to the
135
+ show page for the thing which `acts_as_handcart`.
136
+
137
+ If in the configuration for Handcart the `handcart_show_path` was set to "companies", it
138
+ would result in the following URL:
139
+
140
+ `/companies/:id`
141
+
142
+ Where ID would be set to the id of the company. If this configuration option is not set, it will
143
+ try to infer it based on the `handcart_class` that is specified.
144
+
145
+
146
+ ### Routing Helpers
147
+
148
+ Handcart provides a way to apply domain/subdomain constraints to your routes. The following
149
+ is an example which uses both Domain Constraints and Subdomain Constraints.
150
+
151
+ ```ruby
152
+ # config/routes.rb
153
+
154
+ Rails.application.routes.draw do
155
+ # Allows for a Reserved Subdomain (Master Backend Interface)
156
+ constraints(subdomain: /master/) do
157
+ scope module: 'master' do
158
+ match '/', to: 'dashboard#index', via: [:get], as: :master_root
159
+ end
160
+ end
161
+
162
+ # Allows for Subdomains created through Handcart (Franchisee Interface)
163
+ constraints(Handcart::Subdomain) do
164
+ match '/', to: 'subdomain#index', via: [:get], as: :subdomain_root
165
+ end
166
+
167
+ # Allows for Domain Constraints (Public Interface)
168
+ constraints Handcart::DomainConstraint.default_constraint do
169
+ match '/', to: 'public#index', via: [:get], as: :public_root
170
+ end
171
+ end
172
+ ```
173
+
174
+ ### IP Authorization
175
+
176
+ Handcart provides support for foreign IP authorization using various built-in strategies.
177
+ The IP authorization module provides the following strategies for use when trying to authenticate foreign
178
+ IP addresses:
179
+
180
+ #### None
181
+
182
+ If the `config.ip_authorization_strategy` configuration variable is set to `:none`, then no foreign IP
183
+ authorization will occur. This means that any IP address from the outside world will be permitted to
184
+ login to the franchisee interface.
185
+
186
+ #### Containment
187
+
188
+ Setting `config.ip_authorization_strategy` to `:containment` will require that the foreign IP address
189
+ is simple included in the list of IP addresses which are allowed for the franchisee.
190
+
191
+ #### Inclusion
192
+
193
+ Setting `config.ip_authorization_strategy` to `:inclusion` will require that the foreign IP address
194
+ is included in the list of IP addresses which are allowed for the franchisee AND that the subnet of
195
+ the foreign IP address is also in the same subnet as any which are in the whitelist.
196
+
197
+ ### IP Forwarding
198
+
199
+ If your application has a public interface, Handcart can be configured to automatically forward
200
+ authorized foreign IP addresses to a controller action of your choosing. In addition, if they are not
201
+ authorized, it will forward them to a *public* controller action of your choosing. To invoke IP forwarding
202
+ the following settings must be configured in the initializer:
203
+
204
+ ```ruby
205
+ # config/initializers/handcart.rb
206
+ # What Rails environments enable IP forwarding and forbidden redirects
207
+ config.global_ip_forwarding_enabled_environments = ["development", "staging", "production"]
208
+ ```
209
+
210
+ Make sure that the environments in which you want IP forwarding to occur in are listed in the variable above.
211
+
212
+
213
+ #### Public Controller Invocation
214
+
215
+ To have Handcart enable IP forwarding, the following method must be invoked in the `PublicController`:
216
+
217
+ ```ruby
218
+ # app/controllers/public_controller.rb
219
+ enable_forwarding("subdomain#forwarding", "public#forbidden", only: [:index])
220
+ ```
221
+
222
+ The first argument indicates what controller and action should be invoked inside the franchisee namespace. The second
223
+ argument is the controller and action on the `PublicController` which should be invoked when the foreign IP is NOT authorized.
224
+
225
+ ### IP Blocking
226
+
227
+ If you want Handcart to enable the IP blocking feature, you'll need to have the following settings in the initializer:
228
+
229
+ ```ruby
230
+ # What Rails environments enable IP blocking and blacklisting
231
+ config.global_ip_blocking_enabled_environments = ["development", "production"]
232
+ ```
233
+
234
+ #### Franchisee Controller Invocation
235
+
236
+ To have Handcart enable IP blocking, the following method must be invoked in a controller which is namespaced under
237
+ the franchisee:
238
+
239
+ ```ruby
240
+ # app/controllers/sessions_controller.rb
241
+ enable_blocking("public#forbidden")
242
+ ```
243
+
244
+ The first argument indicates the controller and action which will be redirected to should the IP authorization strategy indicate
245
+ that the foreign IP address is NOT authorized. This method can also accept the standard options such as `only: [:index]`. The use
246
+ case for this method is designed to be the sessions controller for the franchisee. The idea is that it will not let them login to
247
+ the franchise if they're not authorized.
@@ -0,0 +1,37 @@
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
+
8
+ require 'rdoc/task'
9
+
10
+ RDoc::Task.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'Handcart'
13
+ rdoc.options << '--line-numbers'
14
+ rdoc.rdoc_files.include('README.rdoc')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
19
+ load 'rails/tasks/engine.rake'
20
+
21
+ Bundler::GemHelper.install_tasks
22
+
23
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
24
+ require 'rspec/core'
25
+ require 'rspec/core/rake_task'
26
+
27
+ desc "Run all specs in spec directory (excluding plugin specs)"
28
+ RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
29
+ task default: :spec
30
+
31
+ desc 'Print out all defined routes in match order, with names. Target specific controller with CONTROLLER=x.'
32
+ task routes: :environment do
33
+ all_routes = Rails.application.routes.routes
34
+ require 'action_dispatch/routing/inspector'
35
+ inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
36
+ puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, ENV['CONTROLLER'])
37
+ end
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require twitter/bootstrap
16
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *=require twitter-bootstrap-static/bootstrap
13
+ *=require twitter-bootstrap-static/fontawesome
14
+ *= require_tree .
15
+ */
@@ -0,0 +1,21 @@
1
+ footer p {
2
+ margin-top: 1em;
3
+ text-align: center;
4
+ }
5
+
6
+ td.action-button {
7
+ width: 2em;
8
+ }
9
+
10
+ .page-header {
11
+ margin-bottom: 1em !important;
12
+ }
13
+
14
+ #button-toolbar {
15
+ margin-bottom: 2em;
16
+ }
17
+
18
+ .navbar-inverse .nav .active>a, .navbar-inverse .nav .active>a:hover, .navbar-inverse .nav .active>a:focus {
19
+ color: #FFFFFF;
20
+ background-color: #424242;
21
+ }
@@ -0,0 +1,4 @@
1
+ module Handcart
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,56 @@
1
+ require_dependency "handcart/application_controller"
2
+
3
+ module Handcart
4
+ class IpAddressesController < ApplicationController
5
+ before_action :set_ip_address, only: [:show, :edit, :update, :destroy]
6
+
7
+ def index
8
+ @ip_addresses = IpAddress.all
9
+ end
10
+
11
+ def show
12
+ end
13
+
14
+ def new
15
+ @ip_address = IpAddress.new
16
+ end
17
+
18
+ def edit
19
+ end
20
+
21
+ def create
22
+ @ip_address = IpAddress.new(safe_params)
23
+
24
+ if @ip_address.save
25
+ redirect_to @ip_address, notice: 'Ip address was successfully created.'
26
+ else
27
+ render :new
28
+ end
29
+ end
30
+
31
+ def update
32
+ if @ip_address.update(safe_params)
33
+ redirect_to @ip_address, notice: 'Ip address was successfully updated.'
34
+ else
35
+ render :edit
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ @ip_address.destroy
41
+ redirect_to ip_addresses_url, notice: 'Ip address was successfully removed.'
42
+ end
43
+
44
+ private
45
+
46
+ def set_ip_address
47
+ @ip_address = IpAddress.find(params[:id])
48
+ end
49
+
50
+ def safe_params
51
+ safe_attributes = [:address, :subnet_mask, :handcart_id, :blacklisted]
52
+ params.require(:ip_address).permit(safe_attributes)
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,55 @@
1
+ require_dependency "handcart/application_controller"
2
+
3
+ module Handcart
4
+ class SubdomainsController < ApplicationController
5
+ before_action :set_subdomain, only: [:show, :edit, :update, :destroy]
6
+
7
+ def index
8
+ @subdomains = Subdomain.all
9
+ end
10
+
11
+ def show
12
+ end
13
+
14
+ def new
15
+ @subdomain = Subdomain.new
16
+ end
17
+
18
+ def edit
19
+ end
20
+
21
+ def create
22
+ @subdomain = Subdomain.new(safe_params)
23
+
24
+ if @subdomain.save
25
+ redirect_to subdomains_url, notice: 'Subdomain was successfully created.'
26
+ else
27
+ render :new
28
+ end
29
+ end
30
+
31
+ def update
32
+ if @subdomain.update(safe_params)
33
+ redirect_to subdomains_url, notice: 'Subdomain was successfully updated.'
34
+ else
35
+ render :edit
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ @subdomain.destroy
41
+ redirect_to subdomains_url, notice: 'Subdomain was successfully destroyed.'
42
+ end
43
+
44
+ private
45
+
46
+ def set_subdomain
47
+ @subdomain = Subdomain.find(params[:id])
48
+ end
49
+
50
+ def safe_params
51
+ safe_attributes = [:name]
52
+ params.require(:subdomain).permit(safe_attributes)
53
+ end
54
+ end
55
+ end