Skip to content

Commit 3869484

Browse files
committed
feat: create global enforce whitelist
1 parent 1e5c430 commit 3869484

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed

front/lib/front_web/controllers/settings_controller.ex

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,39 @@ defmodule FrontWeb.SettingsController do
9090
)
9191
end
9292

93+
def confirm_enforce_workflow(conn, _params) do
94+
org_id = conn.assigns.organization_id
95+
permissions = conn.assigns.permissions || %{}
96+
97+
if Map.get(permissions, "organization.general_settings.manage", false) do
98+
case Models.OrganizationSettings.modify(org_id, %{"enforce_whitelist" => "true"}) do
99+
{:ok, _updated_settings} ->
100+
conn
101+
|> put_flash(:notice, "Whitelist enforcement applied successfully.")
102+
|> redirect(to: settings_path(conn, :show))
103+
104+
{:error, %Ecto.Changeset{} = changeset} ->
105+
errors =
106+
changeset.errors |> Enum.map(fn {field, {message, _}} -> "#{field}: #{message}" end)
107+
108+
conn
109+
|> put_flash(:errors, errors)
110+
|> put_flash(:alert, "Failed to apply whitelist enforcement.")
111+
|> redirect(to: settings_path(conn, :show))
112+
113+
{:error, reason} ->
114+
conn
115+
|> put_flash(:errors, ["#{inspect(reason)}"])
116+
|> put_flash(:alert, "Failed to apply whitelist enforcement.")
117+
|> redirect(to: settings_path(conn, :show))
118+
end
119+
else
120+
conn
121+
|> put_flash(:alert, "Insufficient permissions.")
122+
|> redirect(to: settings_path(conn, :show))
123+
end
124+
end
125+
93126
def confirm_delete(conn, _params) do
94127
org_id = conn.assigns.organization_id
95128

front/lib/front_web/router.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ defmodule FrontWeb.Router do
126126

127127
get("/settings/confirm_delete", SettingsController, :confirm_delete)
128128

129+
post("/settings/confirm_enforce", SettingsController, :confirm_enforce_workflow)
130+
129131
delete("/settings", SettingsController, :destroy)
130132

131133
get("/jwt_config", OrganizationJWTConfigController, :show)

front/lib/front_web/templates/settings/show.html.eex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@
3737
</div>
3838
<% end %>
3939
</div>
40+
<div class="pv3 bt b--lighter-gray">
41+
<div class="db b">Whitelist Enforcement</div>
42+
<p class="measure mb2">Applies new Whitelist rules to old tags and branches</p>
43+
<div>
44+
<%= link "Enforce Whitelist",
45+
to: settings_path(@conn, :confirm_enforce_workflow),
46+
method: :post,
47+
class: "btn btn-secondary danger" %>
48+
</div>
49+
</div>
4050
<%= if FeatureProvider.feature_enabled?(:multiple_organizations, param: @conn.assigns[:organization_id]) do %>
4151
<%= if @permissions["organization.delete"] do %>
4252
<div class="pt3 bt b--lighter-gray">

front/test/front_web/controllers/settings_controller_test.exs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ defmodule FrontWeb.SettingsControllerTest do
22
use FrontWeb.ConnCase
33
alias Support.Stubs.DB
44

5+
import Mock
6+
57
setup %{conn: conn} do
68
Cacheman.clear(:front)
79

@@ -201,6 +203,86 @@ defmodule FrontWeb.SettingsControllerTest do
201203
end
202204
end
203205

206+
describe "POST confirm_enforce_workflow" do
207+
test "when the user lacks manage permissions => denies the request", %{
208+
conn: conn,
209+
organization_id: organization_id
210+
} do
211+
with_mock Front.Models.OrganizationSettings,
212+
modify: fn ^organization_id, _ ->
213+
send(self(), :modify_called)
214+
{:ok, %{}}
215+
end do
216+
conn =
217+
conn
218+
|> post("/settings/confirm_enforce")
219+
220+
assert redirected_to(conn) =~ "/settings"
221+
assert get_flash(conn, :alert) == "Insufficient permissions."
222+
refute_received :modify_called
223+
end
224+
end
225+
226+
test "when the user can manage general settings => applies the enforcement", %{
227+
conn: conn,
228+
user_id: user_id,
229+
organization_id: organization_id
230+
} do
231+
Support.Stubs.PermissionPatrol.add_permissions(
232+
organization_id,
233+
user_id,
234+
["organization.view", "organization.general_settings.manage"]
235+
)
236+
237+
with_mock Front.Models.OrganizationSettings,
238+
modify: fn ^organization_id, %{"enforce_whitelist" => "true"} ->
239+
send(self(), :modify_called)
240+
{:ok, %{}}
241+
end do
242+
conn =
243+
conn
244+
|> post("/settings/confirm_enforce")
245+
246+
assert redirected_to(conn) == "/settings"
247+
assert get_flash(conn, :notice) == "Whitelist enforcement applied successfully."
248+
assert_received :modify_called
249+
end
250+
end
251+
252+
test "when enforcing fails => shows the error", %{
253+
conn: conn,
254+
user_id: user_id,
255+
organization_id: organization_id
256+
} do
257+
Support.Stubs.PermissionPatrol.add_permissions(
258+
organization_id,
259+
user_id,
260+
["organization.view", "organization.general_settings.manage"]
261+
)
262+
263+
changeset = %Ecto.Changeset{
264+
valid?: false,
265+
changes: %{},
266+
errors: [enforce_whitelist: {"boom", []}],
267+
data: %{},
268+
types: %{}
269+
}
270+
271+
with_mock Front.Models.OrganizationSettings,
272+
modify: fn ^organization_id, %{"enforce_whitelist" => "true"} ->
273+
{:error, changeset}
274+
end do
275+
conn =
276+
conn
277+
|> post("/settings/confirm_enforce")
278+
279+
assert redirected_to(conn) == "/settings"
280+
assert get_flash(conn, :alert) == "Failed to apply whitelist enforcement."
281+
assert get_flash(conn, :errors) == ["enforce_whitelist: boom"]
282+
end
283+
end
284+
end
285+
204286
describe "DELETE destroy" do
205287
test "when everything works => redirects to me page", %{
206288
conn: conn,

0 commit comments

Comments
 (0)