embargoed 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ require 'pathname'
2
+ module Embargoed
3
+ module MaintenancePage
4
+ require 'rack/accept'
5
+
6
+ def self.all
7
+ @all ||= []
8
+ end
9
+
10
+ def self.best_for(env)
11
+ request = Rack::Accept::Request.new(env)
12
+
13
+ all_types = all.map(&:media_types).flatten
14
+ best_type = request.best_media_type(all_types)
15
+ best = all.find { |page| page.media_types.include?(best_type) && File.exist?(page.new.custom_path) }
16
+ best || Embargoed.config.default_maintenance_page
17
+ end
18
+
19
+ require 'embargoed/maintenance_page/base'
20
+ require 'embargoed/maintenance_page/erb'
21
+ require 'embargoed/maintenance_page/html'
22
+ require 'embargoed/maintenance_page/json'
23
+ end
24
+ end
@@ -0,0 +1,98 @@
1
+ module Embargoed
2
+ class OrderedOptions < Hash
3
+ alias_method :_get, :[] # preserve the original #[] method
4
+ protected :_get # make it protected
5
+
6
+ def initialize(constructor = {}, &block)
7
+ if constructor.respond_to?(:to_hash)
8
+ super()
9
+ update(constructor, &block)
10
+ hash = constructor.to_hash
11
+
12
+ self.default = hash.default if hash.default
13
+ self.default_proc = hash.default_proc if hash.default_proc
14
+ else
15
+ super()
16
+ end
17
+ end
18
+
19
+ def update(other_hash)
20
+ if other_hash.is_a? Hash
21
+ super(other_hash)
22
+ else
23
+ other_hash.to_hash.each_pair do |key, value|
24
+ if block_given?
25
+ value = yield(key, value)
26
+ end
27
+ self[key] = value
28
+ end
29
+ self
30
+ end
31
+ end
32
+
33
+ def []=(key, value)
34
+ super(key.to_sym, value)
35
+ end
36
+
37
+ def [](key)
38
+ super(key.to_sym)
39
+ end
40
+
41
+ def method_missing(name, *args)
42
+ name_string = name.to_s
43
+ if name_string.chomp!('=')
44
+ self[name_string] = args.first
45
+ else
46
+ bangs = name_string.chomp!('!')
47
+
48
+ if bangs
49
+ value = fetch(name_string.to_sym)
50
+ raise(RuntimeError.new("#{name_string} is blank.")) if value.nil? || value.empty?
51
+ value
52
+ else
53
+ self[name_string]
54
+ end
55
+ end
56
+ end
57
+
58
+ def except(*keys)
59
+ dup.except!(*keys)
60
+ end
61
+
62
+ def except!(*keys)
63
+ keys.each { |key| delete(key) }
64
+ self
65
+ end
66
+
67
+
68
+ def respond_to_missing?(name, include_private)
69
+ true
70
+ end
71
+ end
72
+
73
+
74
+ # +InheritableOptions+ provides a constructor to build an +OrderedOptions+
75
+ # hash inherited from another hash.
76
+ #
77
+ # Use this if you already have some hash and you want to create a new one based on it.
78
+ #
79
+ # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
80
+ # h.girl # => 'Mary'
81
+ # h.boy # => 'John'
82
+ class InheritableOptions < Embargoed::OrderedOptions
83
+ def initialize(parent = nil)
84
+ if parent.kind_of?(Embargoed::OrderedOptions)
85
+ # use the faster _get when dealing with OrderedOptions
86
+ super(parent) {|key,value| parent._get(key) }
87
+ elsif parent
88
+ super(parent) { |key, value| parent[key] }
89
+ else
90
+ super(parent)
91
+ end
92
+ end
93
+
94
+ def inheritable_copy
95
+ self.class.new(self)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,3 @@
1
+ # This file is meant to be used to include rake tasks in a Rakefile by adding
2
+ # require 'embargoed/rake_tasks'
3
+ Dir[File.expand_path('../../tasks/*.rake', __FILE__)].each { |ext| import ext }
@@ -0,0 +1,39 @@
1
+ require 'ipaddr'
2
+
3
+ module Embargoed
4
+ class Request
5
+ def initialize(env)
6
+ @rack_request = Rack::Request.new(env)
7
+ end
8
+
9
+ def allowed?
10
+ path_allowed? || ip_allowed?
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :rack_request
16
+
17
+ def path_allowed?
18
+ allowed_paths = []
19
+
20
+ allowed_paths.any? do |allowed_path|
21
+ rack_request.path =~ Regexp.new(allowed_path)
22
+ end
23
+ end
24
+
25
+ def ip_allowed?
26
+
27
+ begin
28
+ ip = IPAddr.new(rack_request.ip.to_s)
29
+ rescue ArgumentError
30
+ return false
31
+ end
32
+
33
+ ip_country_code = IPLocator.get_country_code(ip)
34
+
35
+ ip_country_code != "RU"
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Embargoed
2
+ VERSION = '2.5.0'.freeze
3
+ end
data/lib/embargoed.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Embargoed
2
+ require 'embargoed/configuration'
3
+ require 'embargoed/maintenance_file'
4
+ require 'embargoed/maintenance_page'
5
+ require 'embargoed/request'
6
+ require 'embargoed/ip_locator'
7
+ require 'embargoed/engine' if defined? Rails
8
+
9
+ def self.configure
10
+ yield config
11
+ end
12
+
13
+ def self.config
14
+ @config ||= Configuration.new
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ require 'rack'
2
+ require 'embargoed'
3
+
4
+ class Rack::Embargoed
5
+ def initialize(app, config={})
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ request = Embargoed::Request.new(env)
11
+
12
+ if !request.allowed?
13
+ page_class = Embargoed::MaintenancePage.best_for(env)
14
+ page = page_class.new("Reason", env: env)
15
+
16
+ page.rack_response(503, 7200)
17
+ else
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,48 @@
1
+ require 'embargoed'
2
+
3
+ namespace :maintenance do
4
+ desc 'Enable the maintenance mode page ("reason", "allowed_paths", "allowed_ips" and "response_code" can be passed as environment variables)'
5
+ rule /\Amaintenance:(.*:|)start\Z/ do |task|
6
+ invoke_environment
7
+
8
+ maint_file = maintenance_file_for(task)
9
+ maint_file.import_env_vars(ENV)
10
+ maint_file.write
11
+
12
+ puts "Created #{maint_file.path}"
13
+ puts "Run `rake #{task.name.gsub(/\:start/, ':end')}` to stop maintenance mode"
14
+ end
15
+
16
+ desc 'Disable the maintenance mode page'
17
+ rule /\Amaintenance:(.*:|)end\Z/ do |task|
18
+ invoke_environment
19
+
20
+ maint_file = maintenance_file_for(task)
21
+
22
+ if maint_file.delete
23
+ puts "Deleted #{maint_file.path}"
24
+ else
25
+ fail 'Could not find a maintenance file to delete'
26
+ end
27
+ end
28
+
29
+ def invoke_environment
30
+ if Rake::Task.task_defined? 'environment'
31
+ Rake::Task['environment'].invoke
32
+ end
33
+ end
34
+
35
+ def maintenance_file_for(task)
36
+ path_name = (task.name.split(':') - ['maintenance', 'start', 'end']).join(':')
37
+
38
+ maint_file = if path_name == ''
39
+ Embargoed::MaintenanceFile.default
40
+ else
41
+ Embargoed::MaintenanceFile.named(path_name)
42
+ end
43
+
44
+ fail %{Unknown path name: "#{path_name}"} if maint_file.nil?
45
+
46
+ maint_file
47
+ end
48
+ end
Binary file
Binary file
@@ -0,0 +1,206 @@
1
+ The file [`Geoacumen-Country.mmdb`](https://github.com/geoacumen/geoacumen-country) is distributed under an Apache License Version 2.0.
2
+
3
+ As per the license, we must also give a copy of the license under which that file is distributed, which can be found below:
4
+
5
+
6
+ Apache License
7
+ Version 2.0, January 2004
8
+ http://www.apache.org/licenses/
9
+
10
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
11
+
12
+ 1. Definitions.
13
+
14
+ "License" shall mean the terms and conditions for use, reproduction,
15
+ and distribution as defined by Sections 1 through 9 of this document.
16
+
17
+ "Licensor" shall mean the copyright owner or entity authorized by
18
+ the copyright owner that is granting the License.
19
+
20
+ "Legal Entity" shall mean the union of the acting entity and all
21
+ other entities that control, are controlled by, or are under common
22
+ control with that entity. For the purposes of this definition,
23
+ "control" means (i) the power, direct or indirect, to cause the
24
+ direction or management of such entity, whether by contract or
25
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
26
+ outstanding shares, or (iii) beneficial ownership of such entity.
27
+
28
+ "You" (or "Your") shall mean an individual or Legal Entity
29
+ exercising permissions granted by this License.
30
+
31
+ "Source" form shall mean the preferred form for making modifications,
32
+ including but not limited to software source code, documentation
33
+ source, and configuration files.
34
+
35
+ "Object" form shall mean any form resulting from mechanical
36
+ transformation or translation of a Source form, including but
37
+ not limited to compiled object code, generated documentation,
38
+ and conversions to other media types.
39
+
40
+ "Work" shall mean the work of authorship, whether in Source or
41
+ Object form, made available under the License, as indicated by a
42
+ copyright notice that is included in or attached to the work
43
+ (an example is provided in the Appendix below).
44
+
45
+ "Derivative Works" shall mean any work, whether in Source or Object
46
+ form, that is based on (or derived from) the Work and for which the
47
+ editorial revisions, annotations, elaborations, or other modifications
48
+ represent, as a whole, an original work of authorship. For the purposes
49
+ of this License, Derivative Works shall not include works that remain
50
+ separable from, or merely link (or bind by name) to the interfaces of,
51
+ the Work and Derivative Works thereof.
52
+
53
+ "Contribution" shall mean any work of authorship, including
54
+ the original version of the Work and any modifications or additions
55
+ to that Work or Derivative Works thereof, that is intentionally
56
+ submitted to Licensor for inclusion in the Work by the copyright owner
57
+ or by an individual or Legal Entity authorized to submit on behalf of
58
+ the copyright owner. For the purposes of this definition, "submitted"
59
+ means any form of electronic, verbal, or written communication sent
60
+ to the Licensor or its representatives, including but not limited to
61
+ communication on electronic mailing lists, source code control systems,
62
+ and issue tracking systems that are managed by, or on behalf of, the
63
+ Licensor for the purpose of discussing and improving the Work, but
64
+ excluding communication that is conspicuously marked or otherwise
65
+ designated in writing by the copyright owner as "Not a Contribution."
66
+
67
+ "Contributor" shall mean Licensor and any individual or Legal Entity
68
+ on behalf of whom a Contribution has been received by Licensor and
69
+ subsequently incorporated within the Work.
70
+
71
+ 2. Grant of Copyright License. Subject to the terms and conditions of
72
+ this License, each Contributor hereby grants to You a perpetual,
73
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
74
+ copyright license to reproduce, prepare Derivative Works of,
75
+ publicly display, publicly perform, sublicense, and distribute the
76
+ Work and such Derivative Works in Source or Object form.
77
+
78
+ 3. Grant of Patent License. Subject to the terms and conditions of
79
+ this License, each Contributor hereby grants to You a perpetual,
80
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
81
+ (except as stated in this section) patent license to make, have made,
82
+ use, offer to sell, sell, import, and otherwise transfer the Work,
83
+ where such license applies only to those patent claims licensable
84
+ by such Contributor that are necessarily infringed by their
85
+ Contribution(s) alone or by combination of their Contribution(s)
86
+ with the Work to which such Contribution(s) was submitted. If You
87
+ institute patent litigation against any entity (including a
88
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
89
+ or a Contribution incorporated within the Work constitutes direct
90
+ or contributory patent infringement, then any patent licenses
91
+ granted to You under this License for that Work shall terminate
92
+ as of the date such litigation is filed.
93
+
94
+ 4. Redistribution. You may reproduce and distribute copies of the
95
+ Work or Derivative Works thereof in any medium, with or without
96
+ modifications, and in Source or Object form, provided that You
97
+ meet the following conditions:
98
+
99
+ (a) You must give any other recipients of the Work or
100
+ Derivative Works a copy of this License; and
101
+
102
+ (b) You must cause any modified files to carry prominent notices
103
+ stating that You changed the files; and
104
+
105
+ (c) You must retain, in the Source form of any Derivative Works
106
+ that You distribute, all copyright, patent, trademark, and
107
+ attribution notices from the Source form of the Work,
108
+ excluding those notices that do not pertain to any part of
109
+ the Derivative Works; and
110
+
111
+ (d) If the Work includes a "NOTICE" text file as part of its
112
+ distribution, then any Derivative Works that You distribute must
113
+ include a readable copy of the attribution notices contained
114
+ within such NOTICE file, excluding those notices that do not
115
+ pertain to any part of the Derivative Works, in at least one
116
+ of the following places: within a NOTICE text file distributed
117
+ as part of the Derivative Works; within the Source form or
118
+ documentation, if provided along with the Derivative Works; or,
119
+ within a display generated by the Derivative Works, if and
120
+ wherever such third-party notices normally appear. The contents
121
+ of the NOTICE file are for informational purposes only and
122
+ do not modify the License. You may add Your own attribution
123
+ notices within Derivative Works that You distribute, alongside
124
+ or as an addendum to the NOTICE text from the Work, provided
125
+ that such additional attribution notices cannot be construed
126
+ as modifying the License.
127
+
128
+ You may add Your own copyright statement to Your modifications and
129
+ may provide additional or different license terms and conditions
130
+ for use, reproduction, or distribution of Your modifications, or
131
+ for any such Derivative Works as a whole, provided Your use,
132
+ reproduction, and distribution of the Work otherwise complies with
133
+ the conditions stated in this License.
134
+
135
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
136
+ any Contribution intentionally submitted for inclusion in the Work
137
+ by You to the Licensor shall be under the terms and conditions of
138
+ this License, without any additional terms or conditions.
139
+ Notwithstanding the above, nothing herein shall supersede or modify
140
+ the terms of any separate license agreement you may have executed
141
+ with Licensor regarding such Contributions.
142
+
143
+ 6. Trademarks. This License does not grant permission to use the trade
144
+ names, trademarks, service marks, or product names of the Licensor,
145
+ except as required for reasonable and customary use in describing the
146
+ origin of the Work and reproducing the content of the NOTICE file.
147
+
148
+ 7. Disclaimer of Warranty. Unless required by applicable law or
149
+ agreed to in writing, Licensor provides the Work (and each
150
+ Contributor provides its Contributions) on an "AS IS" BASIS,
151
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
152
+ implied, including, without limitation, any warranties or conditions
153
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
154
+ PARTICULAR PURPOSE. You are solely responsible for determining the
155
+ appropriateness of using or redistributing the Work and assume any
156
+ risks associated with Your exercise of permissions under this License.
157
+
158
+ 8. Limitation of Liability. In no event and under no legal theory,
159
+ whether in tort (including negligence), contract, or otherwise,
160
+ unless required by applicable law (such as deliberate and grossly
161
+ negligent acts) or agreed to in writing, shall any Contributor be
162
+ liable to You for damages, including any direct, indirect, special,
163
+ incidental, or consequential damages of any character arising as a
164
+ result of this License or out of the use or inability to use the
165
+ Work (including but not limited to damages for loss of goodwill,
166
+ work stoppage, computer failure or malfunction, or any and all
167
+ other commercial damages or losses), even if such Contributor
168
+ has been advised of the possibility of such damages.
169
+
170
+ 9. Accepting Warranty or Additional Liability. While redistributing
171
+ the Work or Derivative Works thereof, You may choose to offer,
172
+ and charge a fee for, acceptance of support, warranty, indemnity,
173
+ or other liability obligations and/or rights consistent with this
174
+ License. However, in accepting such obligations, You may act only
175
+ on Your own behalf and on Your sole responsibility, not on behalf
176
+ of any other Contributor, and only if You agree to indemnify,
177
+ defend, and hold each Contributor harmless for any liability
178
+ incurred by, or claims asserted against, such Contributor by reason
179
+ of your accepting any such warranty or additional liability.
180
+
181
+ END OF TERMS AND CONDITIONS
182
+
183
+ APPENDIX: How to apply the Apache License to your work.
184
+
185
+ To apply the Apache License to your work, attach the following
186
+ boilerplate notice, with the fields enclosed by brackets "[]"
187
+ replaced with your own identifying information. (Don't include
188
+ the brackets!) The text should be enclosed in the appropriate
189
+ comment syntax for the file format. We also recommend that a
190
+ file or class name and description of purpose be included on the
191
+ same "printed page" as the copyright notice for easier
192
+ identification within third-party archives.
193
+
194
+ Copyright 2020 Kevin Chung
195
+
196
+ Licensed under the Apache License, Version 2.0 (the "License");
197
+ you may not use this file except in compliance with the License.
198
+ You may obtain a copy of the License at
199
+
200
+ http://www.apache.org/licenses/LICENSE-2.0
201
+
202
+ Unless required by applicable law or agreed to in writing, software
203
+ distributed under the License is distributed on an "AS IS" BASIS,
204
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
205
+ See the License for the specific language governing permissions and
206
+ limitations under the License.
@@ -0,0 +1,62 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Page blocked for πŸ‡·πŸ‡Ί Russian visitors</title>
6
+
7
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
8
+
9
+
10
+ <style type="text/css">
11
+
12
+ *{
13
+ font-family: Lato, Arial, Helvetica, sans-serif;
14
+ }
15
+
16
+ body{
17
+ margin: 0;
18
+ background-color: #f6f9fc;
19
+ height: 100vh;
20
+ }
21
+
22
+ .card{
23
+ position: relative;
24
+ padding: 3em 3em;
25
+ text-align: center;
26
+ background: #ffffff;
27
+ color: rgb(66, 84, 102);
28
+ box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px;
29
+ border-radius: 8px;
30
+ }
31
+
32
+ h1{
33
+ margin: 0;
34
+ color: #242424;
35
+ font-size: 26pt;
36
+ margin-bottom: 1em;
37
+ font-weight: bolder;
38
+ }
39
+
40
+ </style>
41
+
42
+ </head>
43
+ <body>
44
+
45
+ <div class="container h-100">
46
+ <div class="row align-items-center h-100">
47
+ <div class="col-12 col-md-8 offset-md-1 col-lg-6 offset-lg-3 mx-auto">
48
+ <div class="card">
49
+ <h1>We're sorry, Russians.</h1>
50
+
51
+ <p>We've blocked this website for Russian visitors.</p>
52
+ <p>On Feb 24, 2022 Russian forces started invading Ukraine. We know you, a regular person, are not to blame. But your leaders have chosen a very violent path breaking international law, and we've chosen not to do business with Russian citizens at the time. We condemn this crime.</p>
53
+ <p>We don't like this situation either, and we'd love to do business with Russia again soon. But only you can make it stop.</p>
54
+ <p><b>Protest in social media and in the streets</b> to demand your leaders stop this invasion. Peace and diplomacy are the only way forward.</p>
55
+ <p>πŸ‡ΊπŸ‡¦ Slava Ukraini</p>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </div>
60
+
61
+ </body>
62
+ </html>
@@ -0,0 +1,69 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Down for Maintenance</title>
6
+
7
+ <style type="text/css">
8
+
9
+ *{
10
+ font-family: Arial, Helvetica, sans-serif;
11
+ }
12
+
13
+ body{
14
+ margin: 0;
15
+ background-color: #fff;
16
+ }
17
+
18
+ #page{
19
+ position: relative;
20
+ width: 550px;
21
+ margin: 200px auto;
22
+ padding: 75px 0;
23
+ text-align: center;
24
+ background-color: #eaeaea;
25
+ border: solid 1px #ccc;
26
+ border-top: solid 10px #666;
27
+ -moz-box-shadow: inset 0 2px 10px #ccc;
28
+ -webkit-box-shadow: inset 0 2px 10px #ccc;
29
+ box-shadow: inset 0 2px 10px #ccc;
30
+ }
31
+
32
+ header, #body{
33
+ width: 400px;
34
+ margin: 0 auto;
35
+ }
36
+
37
+ h1{
38
+ margin: 0;
39
+ color: #CC3601;
40
+ font-size: 26pt;
41
+ border-bottom: solid 4px #666;
42
+ }
43
+
44
+ #reason{
45
+ margin: 10px 0;
46
+ color: #333;
47
+ }
48
+
49
+ </style>
50
+
51
+ </head>
52
+ <body>
53
+
54
+ <section id="page">
55
+
56
+ <header>
57
+ <h1>Down for Maintenance</h1>
58
+ </header>
59
+
60
+ <section id="body">
61
+ <div>
62
+ <%= reason %>
63
+ </div>
64
+ </section>
65
+
66
+ </section>
67
+
68
+ </body>
69
+ </html>
@@ -0,0 +1 @@
1
+ {"error":"Service Unavailable","message":{{ reason }}}