Skip to content

Commit e7bad4c

Browse files
authored
Merge pull request #25 from dwyl/description
adds description_plaintext_unlimited
2 parents f081c58 + 0d03edd commit e7bad4c

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ When you load one of the fields into your database, the corresponding `dump/1` c
4343

4444
Likewise, when you load a field from the database, the `load/1` callback will be called, giving you the data in the format you need. `Fields.EmailEncrypted` will be decrypted back to plaintext.
4545

46+
Each Field optionally defines an `input_type/0` function. This will return an atom representing the `Phoenix.HTML.Form` input type to use for the Field. For example, `Fields.DescriptionPlaintextUnlimited.input_type` returns `:textarea`.
47+
4648
The currently existing fields are:
4749

4850
- [Encrypted](lib/encrypted.ex)
@@ -57,6 +59,7 @@ The currently existing fields are:
5759
- [AddressEncrypted](lib/address_encrypted.ex)
5860
- [PhoneNumber](lib/phone_number.ex)
5961
- [PhoneNumberEncrypted](lib/phone_number_encrypted.ex)
62+
- [DescriptionPlaintextUnlimited](lib/description_plaintext_unlimited.ex)
6063

6164
## Config
6265

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
defmodule Fields.DescriptionPlaintextUnlimited do
2+
@moduledoc """
3+
An Ecto Type for plaintext description fields with no length restrictions.
4+
Strips out all HTML tags to avoid XSS.
5+
6+
## Example
7+
8+
schema "article" do
9+
field(:description, Fields.DescriptionPlaintextUnlimited)
10+
end
11+
"""
12+
@behaviour Ecto.Type
13+
14+
def type, do: :string
15+
16+
def cast(value) do
17+
{:ok, to_string(value)}
18+
end
19+
20+
def dump(value) do
21+
{:ok, HtmlSanitizeEx.strip_tags(value)}
22+
end
23+
24+
def load(value) do
25+
{:ok, value}
26+
end
27+
28+
def input_type, do: :textarea
29+
end

mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Fields.MixProject do
44
def project do
55
[
66
app: :fields,
7-
version: "0.1.1",
7+
version: "0.1.3",
88
elixir: "~> 1.7",
99
start_permanent: Mix.env() == :prod,
1010
deps: deps()
@@ -23,6 +23,7 @@ defmodule Fields.MixProject do
2323
[
2424
{:argon2_elixir, "~> 1.2"},
2525
{:ecto, "~> 2.2.10"},
26+
{:html_sanitize_ex, "~> 1.3"},
2627
{:stream_data, "~> 0.4.2", only: :test}
2728
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
2829
]

mix.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
44
"ecto": {:hex, :ecto, "2.2.11", "4bb8f11718b72ba97a2696f65d247a379e739a0ecabf6a13ad1face79844791c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
55
"elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"},
6+
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
7+
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
68
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
79
"stream_data": {:hex, :stream_data, "0.4.2", "fa86b78c88ec4eaa482c0891350fcc23f19a79059a687760ddcf8680aac2799b", [:mix], [], "hexpm"},
810
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
defmodule Fields.DescriptionPlaintextUnlimitedTest do
2+
use ExUnit.Case
3+
alias Fields.DescriptionPlaintextUnlimited as Description
4+
5+
describe "types" do
6+
test "Desription.type is :string" do
7+
assert Description.type() == :string
8+
end
9+
end
10+
11+
describe "cast" do
12+
test "Description.cast accepts a string" do
13+
assert {:ok, "testing"} == Description.cast("testing")
14+
end
15+
end
16+
17+
describe "dump" do
18+
test "Description.dump strips html tags" do
19+
{:ok, stripped} = Description.dump("<script>alert('hello')</script>")
20+
21+
assert stripped != "<script>alert('hello')</script>"
22+
assert stripped == "alert('hello')"
23+
end
24+
end
25+
26+
describe "load" do
27+
test "Description.load returns a string" do
28+
assert {:ok, "testing"} == Description.load("testing")
29+
end
30+
end
31+
32+
describe "input_type" do
33+
test "Description.input_type returns :textarea" do
34+
assert Description.input_type() == :textarea
35+
end
36+
end
37+
end

0 commit comments

Comments
 (0)