Skip to content

Commit 87e593f

Browse files
committed
Consolidated view access hardening (+feature flag)
- require team-wise feature flag instead of super admin role - redirect to /sites if the team isn't eligible any more - enforce regular site in shared links controller
1 parent 80c13dd commit 87e593f

File tree

7 files changed

+34
-12
lines changed

7 files changed

+34
-12
lines changed

assets/js/dashboard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ if (container && container.dataset) {
6868
team: {
6969
identifier: container.dataset.teamIdentifier ?? null,
7070
hasConsolidatedView:
71-
container.dataset.teamHasConsolidatedView === 'true'
71+
container.dataset.consolidatedViewAvailable === 'true'
7272
}
7373
}
7474
: {

extra/lib/plausible/consolidated_view.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ defmodule Plausible.ConsolidatedView do
4141
%User{} <- user,
4242
true <- flag_enabled?(team),
4343
true <- enabled?(team),
44-
true <- has_sites_to_consolidate?(team) do
44+
true <- has_sites_to_consolidate?(team),
45+
:ok <- Plausible.Billing.Feature.ConsolidatedView.check_availability(team) do
4546
true
4647
else
4748
_ ->

extra/lib/plausible_web/live/customer_support/team/components/consolidated_views.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.ConsolidatedViews do
7676
<.delete_button
7777
phx-click="delete-consolidated-view"
7878
phx-target={@myself}
79-
data-confirm="Are you sure you want to delete this consolidated view?"
79+
data-confirm="Are you sure you want to delete this consolidated view? It will be recreated whenever eligible subscription/trial accesses /sites for that team."
8080
/>
8181
</.td>
8282
</:tbody>

lib/plausible_web/controllers/stats_controller.ex

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ defmodule PlausibleWeb.StatsController do
6363

6464
consolidated_view? = Plausible.Sites.consolidated?(site)
6565

66-
team_has_consolidated_view? =
66+
consolidated_view_available? =
6767
on_ee(do: Plausible.ConsolidatedView.ok_to_display?(site.team, current_user), else: false)
6868

6969
team_identifier = site.team.identifier
@@ -74,6 +74,9 @@ defmodule PlausibleWeb.StatsController do
7474
{:ok, segments} = Plausible.Segments.get_all_for_site(site, site_role)
7575

7676
cond do
77+
consolidated_view? and not consolidated_view_available? and site_role != :super_admin ->
78+
redirect(conn, to: Routes.site_path(conn, :index))
79+
7780
(stats_start_date && can_see_stats?) || (can_see_stats? && skip_to_dashboard?) ->
7881
flags = get_flags(current_user, site)
7982

@@ -96,7 +99,7 @@ defmodule PlausibleWeb.StatsController do
9699
load_dashboard_js: true,
97100
hide_footer?: if(ce?() || demo, do: false, else: site_role != :public),
98101
consolidated_view?: consolidated_view?,
99-
team_has_consolidated_view?: team_has_consolidated_view?,
102+
consolidated_view_available?: consolidated_view_available?,
100103
team_identifier: team_identifier
101104
)
102105

@@ -402,9 +405,9 @@ defmodule PlausibleWeb.StatsController do
402405

403406
embedded? = conn.params["embed"] == "true"
404407

405-
consolidated_view? = Plausible.Sites.consolidated?(shared_link.site)
408+
true = Plausible.Sites.regular?(shared_link.site)
406409

407-
team_has_consolidated_view? =
410+
consolidated_view_available? =
408411
on_ee(
409412
do: Plausible.ConsolidatedView.ok_to_display?(shared_link.site.team, current_user),
410413
else: false
@@ -435,8 +438,9 @@ defmodule PlausibleWeb.StatsController do
435438
segments: segments,
436439
load_dashboard_js: true,
437440
hide_footer?: if(ce?(), do: embedded?, else: embedded? || site_role != :public),
438-
consolidated_view?: consolidated_view?,
439-
team_has_consolidated_view?: team_has_consolidated_view?,
441+
# no shared links for consolidated views
442+
consolidated_view?: false,
443+
consolidated_view_available?: consolidated_view_available?,
440444
team_identifier: team_identifier
441445
)
442446
end

lib/plausible_web/live/sites.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ defmodule PlausibleWeb.Live.Sites do
10791079
defp consolidated_view_ok_to_display?(_team, _user), do: false
10801080

10811081
defp init_consolidated_view_assigns(_user, _team),
1082-
do: no_consolidated_view(no_consolidated_view_reason: :unabailable)
1082+
do: no_consolidated_view(no_consolidated_view_reason: :unavailable)
10831083

10841084
defp load_consolidated_stats(_consolidated_view), do: nil
10851085
end

lib/plausible_web/templates/stats/stats.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
Plausible.Stats.Interval.valid_by_period(site: @site) |> Jason.encode!()
5151
}
5252
data-is-consolidated-view={Jason.encode!(@consolidated_view?)}
53-
data-team-has-consolidated-view={Jason.encode!(@team_has_consolidated_view?)}
53+
data-consolidated-view-available={Jason.encode!(@consolidated_view_available?)}
5454
data-team-identifier={@team_identifier}
5555
>
5656
</div>

test/plausible_web/controllers/stats_controller_test.exs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule PlausibleWeb.StatsControllerTest do
3030
assert text_of_attr(resp, @react_container, "data-current-user-id") == "null"
3131
assert text_of_attr(resp, @react_container, "data-embedded") == ""
3232
assert text_of_attr(resp, @react_container, "data-is-consolidated-view") == "false"
33-
assert text_of_attr(resp, @react_container, "data-team-has-consolidated-view") == "false"
33+
assert text_of_attr(resp, @react_container, "data-consolidated-view-available") == "false"
3434
assert text_of_attr(resp, @react_container, "data-team-identifier") == site.team.identifier
3535

3636
assert "noindex, nofollow" ==
@@ -197,6 +197,23 @@ defmodule PlausibleWeb.StatsControllerTest do
197197
assert text_of_attr(resp, @react_container, "data-current-user-role") == "owner"
198198
assert text_of_attr(resp, @react_container, "data-current-user-id") == "#{user.id}"
199199
end
200+
201+
test "redirects to /sites if for some reason ineligible anymore", %{
202+
conn: conn,
203+
user: user
204+
} do
205+
new_site(owner: user)
206+
new_site(owner: user)
207+
cv = user |> team_of() |> new_consolidated_view()
208+
209+
user
210+
|> team_of()
211+
|> Plausible.Teams.Team.end_trial()
212+
|> Plausible.Repo.update!()
213+
214+
conn = get(conn, "/" <> cv.domain)
215+
assert redirected_to(conn, 302) == "/sites"
216+
end
200217
end
201218

202219
@tag :ee_only

0 commit comments

Comments
 (0)