Skip to content

Commit

Permalink
Merge pull request #23 from Recruitee/additional-data-validation
Browse files Browse the repository at this point in the history
Validate special props
  • Loading branch information
rdk08 authored Oct 24, 2023
2 parents 22961e9 + 62cba87 commit d6c8d89
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 2 deletions.
25 changes: 25 additions & 0 deletions lib/plausible/event/clickhouse_schema.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
defmodule Plausible.ClickhouseEvent do
use Ecto.Schema

import Ecto.Changeset

alias Plausible.ValueHelpers

@primary_key false
schema "events" do
field :event_id, :integer
Expand Down Expand Up @@ -89,5 +92,27 @@ defmodule Plausible.ClickhouseEvent do
empty_values: [nil, ""]
)
|> validate_required([:name, :domain, :hostname, :pathname, :event_id, :user_id, :timestamp])
|> validate_campaign_id()
|> validate_product_id()
end

defp validate_campaign_id(changeset) do
campaign_id = get_field(changeset, :campaign_id)

if ValueHelpers.validate(campaign_id, type: :prefixed_id) do
changeset
else
delete_change(changeset, :campaign_id)
end
end

defp validate_product_id(changeset) do
product_id = get_field(changeset, :product_id)

if ValueHelpers.validate(product_id, type: :prefixed_id) do
changeset
else
delete_change(changeset, :product_id)
end
end
end
16 changes: 16 additions & 0 deletions lib/plausible/helpers/value.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Plausible.ValueHelpers do
@prefix_pattern "[a-zA-Z]+"
@id_pattern "\\d+"
@uuid_pattern "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"

@spec validate(any(), keyword()) :: any()
def validate(value, type: :prefixed_id) when is_binary(value) do
pattern = ~r/\A(#{@prefix_pattern})-(#{@id_pattern}|#{@uuid_pattern})\Z/

if Regex.match?(pattern, value), do: value, else: nil
end

def validate(nil, _), do: nil
def validate("", _), do: nil
def validate(value, _), do: value
end
25 changes: 25 additions & 0 deletions lib/plausible/session/clickhouse_schema.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
defmodule Plausible.ClickhouseSession do
use Ecto.Schema

import Ecto.Changeset

alias Plausible.ValueHelpers

@primary_key false
schema "sessions" do
field :hostname, :string
Expand Down Expand Up @@ -80,5 +83,27 @@ defmodule Plausible.ClickhouseSession do
:screen_size
])
|> validate_required([:hostname, :domain, :fingerprint, :is_bounce, :start])
|> validate_campaign_id()
|> validate_product_id()
end

defp validate_campaign_id(changeset) do
campaign_id = get_field(changeset, :campaign_id)

if ValueHelpers.validate(campaign_id, type: :prefixed_id) do
changeset
else
delete_change(changeset, :campaign_id)
end
end

defp validate_product_id(changeset) do
product_id = get_field(changeset, :product_id)

if ValueHelpers.validate(product_id, type: :prefixed_id) do
changeset
else
delete_change(changeset, :product_id)
end
end
end
35 changes: 33 additions & 2 deletions test/plausible_web/controllers/api/external_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
company_id: 10,
job_id: 12,
page_id: 15,
product_id: "vendor-11",
product_id: "vendor-6a01cfb6-717a-11ee-b962-0242ac120002",
site_id: 9,
careers_application_form_uuid: "313a26c2-741c-421c-9a6b-f39c02c8d35c"
}
Expand All @@ -514,7 +514,7 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
event = get_event("special-props-test.com")

assert Map.get(event, :campaign_id) == "vendor-8"
assert Map.get(event, :product_id) == "vendor-11"
assert Map.get(event, :product_id) == "vendor-6a01cfb6-717a-11ee-b962-0242ac120002"
assert Map.get(event, :company_id) == 10
assert Map.get(event, :job_id) == 12
assert Map.get(event, :page_id) == 15
Expand All @@ -527,6 +527,37 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do
assert Map.get(event, :"meta.value") == []
end

test "casts special props, invalidates specific params", %{conn: conn} do
params = %{
name: "Signup",
url: "http://gigride.live/",
domain: "special-props-validation-test.com",
props: %{
campaign_id: "12345",
company_id: 10,
page_id: 15,
product_id: "incorrect-product-id",
careers_application_form_uuid: "313a26c2-741c-421c-9a6b-f39c02c8d35c"
}
}

conn
|> post("/api/event", params)

event = get_event("special-props-validation-test.com")

assert Map.get(event, :campaign_id) == ""
assert Map.get(event, :product_id) == ""
assert Map.get(event, :company_id) == 10
assert Map.get(event, :page_id) == 15

assert Map.get(event, :careers_application_form_uuid) ==
"313a26c2-741c-421c-9a6b-f39c02c8d35c"

assert Map.get(event, :"meta.key") == []
assert Map.get(event, :"meta.value") == []
end

test "generates event id", %{conn: conn} do
params = %{
name: "Signup",
Expand Down

0 comments on commit d6c8d89

Please sign in to comment.