mission_control-web 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +122 -15
  4. data/Rakefile +21 -3
  5. data/app/assets/config/mission_control_web_manifest.js +2 -0
  6. data/app/assets/stylesheets/mission_control/web/application.css +15 -0
  7. data/app/assets/stylesheets/mission_control/web/vendor/bulma.min.css +1 -0
  8. data/app/controllers/concerns/mission_control/web/application_scoped.rb +17 -0
  9. data/app/controllers/mission_control/web/application_controller.rb +4 -0
  10. data/app/controllers/mission_control/web/errors_controller.rb +6 -0
  11. data/app/controllers/mission_control/web/routes_controller.rb +52 -0
  12. data/app/helpers/mission_control/web/applications_helper.rb +9 -0
  13. data/app/helpers/mission_control/web/routes_helper.rb +9 -0
  14. data/app/javascript/mission_control/web/application.js +1 -0
  15. data/app/models/concerns/mission_control/web/route/applications.rb +17 -0
  16. data/app/models/mission_control/web/application/routes.rb +24 -0
  17. data/app/models/mission_control/web/application.rb +34 -0
  18. data/app/models/mission_control/web/application_record.rb +3 -0
  19. data/app/models/mission_control/web/current.rb +8 -0
  20. data/app/models/mission_control/web/route.rb +14 -0
  21. data/app/views/layouts/mission_control/web/application.html.erb +23 -0
  22. data/app/views/mission_control/web/application/_current_application_selector.html.erb +15 -0
  23. data/app/views/mission_control/web/application/_flash.html.erb +3 -0
  24. data/app/views/mission_control/web/application/_form_errors.html.erb +11 -0
  25. data/app/views/mission_control/web/application/_navbar.html.erb +14 -0
  26. data/app/views/mission_control/web/errors/disallowed.html.erb +8 -0
  27. data/app/views/mission_control/web/routes/_form.html.erb +26 -0
  28. data/app/views/mission_control/web/routes/_route.html.erb +13 -0
  29. data/app/views/mission_control/web/routes/edit.html.erb +8 -0
  30. data/app/views/mission_control/web/routes/index.html.erb +27 -0
  31. data/app/views/mission_control/web/routes/new.html.erb +8 -0
  32. data/app/views/mission_control/web/routes/show.html.erb +42 -0
  33. data/config/importmap.rb +2 -0
  34. data/config/routes.rb +7 -0
  35. data/db/migrate/20221025093008_create_mission_control_web_routes.rb +14 -0
  36. data/lib/generators/mission_control/web/install/admin_generator.rb +38 -0
  37. data/lib/generators/mission_control/web/install/middleware_generator.rb +26 -0
  38. data/lib/generators/mission_control/web/install_generator.rb +6 -0
  39. data/lib/mission_control/web/action_dispatch_request.rb +7 -0
  40. data/lib/mission_control/web/bulma_form_builder.rb +50 -0
  41. data/lib/mission_control/web/configuration.rb +21 -0
  42. data/lib/mission_control/web/engine.rb +45 -0
  43. data/lib/mission_control/web/errors/resource_not_found.rb +2 -0
  44. data/lib/mission_control/web/request_filter.rb +17 -0
  45. data/lib/mission_control/web/request_filter_middleware.rb +26 -0
  46. data/lib/mission_control/web/routes_cache.rb +52 -0
  47. data/lib/mission_control/web/version.rb +1 -3
  48. data/lib/mission_control/web.rb +18 -4
  49. data/lib/tasks/mission_control/web_tasks.rake +4 -0
  50. metadata +147 -8
  51. data/LICENSE.txt +0 -21
  52. data/mission_control-web.gemspec +0 -35
  53. data/sig/mission_control/web.rbs +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55a15e8774db77d237cc2774713fffddc56311462282805c723ed49c3f2514c8
