mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
chore(portal): Enforce only internet resource in internet site (#8254)
Currently, it would theoretically be possible for an admin to connect non-internet Resources to the Internet site. This PR fixes that by enforcing only the `internet` Resource type can belong to the `Internet` gateway group. Related: #6834
This commit is contained in:
@@ -22,6 +22,10 @@ defmodule Domain.Resources.Connection.Changeset do
|
||||
|> assoc_constraint(:resource)
|
||||
|> assoc_constraint(:gateway_group)
|
||||
|> assoc_constraint(:account)
|
||||
|> check_constraint(:resource,
|
||||
name: :internet_resource_in_internet_site,
|
||||
message: "type must be 'internet' for the Internet site"
|
||||
)
|
||||
|> put_change(:account_id, account_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
defmodule Domain.Repo.Migrations.RequireInternetResourceInInternetSite do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
# Create a function to enforce only 'internet' resources in 'Internet' site
|
||||
execute(
|
||||
"""
|
||||
CREATE OR REPLACE FUNCTION enforce_internet_resource_in_internet_gg()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
resource_type text;
|
||||
site_name text;
|
||||
site_managed_by text;
|
||||
BEGIN
|
||||
-- Fetch the resource type and gateway group details
|
||||
SELECT r.type INTO resource_type
|
||||
FROM resources r
|
||||
WHERE r.id = NEW.resource_id;
|
||||
|
||||
SELECT gg.name, gg.managed_by INTO site_name, site_managed_by
|
||||
FROM gateway_groups gg
|
||||
WHERE gg.id = NEW.gateway_group_id;
|
||||
|
||||
-- Rule 1: Prevent non-'internet' resources in the 'Internet' gateway group
|
||||
IF site_name = 'Internet' AND site_managed_by = 'system' AND resource_type != 'internet' THEN
|
||||
RAISE EXCEPTION 'Only internet resource type is allowed in the Internet site'
|
||||
USING ERRCODE = '23514', CONSTRAINT = 'internet_resource_in_internet_site';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
""",
|
||||
"""
|
||||
DROP FUNCTION IF EXISTS enforce_internet_resource_in_internet_gg();
|
||||
"""
|
||||
)
|
||||
|
||||
# Create a trigger to run the check on insert or update
|
||||
execute(
|
||||
"""
|
||||
CREATE TRIGGER internet_resource_in_internet_gg
|
||||
BEFORE INSERT OR UPDATE OF resource_id, gateway_group_id
|
||||
ON resource_connections
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION enforce_internet_resource_in_internet_gg();
|
||||
""",
|
||||
"""
|
||||
DROP TRIGGER IF EXISTS internet_resource_in_internet_gg ON resource_connections;
|
||||
"""
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -1003,6 +1003,26 @@ defmodule Domain.ResourcesTest do
|
||||
end
|
||||
|
||||
describe "create_resource/2" do
|
||||
test "prevents adding other resources to the internet site", %{
|
||||
account: account,
|
||||
subject: subject
|
||||
} do
|
||||
{:ok, gateway_group} = Domain.Gateways.create_internet_group(account)
|
||||
|
||||
attrs =
|
||||
Fixtures.Resources.resource_attrs(
|
||||
type: :dns,
|
||||
address: "example.com",
|
||||
connections: [%{gateway_group_id: gateway_group.id}]
|
||||
)
|
||||
|
||||
assert {:error, changeset} = create_resource(attrs, subject)
|
||||
|
||||
assert %{resource: ["type must be 'internet' for the Internet site"]} in errors_on(
|
||||
changeset
|
||||
).connections
|
||||
end
|
||||
|
||||
test "returns changeset error on empty attrs", %{subject: subject} do
|
||||
assert {:error, changeset} = create_resource(%{}, subject)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user