handcart 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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,14 @@
1
+ module Handcart
2
+ module ApplicationHelper
3
+ def title(page_title, show_sub_title = true, options={})
4
+ content_for(:title) { page_title }
5
+ if show_sub_title
6
+ sub_title(page_title)
7
+ end
8
+ end
9
+
10
+ def sub_title(sub_title, options={})
11
+ content_for(:sub_title) { sub_title }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Handcart
2
+ module UrlHelper
3
+ def with_subdomain(subdomain)
4
+ subdomain = (subdomain || "")
5
+ subdomain += "." unless subdomain.empty?
6
+ [subdomain, request.domain, request.port_string].join
7
+ end
8
+
9
+ def url_for(options = nil)
10
+ if options.kind_of?(Hash) && options.has_key?(:subdomain)
11
+ options[:host] = with_subdomain(options.delete(:subdomain))
12
+ end
13
+ super
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module Handcart::Concerns::Handcarts
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to :subdomain, class_name: Handcart.subdomain_class.to_s
6
+ has_many :ip_addresses, dependent: :destroy, class_name: "Handcart::IpAddress", foreign_key: "handcart_id"
7
+
8
+ # Nuke the subdomain
9
+ before_destroy { |handcart| handcart.subdomain.destroy }
10
+ end
11
+
12
+ module ClassMethods
13
+ # Try to formulate a path to view the handcart show page
14
+ def handcart_show_path(handcart)
15
+ if Handcart.handcart_show_path.present?
16
+ # Load it straight from the config
17
+ "/#{Handcart.handcart_show_path}/#{handcart.to_param}"
18
+ else
19
+ if Rails.application.routes.url_helpers.respond_to?("#{Handcart.handcart_class.model_name.singular}_path".to_sym)
20
+ # Is there one already defined
21
+ Rails.application.routes.url_helpers.send("#{Handcart.handcart_class.model_name.singular}_path", handcart.to_param)
22
+ else
23
+ # Shot in the dark
24
+ "/#{Handcart.handcart_class.model_name.route_key}/#{handcart.to_param}"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,20 @@
1
+ module Handcart
2
+ class DomainConstraint
3
+
4
+ attr_reader :domain
5
+
6
+ def initialize(domain)
7
+ @domain = domain
8
+ Handcart.domain_constraints << @domain unless Handcart.domain_constraints.include?(@domain)
9
+ end
10
+
11
+ def matches?(request)
12
+ Handcart.domain_constraints.include?(request.domain)
13
+ end
14
+
15
+ def self.default_constraint
16
+ DomainConstraint.new(Handcart::Engine::CONFIG[:domain_constraint])
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module Handcart
2
+ class IpAddress < ActiveRecord::Base
3
+ belongs_to :handcart, class_name: Handcart.handcart_class.to_s
4
+
5
+ validates :address,
6
+ presence: true,
7
+ uniqueness: { case_sensitive: false },
8
+ format: { with: Resolv::IPv4::Regex }
9
+
10
+ validates :subnet_mask,
11
+ presence: true,
12
+ format: { with: Resolv::IPv4::Regex }
13
+
14
+ scope :blacklisted, -> { where(blacklisted: true) }
15
+ scope :permitted, -> { where.not(blacklisted: true) }
16
+ scope :with_handcart, lambda { |handcart| where(handcart_id: handcart.try(:id)) }
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ module Handcart
2
+ class SettingConstraint
3
+
4
+ attr_accessor :matcher, :feature
5
+
6
+ def initialize(matcher, feature)
7
+ @matcher = matcher
8
+ @feature = feature
9
+ end
10
+
11
+ def matches?(request)
12
+ # Given this request, find out if the thing which `acts_as_handcart` can call `matcher` looking for `feature`.
13
+ my_subdomain = Subdomain.find_by_name(request.subdomain)
14
+ if my_subdomain && request.subdomain.present? && my_subdomain.handcart
15
+ if my_subdomain.handcart.respond_to?(@matcher)
16
+ my_subdomain.handcart.send(@matcher.to_s, @feature)
17
+ else
18
+ # The handcart doesn't respond to the matcher, so no point checking
19
+ false
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ module Handcart
2
+ class Subdomain < ActiveRecord::Base
3
+ has_one :handcart, class_name: Handcart.handcart_class.to_s
4
+
5
+ validates :name,
6
+ presence: true,
7
+ uniqueness: { case_sensitive: false },
8
+ exclusion: { in: Handcart.reserved_subdomains }
9
+
10
+ scope :allocated, -> { Subdomain.includes(:handcart).where("#{Handcart.handcart_class.model_name.plural}.subdomain_id IS NOT NULL").references(:handcart) }
11
+ scope :unallocated, -> { Subdomain.includes(:handcart).where("#{Handcart.handcart_class.model_name.plural}.subdomain_id IS NULL").references(:handcart) }
12
+ scope :unallocated_or_current, lambda { |handcart| Subdomain.includes(:handcart).where("#{Handcart.handcart_class.model_name.plural}.subdomain_id IS NULL OR #{Handcart.handcart_class.model_name.plural}.subdomain_id IN (?)", handcart.try(:subdomain_id)).references(:handcart) }
13
+
14
+ before_save :normalize_name
15
+
16
+
17
+ def self.matches?(request)
18
+ my_subdomain = Subdomain.find_by_name(request.subdomain)
19
+ if my_subdomain && request.subdomain.present? && !Handcart.reserved_subdomains.include?(request.subdomain) && my_subdomain.handcart
20
+ if my_subdomain.handcart.respond_to?(:active?)
21
+ my_subdomain.handcart.active?
22
+ else
23
+ # Just default to true since we found the record
24
+ true
25
+ end
26
+ end
27
+ end
28
+
29
+
30
+ private
31
+
32
+ def normalize_name
33
+ self.name = name.squish.gsub(/\s+|\+|\/|=|\?/, '').parameterize
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,12 @@
1
+ = simple_form_for @ip_address, html: { class: 'form-horizontal' } do |f|
2
+ = f.error_notification
3
+
4
+ .form-inputs
5
+ = f.input :address
6
+ = f.input :subnet_mask
7
+ = f.association :handcart, collection: Company.all
8
+ = f.input :blacklisted, as: :select, include_blank: false
9
+
10
+ .form-actions
11
+ = f.button :submit, class: 'btn btn-primary'
12
+ = link_to 'Cancel', ip_addresses_path, class: 'btn'
@@ -0,0 +1,3 @@
1
+ - title t(".title")
2
+
3
+ = render 'form'
@@ -0,0 +1,36 @@
1
+ - title t(".title")
2
+
3
+ - content_for(:toolbar) do
4
+ .btn-group
5
+ = link_to new_ip_address_path, class: 'btn btn-primary', title: t(".new_ip_address") do
6
+ %i.icon-plus
7
+
8
+ %table.table.table-striped
9
+ %thead
10
+ %tr
11
+ %th= Handcart::IpAddress.human_attribute_name(:address)
12
+ %th= Handcart::IpAddress.human_attribute_name(:subnet_mask)
13
+ %th= Handcart::IpAddress.human_attribute_name(:handcart)
14
+ %th= Handcart::IpAddress.human_attribute_name(:blacklisted)
15
+ %th
16
+ %th
17
+ %th
18
+ %tbody
19
+ - @ip_addresses.each do |ip_address|
20
+ %tr
21
+ %td= ip_address.address
22
+ %td= ip_address.subnet_mask
23
+ %td= ip_address.handcart
24
+ %td= ip_address.blacklisted? ? "Yes" : "No"
25
+ %td.action-button
26
+ .pull-right
27
+ = link_to ip_address, class: 'btn', title: t(".view_ip_address") do
28
+ %i.icon-eye-open
29
+ %td.action-button
30
+ .pull-right
31
+ = link_to edit_ip_address_path(ip_address), class: 'btn', title: t(".edit_ip_address") do
32
+ %i.icon-pencil
33
+ %td.action-button
34
+ .pull-right
35
+ = link_to ip_address, method: :delete, data: { confirm: t(".confirm") }, class: 'btn btn-danger', title: t(".remove_ip_address") do
36
+ %i.icon-remove
@@ -0,0 +1,3 @@
1
+ - title t(".title")
2
+
3
+ = render 'form'
@@ -0,0 +1,20 @@
1
+ - title t(".title", address: @ip_address.address)
2
+
3
+ %table.table.table-striped
4
+ %thead
5
+ %tr
6
+ %th= Handcart::IpAddress.human_attribute_name(:address)
7
+ %th= Handcart::IpAddress.human_attribute_name(:subnet_mask)
8
+ %th= Handcart::IpAddress.human_attribute_name(:handcart)
9
+ %th= Handcart::IpAddress.human_attribute_name(:blacklisted)
10
+ %th
11
+ %tbody
12
+ %tr
13
+ %td= @ip_address.address
14
+ %td= @ip_address.subnet_mask
15
+ %td= @ip_address.handcart
16
+ %td= @ip_address.blacklisted? ? "Yes" : "No"
17
+ %td.action-button
18
+ .pull-right
19
+ = link_to edit_ip_address_path(@ip_address), class: 'btn', title: t(".edit_ip_address") do
20
+ %i.icon-pencil
@@ -0,0 +1,9 @@
1
+ = simple_form_for @subdomain, html: { class: 'form-horizontal' } do |f|
2
+ = f.error_notification
3
+
4
+ .form-inputs
5
+ = f.input :name
6
+
7
+ .form-actions
8
+ = f.button :submit, class: 'btn btn-primary'
9
+ = link_to 'Cancel', subdomains_path, class: 'btn'
@@ -0,0 +1,3 @@
1
+ - title t(".title")
2
+
3
+ = render 'form'
@@ -0,0 +1,31 @@
1
+ - title t(".subdomains")
2
+
3
+ - content_for(:toolbar) do
4
+ .btn-group
5
+ = link_to new_subdomain_path, class: 'btn btn-primary', title: t(".new_subdomain") do
6
+ %i.icon-plus
7
+
8
+ %table.table.table-striped
9
+ %thead
10
+ %tr
11
+ %th= Handcart.subdomain_class.human_attribute_name(:name)
12
+ %th= Handcart.handcart_class.model_name.human
13
+ %th
14
+ %th
15
+ %tbody
16
+ - @subdomains.each do |subdomain|
17
+ %tr
18
+ %td= link_to subdomain.name, subdomain
19
+ %td
20
+ - if subdomain.handcart
21
+ = link_to subdomain.handcart.try(:to_s), Handcart.handcart_class.handcart_show_path(subdomain.handcart)
22
+ - else
23
+ None
24
+ %td.action-button
25
+ .pull-right
26
+ = link_to edit_subdomain_path(subdomain), class: 'btn', title: t(".edit_subdomain") do
27
+ %i.icon-pencil
28
+ %td.action-button
29
+ .pull-right
30
+ = link_to subdomain, method: :delete, data: { confirm: t(".confirm") }, class: 'btn btn-danger', title: t(".remove_subdomain") do
31
+ %i.icon-remove
@@ -0,0 +1,3 @@
1
+ - title t(".title")
2
+
3
+ = render 'form'
@@ -0,0 +1,20 @@
1
+ - title t(".title", subdomain: @subdomain.name)
2
+
3
+ %table.table.table-striped
4
+ %thead
5
+ %tr
6
+ %th= Handcart.subdomain_class.human_attribute_name(:name)
7
+ %th= Handcart.handcart_class.model_name.human
8
+ %th
9
+ %tbody
10
+ %tr
11
+ %td= @subdomain.name
12
+ %td
13
+ - if @subdomain.handcart
14
+ = link_to @subdomain.handcart.try(:to_s), Handcart.handcart_class.handcart_show_path(@subdomain.handcart)
15
+ - else
16
+ None
17
+ %td.action-button
18
+ .pull-right
19
+ = link_to edit_subdomain_path(@subdomain), class: 'btn', title: t(".edit_subdomain") do
20
+ %i.icon-pencil
@@ -0,0 +1,15 @@
1
+ %ul.nav
2
+ %li
3
+ = link_to main_app.root_path do
4
+ %i.icon-arrow-left
5
+ Back to
6
+ = t(".main_app")
7
+ %li{class: (params[:controller] == "handcart/subdomains") ? "active" : nil}
8
+ = link_to handcart.root_path do
9
+ %i.icon-th-list
10
+ = t(".subdomains")
11
+ - unless (Handcart.ip_authorization.ip_authorization_strategy == :none)
12
+ %li{class: (params[:controller] == "handcart/ip_addresses") ? "active" : nil}
13
+ = link_to handcart.ip_addresses_path do
14
+ %i.icon-screenshot
15
+ = t(".ip_addresses")
@@ -0,0 +1,60 @@
1
+ !!! 5
2
+ %html(lang="en")
3
+ %head
4
+ %meta(charset="utf-8")
5
+ %meta(http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1")
6
+ %meta(name="viewport" content="width=device-width, initial-scale=1.0")
7
+ %title= content_for?(:title) ? t('.title', title: yield(:title)) : t('.default_title')
8
+ = csrf_meta_tags
9
+ / Le HTML5 shim, for IE6-8 support of HTML elements
10
+ /[if lt IE 9]
11
+ = javascript_include_tag "//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6.1/html5shiv.js"
12
+ = stylesheet_link_tag "handcart/application", media: "all"
13
+ = favicon_link_tag 'apple-touch-icon-144x144-precomposed.png', rel: 'apple-touch-icon-precomposed', type: 'image/png', sizes: '144x144'
14
+ = favicon_link_tag 'apple-touch-icon-114x114-precomposed.png', rel: 'apple-touch-icon-precomposed', type: 'image/png', sizes: '114x114'
15
+ = favicon_link_tag 'apple-touch-icon-72x72-precomposed.png', rel: 'apple-touch-icon-precomposed', type: 'image/png', sizes: '72x72'
16
+ = favicon_link_tag 'apple-touch-icon-precomposed.png', rel: 'apple-touch-icon-precomposed', type: 'image/png'
17
+ = javascript_include_tag "handcart/application"
18
+
19
+ %body
20
+ .navbar.navbar-fluid-top.navbar-inverse
21
+ .navbar-inner
22
+ .container-fluid
23
+ %a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse")
24
+ %span.icon-bar
25
+ %span.icon-bar
26
+ %span.icon-bar
27
+ %a.brand(href= root_path)
28
+ %i.icon-heart
29
+ = t(".handcart_brand")
30
+ = render "layouts/handcart/navbar"
31
+
32
+ .container-fluid
33
+ .row-fluid
34
+ - if content_for?(:sidebar)
35
+ .span9
36
+ %div.flash-message
37
+ = bootstrap_flash
38
+ - if content_for?(:sub_title)
39
+ .page-header
40
+ %h3.sub-title.inline= content_for?(:sub_title) ? yield(:sub_title) : t('.default_sub_title')
41
+ - if content_for?(:toolbar)
42
+ %div#button-toolbar= yield(:toolbar)
43
+ %div= yield
44
+ .span3
45
+ .well.sidebar-nav
46
+ %ul.nav.nav-list= yield(:sidebar)
47
+ - else
48
+ .span12
49
+ %div.flash-message
50
+ = bootstrap_flash
51
+ - if content_for?(:sub_title)
52
+ .page-header
53
+ %h3.sub-title.inline= content_for?(:sub_title) ? yield(:sub_title) : t('.default_sub_title')
54
+ - if content_for?(:toolbar)
55
+ %div#button-toolbar= yield(:toolbar)
56
+ %div= yield
57
+ %footer
58
+ %p
59
+ &copy;
60
+ = t(".copyright", year: Date.today.year)
@@ -0,0 +1,6 @@
1
+ {
2
+ "development" : { "domain_constraint" : "dummy.dev" },
3
+ "test" : { "domain_constraint" : "dummy.test" },
4
+ "staging" : { "domain_constraint" : "dummy.dev" },
5
+ "production" : { "domain_constraint" : "dummy.dev" }
6
+ }
@@ -0,0 +1,61 @@
1
+ en:
2
+ date:
3
+ formats:
4
+ short: "%d %B %Y"
5
+ time:
6
+ formats:
7
+ short: "%d %B %Y,%l:%M %P"
8
+ only_time: "%l:%M %P"
9
+ activerecord:
10
+ attributes:
11
+ handcart/ip_address:
12
+ address: 'Address'
13
+ blacklisted: 'Blacklisted'
14
+ subnet_mask: 'Subnet Mask'
15
+ handcart/subdomain:
16
+ name: 'Name'
17
+ models:
18
+ handcart/subdomain: 'Subdomain'
19
+ handcart/ip_address: 'IP Address'
20
+ layouts:
21
+ handcart:
22
+ navbar:
23
+ main_app: 'Dummy'
24
+ subdomains: 'Subdomains'
25
+ ip_addresses: 'IP Addresses'
26
+ application:
27
+ handcart_brand: 'Handcart'
28
+ copyright: "Handcart %{year}"
29
+ default_title: 'Handcart'
30
+ default_sub_title: ''
31
+ title: "Handcart : %{title}"
32
+ handcart:
33
+ ip_addresses:
34
+ edit:
35
+ title: "Edit IP Address"
36
+ index:
37
+ confirm: 'Are you sure you want to remove this IP Address?'
38
+ edit_ip_address: 'Edit IP Address'
39
+ new_ip_address: 'New IP Address'
40
+ remove_ip_address: 'Remove IP Address'
41
+ title: "IP Addresses"
42
+ view_ip_address: 'View IP Address'
43
+ new:
44
+ title: "New IP Address"
45
+ show:
46
+ edit_ip_address: 'Edit IP Address'
47
+ title: "IP Address : %{address}"
48
+ subdomains:
49
+ edit:
50
+ title: "Edit Subdomain"
51
+ index:
52
+ confirm: 'Are you sure you want to remove this subdomain?'
53
+ edit_subdomain: "Edit Subdomain"
54
+ new_subdomain: "New Subdomain"
55
+ remove_subdomain: "Remove Subdomain"
56
+ subdomains: "Subdomains"
57
+ new:
58
+ title: 'New Subdomain'
59
+ show:
60
+ edit_subdomain: "Edit Subdomain"
61
+ title: "Subdomain : %{subdomain}"