4
- data.tar.gz: 220c96b20fdde502187c4e88099c8713ee1394413ab8e6d0540ad2069b6942fd
3
+ metadata.gz: 263fd9deb28663f3a334c57d836127d45e9acfb9c2c7cb542659715ce23bcef2
4
+ data.tar.gz: 38867c05c69375966ae4512fe39ea7769938843c043776c23b4b2d52ba1490b9
5
5
  SHA512:
6
- metadata.gz: 8acd06b3debdca5db4cfc6d22ee6c4d6d2df6f7091ffcb865503d38835a8e832d52711a87e5179c2ae2535a6cab17594e320d57c7c1a972d854fc8927cfb5857
7
- data.tar.gz: c4260b3d1ddaf75e1a92aaf592adbe32e2a2f76f6df1341395daad2e719044012cdfc239076228aa4d72ed7b0ebd7a8b1aa1b0e821c91994bbd2502809a5fc01
6
+ metadata.gz: '08dfb3c27a1acc73a75be00ed3331412451913692fcefa539f2da96ee1a821b2959abdf21927193d0a3b16fc5a3a090fc9c281271cf578f1c69a4b522dcdf8b7'
7
+ data.tar.gz: dae3c2f2ff15c3b39e5a640cc0486a090557bf36c2bcfeb119e1eea45cc34bffc996a06ede592be861435a1daf00170351389b776637f608e17862b00b5a1b75
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 37signals, LLC
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 CHANGED
@@ -1,34 +1,141 @@
1
- # MissionControl::Web
1
+ # Mission Control - Web
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
3
+ This gem provides a Rails-based frontend and middleware to deny access to particular parts of your application. This is
4
+ especially useful in an incident response scenario such as deployment of unperformant code, or a denial of service
5
+ attack.
4
6
 
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mission_control/web`. To experiment with that code, run `bin/console` for an interactive prompt.
7
+ <img width="952" alt="Screenshot of Mission Control - Web admin UI" src="https://github.com/basecamp/mission_control-web/assets/1773614/5c75a304-820e-4151-882e-f0782211356c">
8
+
9
+ ## How it works
10
+
11
+ Mission Control - Web can be configured via the admin interface to block requests whose path matched a regex pattern. If
12
+ the requested path matches any "Denied" path, it will be blocked with a 503 HTTP status code.
13
+
14
+ ## Usage
15
+
16
+ You can choose to deploy Mission Control - Web admin and middleware both in the same Rails app, or two separate apps, a
17
+ protected Rails app and an admin app.
18
+
19
+ The benefit of using two separate apps is that if your protected app is attacked or suffers a performance issue, it may
20
+ become inaccessible while an admin app does not.
6
21
 
7
22
  ## Installation
8
23
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
24
+ Add this line to your application's Gemfile:
10
25
 
11
- Install the gem and add to the application's Gemfile by executing:
26
+ ```ruby
27
+ gem "mission_control-web"
28
+ ```
12
29
 
13
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
30
+ And then execute:
31
+ ```bash
32
+ $ bundle
33
+ ```
14
34
 
15
- If bundler is not being used to manage dependencies, install the gem by executing:
35
+ then, follow the instructions below for a single app, or a separate admin app.
16
36
 
17
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
37
+ ## Installation in a single app
18
38
 
19
- ## Usage
39
+ And then execute:
40
+ ```bash
41
+ $ bin/rails generate mission_control:web:install
42
+ ```
43
+
44
+ ## Installation with two apps, admin and protected
45
+
46
+ After adding the `mission_control-web` gem, in your admin app:
47
+
48
+ ```bash
49
+ $ bin/rails generate mission_control:web:install:admin
50
+ ```
51
+
52
+ and in your protected Rails app:
53
+
54
+ ```bash
55
+ $ bin/rails generate mission_control:web:install:middleware
56
+ ```
57
+
58
+ ## Configuration
59
+
60
+ ### Redis client
61
+
62
+ Configure Mission Control - Web with a Redis client.
63
+
64
+ ```rb
65
+ # config/initializers/mission_control_web.rb
66
+
67
+ config.mission_control.web.redis = Redis.new(url: "redis://server:6379/0")
68
+ ```
69
+
70
+ ### Administered applications
71
+
72
+ ```rb
73
+ config.mission_control.web.administered_applications = [ { name: "My Rails App", redis: Redis.new(url: "redis://server:6379/0") } ]
74
+ ```
75
+
76
+ ### Authentication and base controller class
77
+
78
+ By default, Mission Control's controllers will extend the host app's ApplicationController. If no authentication is
79
+ enforced, the admin pages will be available to everyone. You might want to implement some kind of authentication for
80
+ this in your app. To make this easier, you can specify a different controller as the base class for Mission Control's
81
+ controllers:
82
+
83
+ ```rb
84
+ config.mission_control.web.base_controller_class = "AdminController"
85
+ ```
86
+
87
+ ### Custom "denied" page
88
+
89
+ You can configure a custom page to show to users when a request is denied by Mission Control - Web. Configure this like
90
+ so:
91
+
92
+ ```rb
93
+ config.mission_control.web.errors_controller = MissionControl::Web::CustomErrorsController
94
+ ```
95
+
96
+ Then, in your application, create a custom errors controller:
97
+
98
+ ```rb
99
+ class MissionControl::Web::CustomErrorsController < MissionControl::Web::ErrorsController
100
+ def disallowed
101
+ render file: "public/503.html"
102
+ end
103
+ end
104
+ ```
105
+
106
+ ### Other configuration
107
+
108
+ Useful for disabling the Mission Control - Web request intercept middleware on a per-application or per-environment basis:
109
+
110
+ ```rb
111
+ config.mission_control.web.middleware_enabled = false
112
+ ```
113
+
114
+ Denied paths are cached by the middleware and refreshed from Redis on this interval. With this configuration, it takes up to 10 seconds for path denial to take effect:
115
+
116
+ ```rb
117
+ config.mission_control.web.routes_cache_ttl = 10.seconds
118
+ ```
119
+
120
+ ## Testing
121
+
122
+ Run:
20
123
 
21
- TODO: Write usage instructions here
124
+ ```sh
125
+ rake test
126
+ ```
22
127
 
23
- ## Development
128
+ Performance tests can be run in the "profile" environment for more consistent results with:
24
129
 
25
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
130
+ ```sh
131
+ RAILS_ENV=profile rake test:performance
132
+ ```
26
133
 
27
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
134
+ ## Resiliency
28
135
 
29
- ## Contributing
136
+ If Redis is down (or raises any instance of Redis::BaseConnectionError), Mission Control Web middleware will fail-open.
30
137
 
31
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mission_control-web.
138
+ It's recommended to also consider using a resilient Redis client with a circuit-breaker. See [Semian](https://github.com/Shopify/semian).
32
139
 
33
140
  ## License
34
141
 
data/Rakefile CHANGED
@@ -1,8 +1,26 @@
1
- # frozen_string_literal: true
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
2
7
 
3
8
  require "bundler/gem_tasks"
4
- require "minitest/test_task"
5
9
 
6
- Minitest::TestTask.create
10
+ require "rake/testtask"
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << "test"
14
+ t.test_files = FileList["test/**/*_test.rb"].exclude("test/performance/**/*")
15
+ t.verbose = false
16
+ end
17
+
18
+ namespace :test do
19
+ Rake::TestTask.new(:performance) do |t|
20
+ t.libs << "test"
21
+ t.test_files = FileList["test/performance/**/*_test.rb"]
22
+ t.verbose = false
23
+ end
24
+ end
7
25
 
8
26
  task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../stylesheets/mission_control/web .css
2
+ //= link_directory ../../javascript/mission_control/web .js
@@ -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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */