豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit c7b6f8d

Browse files
committed
Merge remote-tracking branch 'origin/main' into deny-actors
2 parents 6d246e7 + bf47515 commit c7b6f8d

File tree

9 files changed

+141
-6
lines changed

9 files changed

+141
-6
lines changed

lib/flipper/adapters/http.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def get_all(cache_bust: false)
6565
path += "&_cb=#{Time.now.to_i}" if cache_bust
6666
etag = @get_all_mutex.synchronize { @last_get_all_etag }
6767

68-
if etag
68+
if etag && !cache_bust
6969
options[:headers] = { if_none_match: etag }
7070
end
7171

lib/flipper/ui/actions/import.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class Import < UI::Action
88
route %r{\A/settings\/import/?\Z}
99

1010
def post
11+
render_read_only if read_only?
1112
contents = params['file'][:tempfile].read
1213
export = Flipper::Exporters::Json::Export.new(contents: contents)
1314
flipper.import(export)

lib/flipper/ui/configuration.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ class Configuration
4545
# false and it will go away. Defaults to true.
4646
attr_accessor :cloud_recommendation
4747

48+
# Public: Set to false to disable the version check that fetches the
49+
# latest release from flippercloud.io. Useful when a strict Content
50+
# Security Policy is in place. Defaults to true.
51+
attr_accessor :version_check_enabled
52+
4853
# Public: What should show up in the form to add actors. This can be
4954
# different per application since flipper_id's can be whatever an
5055
# application needs. Defaults to "a flipper id".
@@ -114,6 +119,7 @@ def initialize
114119
@feature_removal_enabled = true
115120
@fun = true
116121
@cloud_recommendation = true
122+
@version_check_enabled = true
117123
@add_actor_placeholder = "a flipper id"
118124
@descriptions_source = DEFAULT_DESCRIPTIONS_SOURCE
119125
@actor_names_source = DEFAULT_ACTOR_NAMES_SOURCE

lib/flipper/ui/views/layout.erb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
<%- end -%>
1919

2020
<div class="text-muted small text-end">
21-
<a href="#" class="badge text-bg-warning ms-2 d-none" style="font-size:100%" id="new-version-badge" data-version="<%= Flipper::VERSION %>">
22-
</a>
21+
<% if Flipper::UI.configuration.version_check_enabled %>
22+
<a href="#" class="badge text-bg-warning ms-2 d-none" style="font-size:100%" id="new-version-badge" data-version="<%= Flipper::VERSION %>">
23+
</a>
24+
<% end %>
2325

2426
<% if Flipper.deprecated_ruby_version? %>
2527
<a href="https://github.com/flippercloud/flipper/pull/776" class="badge text-bg-danger ms-2" style="font-size:100%">
@@ -83,6 +85,8 @@
8385
<script src="<%= script_name + popper_js[:src] %>" integrity="<%= popper_js[:hash] %>" crossorigin="anonymous"></script>
8486
<script src="<%= script_name + bootstrap_js[:src] %>" integrity="<%= bootstrap_js[:hash] %>" crossorigin="anonymous"></script>
8587
<script src="<%= script_name %>/js/application.js?v=<%= Flipper::VERSION %>"></script>
86-
<script src="<%= script_name %>/js/version.js?v=<%= Flipper::VERSION %>"></script>
88+
<% if Flipper::UI.configuration.version_check_enabled %>
89+
<script src="<%= script_name %>/js/version.js?v=<%= Flipper::VERSION %>"></script>
90+
<% end %>
8791
</body>
8892
</html>

lib/flipper/ui/views/settings.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
</div>
3939
</div>
4040

41+
<% if write_allowed? %>
4142
<div class="card">
4243
<div class="card-header">
4344
<h4 class="m-0">Import</h4>
@@ -51,3 +52,4 @@
5152
</form>
5253
</div>
5354
</div>
55+
<% end %>

lib/flipper/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Flipper
2-
VERSION = '1.4.0'.freeze
2+
VERSION = '1.4.1'.freeze
33

44
REQUIRED_RUBY_VERSION = '2.6'.freeze
55
NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze

spec/flipper/adapters/http_spec.rb

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,95 @@
278278
}.to raise_error(Flipper::Adapters::Http::Error)
279279
end
280280

281+
it "skips If-None-Match header when cache_bust is true" do
282+
features_response = {
283+
"features" => [
284+
{
285+
"key" => "search",
286+
"gates" => [
287+
{"key" => "boolean", "value" => true}
288+
]
289+
}
290+
]
291+
}
292+
293+
# First request - populate the ETag cache
294+
stub_request(:get, "http://app.com/flipper/features?exclude_gate_names=true")
295+
.to_return(
296+
status: 200,
297+
body: JSON.generate(features_response),
298+
headers: { 'ETag' => '"abc123"' }
299+
)
300+
301+
adapter = described_class.new(url: 'http://app.com/flipper')
302+
adapter.get_all
303+
304+
# Second request with cache_bust - should NOT send If-None-Match
305+
cache_bust_stub = stub_request(:get, %r{/flipper/features\?_cb=\d+&exclude_gate_names=true})
306+
.to_return(
307+
status: 200,
308+
body: JSON.generate(features_response),
309+
headers: { 'ETag' => '"def456"' }
310+
)
311+
312+
adapter.get_all(cache_bust: true)
313+
314+
expect(cache_bust_stub).to have_been_requested.once
315+
expect(
316+
a_request(:get, %r{/flipper/features\?_cb=\d+&exclude_gate_names=true})
317+
.with { |req| req.headers['If-None-Match'].nil? }
318+
).to have_been_made.once
319+
end
320+
321+
it "returns fresh data on cache_bust even when ETag is cached" do
322+
stale_response = {
323+
"features" => [
324+
{
325+
"key" => "search",
326+
"gates" => [
327+
{"key" => "boolean", "value" => nil}
328+
]
329+
}
330+
]
331+
}
332+
333+
fresh_response = {
334+
"features" => [
335+
{
336+
"key" => "search",
337+
"gates" => [
338+
{"key" => "boolean", "value" => true}
339+
]
340+
}
341+
]
342+
}
343+
344+
# First request - populate ETag cache with feature disabled
345+
stub_request(:get, "http://app.com/flipper/features?exclude_gate_names=true")
346+
.to_return(
347+
status: 200,
348+
body: JSON.generate(stale_response),
349+
headers: { 'ETag' => '"abc123"' }
350+
)
351+
352+
adapter = described_class.new(url: 'http://app.com/flipper')
353+
stale_result = adapter.get_all
354+
355+
expect(stale_result["search"][:boolean]).to be_nil
356+
357+
# Cache bust request returns fresh data (feature now enabled)
358+
stub_request(:get, %r{/flipper/features\?_cb=\d+&exclude_gate_names=true})
359+
.to_return(
360+
status: 200,
361+
body: JSON.generate(fresh_response),
362+
headers: { 'ETag' => '"def456"' }
363+
)
364+
365+
fresh_result = adapter.get_all(cache_bust: true)
366+
367+
expect(fresh_result["search"][:boolean]).to eq("true")
368+
end
369+
281370
it "does not send If-None-Match for other endpoints" do
282371
stub_request(:get, "http://app.com/flipper/features/search")
283372
.to_return(status: 404)

spec/flipper/ui/actions/import_spec.rb

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
{ :csrf => token, 'csrf' => token, '_csrf_token' => token }
1212
end
1313

14+
let(:path) { FlipperRoot.join("spec", "fixtures", "flipper_pstore_1679087600.json") }
15+
1416
describe "POST /settings/import" do
1517
before do
1618
flipper.enable :plausible
1719
flipper.disable :google_analytics
18-
path = FlipperRoot.join("spec", "fixtures", "flipper_pstore_1679087600.json")
1920

2021
post '/settings/import',
2122
{
@@ -37,5 +38,26 @@
3738
expect(last_response.status).to be(302)
3839
expect(last_response.headers['location']).to eq('/features')
3940
end
41+
42+
context "when in read only mode" do
43+
before do
44+
allow(flipper).to receive(:read_only?) { true }
45+
46+
post '/settings/import',
47+
{
48+
'authenticity_token' => token,
49+
'file' => Rack::Test::UploadedFile.new(path, "application/json"),
50+
},
51+
'rack.session' => session
52+
end
53+
54+
it 'returns 403' do
55+
expect(last_response.status).to be(403)
56+
end
57+
58+
it 'renders read only template' do
59+
expect(last_response.body).to include('read only')
60+
end
61+
end
4062
end
4163
end

spec/flipper/ui/configuration_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@
7373
end
7474
end
7575

76+
describe "#version_check_enabled" do
77+
it "has default value" do
78+
expect(configuration.version_check_enabled).to eq(true)
79+
end
80+
81+
it "can be updated" do
82+
configuration.version_check_enabled = false
83+
expect(configuration.version_check_enabled).to eq(false)
84+
end
85+
end
86+
7687
describe "#feature_removal_enabled" do
7788
it "has default value" do
7889
expect(configuration.feature_removal_enabled).to eq(true)

0 commit comments

Comments
 (0)