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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +247 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/handcart/application.js +16 -0
- data/app/assets/stylesheets/handcart/application.css +15 -0
- data/app/assets/stylesheets/handcart/layout.css.scss +21 -0
- data/app/controllers/handcart/application_controller.rb +4 -0
- data/app/controllers/handcart/ip_addresses_controller.rb +56 -0
- data/app/controllers/handcart/subdomains_controller.rb +55 -0
- data/app/helpers/handcart/application_helper.rb +14 -0
- data/app/helpers/handcart/url_helper.rb +16 -0
- data/app/models/handcart/concerns/handcarts.rb +30 -0
- data/app/models/handcart/domain_constraint.rb +20 -0
- data/app/models/handcart/ip_address.rb +18 -0
- data/app/models/handcart/setting_constraint.rb +26 -0
- data/app/models/handcart/subdomain.rb +36 -0
- data/app/views/handcart/ip_addresses/_form.html.haml +12 -0
- data/app/views/handcart/ip_addresses/edit.html.haml +3 -0
- data/app/views/handcart/ip_addresses/index.html.haml +36 -0
- data/app/views/handcart/ip_addresses/new.html.haml +3 -0
- data/app/views/handcart/ip_addresses/show.html.haml +20 -0
- data/app/views/handcart/subdomains/_form.html.haml +9 -0
- data/app/views/handcart/subdomains/edit.html.haml +3 -0
- data/app/views/handcart/subdomains/index.html.haml +31 -0
- data/app/views/handcart/subdomains/new.html.haml +3 -0
- data/app/views/handcart/subdomains/show.html.haml +20 -0
- data/app/views/layouts/handcart/_navbar.html.haml +15 -0
- data/app/views/layouts/handcart/application.html.haml +60 -0
- data/config/handcart.json +6 -0
- data/config/locales/en.yml +61 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20131009165427_create_handcart_subdomains.rb +9 -0
- data/db/migrate/20131203000934_create_handcart_ip_addresses.rb +12 -0
- data/lib/handcart.rb +67 -0
- data/lib/handcart/acts_as_handcart.rb +16 -0
- data/lib/handcart/controller_additions.rb +152 -0
- data/lib/handcart/engine.rb +27 -0
- data/lib/handcart/ip_authorization.rb +27 -0
- data/lib/handcart/simple_form.rb +179 -0
- data/lib/handcart/strategies/base_ip_strategy.rb +21 -0
- data/lib/handcart/strategies/containment_strategy.rb +16 -0
- data/lib/handcart/strategies/inclusion_strategy.rb +17 -0
- data/lib/handcart/templates/rspec/controller/controller_spec.rb +17 -0
- data/lib/handcart/templates/rspec/scaffold/routing_spec.rb +40 -0
- data/lib/handcart/version.rb +3 -0
- data/spec/controllers/handcart/ip_addresses_controller_spec.rb +134 -0
- data/spec/controllers/handcart/subdomains_controller_spec.rb +138 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/assets/stylesheets/layout.css.scss +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +7 -0
- data/spec/dummy/app/controllers/custom_constraints_controller.rb +2 -0
- data/spec/dummy/app/controllers/ip_addresses_controller.rb +7 -0
- data/spec/dummy/app/controllers/master/companies_controller.rb +51 -0
- data/spec/dummy/app/controllers/master/dashboard_controller.rb +4 -0
- data/spec/dummy/app/controllers/master_controller.rb +2 -0
- data/spec/dummy/app/controllers/public_controller.rb +12 -0
- data/spec/dummy/app/controllers/subdomain_controller.rb +8 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/company.rb +7 -0
- data/spec/dummy/app/views/ip_addresses/index.html.haml +12 -0
- data/spec/dummy/app/views/ip_addresses/show.html.haml +1 -0
- data/spec/dummy/app/views/layouts/_navbar.html.haml +11 -0
- data/spec/dummy/app/views/layouts/application.html.haml +53 -0
- data/spec/dummy/app/views/layouts/public.html.haml +41 -0
- data/spec/dummy/app/views/master/companies/_form.html.haml +19 -0
- data/spec/dummy/app/views/master/companies/edit.html.haml +7 -0
- data/spec/dummy/app/views/master/companies/index.html.haml +25 -0
- data/spec/dummy/app/views/master/companies/new.html.haml +5 -0
- data/spec/dummy/app/views/master/companies/show.html.haml +12 -0
- data/spec/dummy/app/views/master/dashboard/index.html.haml +2 -0
- data/spec/dummy/app/views/public/forbidden.html.haml +3 -0
- data/spec/dummy/app/views/public/index.html.haml +2 -0
- data/spec/dummy/app/views/subdomain/index.html.haml +2 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +40 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +26 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/handcart.json +6 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/handcart.rb +16 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +12 -0
- data/spec/dummy/config/routes.rb +23 -0
- data/spec/dummy/db/migrate/20131010194534_create_companies.rb +10 -0
- data/spec/dummy/db/migrate/20131016183624_add_active_to_companies.rb +5 -0
- data/spec/dummy/db/schema.rb +41 -0
- data/spec/dummy/log/development.log +14 -0
- data/spec/dummy/log/test.log +786 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/spec/models/company_spec.rb +36 -0
- data/spec/dummy/spec/routing/custom_constraints_routing_spec.rb +37 -0
- data/spec/dummy/tmp/cache/assets/development/sass/27d34b7cbcb5b92ab03220c4d4b91379cc64c2c0/layout.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/dc98e44780f42e6521ebbf14c4db22f6a78c41ef/layout.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/05974a1f812cf4a61bb242d48722fd19 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/063a74a7c73c9501ee373ef00111f159 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/073d2b13ed9366ce539940749eb3844d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0d76367ded60510a66afc3dea891e76a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/106c3f4e1fc71e9dc70abae55d432886 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13ae4613233656a42188d4d3ddbb7fc1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/18c826ba1d6dac1633cae2da25c0402a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/247df6a90ce931f763db1ade5227d4b1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2860df473a6cf4c483cd6f251fea3ae0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2a99072e783dcef4637b38221531ea61 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2ab4b3177ab6c9d837c0905b61eedad5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2b84c9cc30f71e24310dd1a4381caae8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2bebf0981bc585e24939ca8ffe10081c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2c45a1517014fd239c930e48a71a93f0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2d5147f4ea70131b4e330cab38aeb1a1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3124588878c79981009129f32d5fe408 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/33325c558d8db2071bf8a938517e5af2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/350c8c72b1dbd7a84f85424b5cd4def1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3a3d69c38e3b3d20e94420ebebd05a69 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3b1656b46a35a6120c3407b930d468ba +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3c0fc39d9b84afb4937545b620cd2d72 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3fa878a57cb0b42be266336564609b18 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/40f26b5e75d0f747e691c0b38529fb59 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/42aa8e53e39d8f5247f1b3e89cb00adc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/42e1f4c72bf58cf112dd11eae8ee768b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/433be3db83a4d9f93f5d1fa2ae3bde4e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4b6f9f46d7a2e230321d7f8df06ea470 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4c17c77b444339bb3ab293047da0ff0d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4ee93c096bb850d38032eb457afebf69 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4f25edc4354919ba67721f488ba10e12 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/58fb821d4a4a44fdb2a89d4f487a8390 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5f97a76ac644497413f4c8dc547ddea6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6076ab56e9c62fd04155d6f6c43e575e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/60b75d9635ed84e08a0b9a245d8a3202 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/64ad9f343408809fdfb1df851186853d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6e79870e51ea835a6847f8c65e23e14b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6e9d2e7aafa45c939731291fa453b8c2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/78f915513059378e161ceb6f2d14fbd9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8102cf6724f489a310fe3a6b764bb2e9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/81108a1123b15b10c7f7f2e0d1207267 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/81b3dcc0aa61577b08de13ba5633dbc4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/83e686634b5ac6d4b183677ed2edda8b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8581aae276f167a9b7b2158641b0bf87 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/94cb3819408e525700729fbd473432c8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/99eb5e50b6d0e5d0d6b6c37cbde33864 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a7c86e9a777f7789dd1c78d26a662a87 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a9e19eb45005fa24bc8b90b6a374089f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ac4492393938e58cede2b6277afb0bc6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ad1d96635f4dae7eb22d1984947d7440 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/af718c632887ccb6c1c35c4b65c61293 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b2f45720a78d375468b99bb25f121c4e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b559f2694561fc6c44e3319f507de1e7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b6e8c6ba59755a8fe132457f81065f96 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b796b57f310287a7a619afa9d5b99952 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b7c36a1c00d7804d9e827d704c0dd811 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bc28a210f3df576c74059aff8233eae3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bc414fbd5123e40c4f5e69f4c294f489 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c0181c32e0ed10ec8fa3049f9a80f551 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c17130f66131c854d6f8c2196902b596 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c4c0e10aa5c21ece42c0bfe998a5d8c0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c63bcc000975adbdf423db3ad43eb93f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c962f9220062a6407dfc7d9447565273 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cb8b538b6fce61b500edebe63156bf62 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cfcef2015b7df990ed90006632877389 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cff56d2d0a8b8a25d4b0388d242be9c8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d32fc7356f764b22ecbcebbcb9b47ee1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d776667bae72eb3d582da5803fc931ca +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/dfc307d14a0cf64cf8c3a4e94fdbcfb9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e4b6570b82329477bc7043183b64b105 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/eff1316ad12dd5b8f4cbf0ba9e448229 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f2348b747b81ca6e3a24d5bd0b7023c4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f6f921309fcc78b6850abcf2418279fe +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7e1dbf50c19c9d439de52caa4296164 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ff2adfc3ed446b68ac2d0077e8af34e2 +0 -0
- data/spec/factories/companies.rb +7 -0
- data/spec/factories/handcart_ip_addresses.rb +8 -0
- data/spec/factories/handcart_subdomains.rb +5 -0
- data/spec/models/handcart/base_ip_strategy_spec.rb +23 -0
- data/spec/models/handcart/containment_strategy_spec.rb +23 -0
- data/spec/models/handcart/domain_constraint_spec.rb +38 -0
- data/spec/models/handcart/engine_spec.rb +14 -0
- data/spec/models/handcart/handcart_spec.rb +38 -0
- data/spec/models/handcart/inclusion_strategy_spec.rb +29 -0
- data/spec/models/handcart/ip_address_spec.rb +51 -0
- data/spec/models/handcart/ip_authorization_spec.rb +17 -0
- data/spec/models/handcart/subdomain_spec.rb +153 -0
- data/spec/routing/handcart/ip_addresses_routing_spec.rb +38 -0
- data/spec/routing/handcart/subdomains_routing_spec.rb +38 -0
- data/spec/spec_helper.rb +65 -0
- data/spec/support/subdomains.rb +26 -0
- metadata +565 -0
checksums.yaml
ADDED
|
@@ -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
|
data/MIT-LICENSE
ADDED
|
@@ -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.
|
data/README.md
ADDED
|
@@ -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.
|
data/Rakefile
ADDED
|
@@ -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,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
|