Skip to content

Commit

Permalink
feature: add a simple honeypot implementation that denies the qr code…
Browse files Browse the repository at this point in the history
… creation when the field is set (#183)
  • Loading branch information
nwittstruck authored Jan 24, 2024
1 parent 8a96e20 commit 6c3334b
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 5 deletions.
5 changes: 4 additions & 1 deletion lib/qrstorage/qr_codes/qr_code.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ defmodule Qrstorage.QrCodes.QrCode do
field :admin_url_id, :binary_id, read_after_writes: true
field :dots_type, Ecto.Enum, values: @dots_types
field :voice, Ecto.Enum, values: @voices
field :hp, :string, virtual: true

timestamps()
end
Expand All @@ -52,8 +53,10 @@ defmodule Qrstorage.QrCodes.QrCode do
:content_type,
:deltas,
:dots_type,
:voice
:voice,
:hp
])
|> validate_length(:hp, is: 0)
|> scrub_text
|> validate_text_length(:text)
|> validate_inclusion(:color, @colors)
Expand Down
1 change: 1 addition & 0 deletions lib/qrstorage_web/templates/qr_code/form_audio.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
checked: true
) %>
<%= select(f, :color, translated_colors_for_select(), class: "visually-hidden") %>
<%= render("partials/_honeypot.html", f: f) %>

<%= if @changeset.action do %>
<div class="alert alert-danger">
Expand Down
1 change: 1 addition & 0 deletions lib/qrstorage_web/templates/qr_code/form_link.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
checked: true
) %>
<%= select(f, :color, translated_colors_for_select(), class: "visually-hidden") %>
<%= render("partials/_honeypot.html", f: f) %>

<%= if @changeset.action do %>
<div class="alert alert-danger">
Expand Down
1 change: 1 addition & 0 deletions lib/qrstorage_web/templates/qr_code/form_text.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
checked: true
) %>
<%= select(f, :color, translated_colors_for_select(), class: "visually-hidden") %>
<%= render("partials/_honeypot.html", f: f) %>

<%= textarea(f, :deltas,
value: deltas_json_from_changeset(@changeset),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= text_input(@f, :hp, class: "d-none") %>
25 changes: 22 additions & 3 deletions test/qrstorage/qr_codes_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Qrstorage.QrCodesTest do
hide_text: false,
content_type: "text",
language: nil,
hp: nil,
deltas: %{"id" => "test"},
dots_type: "dots"
}
Expand All @@ -22,6 +23,7 @@ defmodule Qrstorage.QrCodesTest do
hide_text: false,
content_type: "audio",
language: "de",
hp: nil,
voice: "female",
dots_type: "dots"
}
Expand Down Expand Up @@ -189,13 +191,30 @@ defmodule Qrstorage.QrCodesTest do
end

test "create_qr_code/1 with invalid dots_type returns error changeset" do
invalid_link_attrs = %{@valid_attrs | dots_type: "invalid"}
assert {:error, %Ecto.Changeset{}} = QrCodes.create_qr_code(invalid_link_attrs)
invalid_attrs = %{@valid_attrs | dots_type: "invalid"}
assert {:error, %Ecto.Changeset{}} = QrCodes.create_qr_code(invalid_attrs)
end

test "create_qr_code/1 without dots_type returns error changeset" do
invalid_link_attrs = %{@valid_attrs | dots_type: ""}
invalid_attrs = %{@valid_attrs | dots_type: ""}
assert {:error, %Ecto.Changeset{}} = QrCodes.create_qr_code(invalid_attrs)
end
end

describe "honeypot" do
test "create_qr_code/1 with audio type and honeypot set returns error changeset" do
invalid_audio_attrs = %{@valid_audio_attrs | hp: "set"}
assert {:error, %Ecto.Changeset{}} = QrCodes.create_qr_code(invalid_audio_attrs)
end

test "create_qr_code/1 with link type and honeypot set returns error changeset" do
invalid_link_attrs = %{@valid_attrs | content_type: "link", hp: "set"}
assert {:error, %Ecto.Changeset{}} = QrCodes.create_qr_code(invalid_link_attrs)
end

test "create_qr_code/1 with text type and honeypot set returns error changeset" do
invalid_text_attrs = %{@valid_attrs | hp: "set"}
assert {:error, %Ecto.Changeset{}} = QrCodes.create_qr_code(invalid_text_attrs)
end
end
end
11 changes: 10 additions & 1 deletion test/qrstorage_web/controllers/qr_code_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ defmodule QrstorageWeb.QrCodeControllerTest do
language: nil,
content_type: "text",
dots_type: "dots",
voice: nil
voice: nil,
hp: nil
}

@invalid_attrs %{delete_after: "10", text: nil, language: nil, content_type: "text"}
Expand Down Expand Up @@ -90,6 +91,14 @@ defmodule QrstorageWeb.QrCodeControllerTest do
end
end

describe "honeypot create qr_code" do
test "does not create qr_code when honeypot is set", %{conn: conn} do
honeypot_set_attrs = %{@create_attrs | hp: "set"}
conn = post(conn, Routes.qr_code_path(conn, :create), qr_code: honeypot_set_attrs)
assert html_response(conn, 200) =~ "Oops, something went wrong"
end
end

describe "create audio qr_code" do
test "audio code is successfully created", %{conn: conn} do
Qrstorage.Services.Gcp.GoogleApiServiceMock
Expand Down

0 comments on commit 6c3334b

Please sign in to comment.