From c62843cd6bc933fc2a5781d75c2a53c51d19a228 Mon Sep 17 00:00:00 2001 From: Rafael Friesen Date: Thu, 12 May 2016 09:41:16 +0200 Subject: [PATCH] Add email validator option --- doc/Mailman.html | 48 ++--- docs/Mailman.Adapter.html | 60 +++---- docs/Mailman.ExternalSmtpAdapter.html | 56 +++--- docs/Mailman.LocalSmtpAdapter.html | 62 +++---- docs/Mailman.TestingAdapter.html | 54 +++--- docs/Mailman.html | 56 +++--- docs/modules_list.html | 248 +++++++++++++------------- docs/protocols_list.html | 24 +-- lib/mailman.ex | 30 ++-- lib/mailman/external_smtp_adapter.ex | 20 ++- lib/mailman/local_smtp_adapter.ex | 4 +- lib/mailman/local_smtp_config.ex | 4 +- lib/mailman/smtp_config.ex | 4 +- lib/mailman/test_config.ex | 4 +- lib/mailman/testing_adapter.ex | 2 +- mix.lock | 2 +- test/mailman_test.exs | 26 +-- 17 files changed, 358 insertions(+), 346 deletions(-) diff --git a/doc/Mailman.html b/doc/Mailman.html index fe8fdb0..5c7e5e8 100644 --- a/doc/Mailman.html +++ b/doc/Mailman.html @@ -28,44 +28,44 @@

Mailman - +

- - + + Source - - + +

Summary

- + - +
deliver(email, context)

Delivers given email and returns a Task

- - - + + +

Functions

@@ -77,22 +77,22 @@

Functions

- +

Delivers given email and returns a Task

- - Source - + + Source +
- - - + + + diff --git a/docs/Mailman.Adapter.html b/docs/Mailman.Adapter.html index f11ab40..eb424cb 100644 --- a/docs/Mailman.Adapter.html +++ b/docs/Mailman.Adapter.html @@ -24,80 +24,80 @@

Mailman.Adapter - + protocol - +

- - + + Source - - + +

Summary

- - + +
deliver(context, email, message)deliver(context, email, message, opts)
- - + +

Types

t :: term

- +
- - + +

Functions

-
- deliver(context, email, message) +
+ deliver(context, email, message, opts)
- +
- + Source - +
- - - + + +
diff --git a/docs/Mailman.ExternalSmtpAdapter.html b/docs/Mailman.ExternalSmtpAdapter.html index 2ca85e1..dcf96cf 100644 --- a/docs/Mailman.ExternalSmtpAdapter.html +++ b/docs/Mailman.ExternalSmtpAdapter.html @@ -24,74 +24,74 @@

Mailman.ExternalSmtpAdapter - +

- +

Adapter for sending email via external SMTP server

- - + + Source - - + +

Summary

- - + + - +
deliver(config, email, message)deliver(config, email, message, opts)

Delivers an email based on specified config

- - - + + +

Functions

-
- deliver(config, email, message) +
+ deliver(config, email, message, opts)
- +

Delivers an email based on specified config

- + Source - +
- - - + + +
diff --git a/docs/Mailman.LocalSmtpAdapter.html b/docs/Mailman.LocalSmtpAdapter.html index a84f580..a90914a 100644 --- a/docs/Mailman.LocalSmtpAdapter.html +++ b/docs/Mailman.LocalSmtpAdapter.html @@ -24,70 +24,70 @@

Mailman.LocalSmtpAdapter - +

- +

Adapter for using locally spawned SMTP server

- - + + Source - - + +

Summary

- - + + - + - +
deliver(config, email, message)deliver(config, email, message, opts)

Delivers an email through a locally running process

external_for(config)
- - - + + +

Functions

-
- deliver(config, email, message) +
+ deliver(config, email, message, opts)
- +

Delivers an email through a locally running process

- + Source - +
@@ -98,19 +98,19 @@

Functions

- +
Source - +
- - - + + + diff --git a/docs/Mailman.TestingAdapter.html b/docs/Mailman.TestingAdapter.html index 2d42131..d443d96 100644 --- a/docs/Mailman.TestingAdapter.html +++ b/docs/Mailman.TestingAdapter.html @@ -24,70 +24,70 @@

Mailman.TestingAdapter - +

- +

Implementation of the testing SMTP adapter

- - + + Source - - + +

Summary

- - + +
deliver(config, email, message)deliver(config, email, message, opts)
- - - + + +

Functions

-
- deliver(config, email, message) +
+ deliver(config, email, message, opts)
- +
- + Source - +
- - - + + +
diff --git a/docs/Mailman.html b/docs/Mailman.html index 41450ab..ed94003 100644 --- a/docs/Mailman.html +++ b/docs/Mailman.html @@ -24,69 +24,69 @@

Mailman - +

- - + + Source - - + +

Summary

- - + + - +
deliver(email, context)deliver(email, context, opts)

Delivers given email and returns a Task

- - - + + +

Functions

-
- deliver(email, context) +
+ deliver(email, context, opts)
- +

Delivers given email and returns a Task

- - Source - + + Source +
- - - + + +
diff --git a/docs/modules_list.html b/docs/modules_list.html index e43c18d..080e0d1 100644 --- a/docs/modules_list.html +++ b/docs/modules_list.html @@ -16,13 +16,13 @@

- + Mailman v0.0.3 - +

- + Overview

@@ -35,695 +35,695 @@

diff --git a/docs/protocols_list.html b/docs/protocols_list.html index ee5ae7b..9f6a70b 100644 --- a/docs/protocols_list.html +++ b/docs/protocols_list.html @@ -16,13 +16,13 @@

- + Mailman v0.0.3 - +

- + Overview

@@ -35,42 +35,42 @@

diff --git a/lib/mailman.ex b/lib/mailman.ex index 54a3cb8..af228be 100644 --- a/lib/mailman.ex +++ b/lib/mailman.ex @@ -2,7 +2,7 @@ defmodule Mailman do defprotocol Adapter do @moduledoc "Protocol for implementing different medium of emails delivery" - def deliver(context, email, message) + def deliver(context, email, message, opts \\ []) end defprotocol Composer do @@ -10,32 +10,36 @@ defmodule Mailman do def compile_part(config, mode, email) end - @doc "Delivers given email and returns a Task" - def deliver(email, context) do - message = Mailman.Render.render(email, context.composer) - Adapter.deliver(Mailman.Context.get_config(context), email, message) - end - @doc "Delivers given email to all addresses and returns a list of Tasks" - def deliver(email, context, :send_cc_and_bcc) do + def deliver(email, context, :send_cc_and_bcc, opts) do bcc_list = email.bcc cleaned_email = %Mailman.Email{email | bcc: []} message = Mailman.Render.render(cleaned_email, context.composer) - to_task = [Adapter.deliver(context.config, email, message)] + to_task = [Adapter.deliver(context.config, email, message, opts)] - cc_tasks = email.cc |> Enum.map(fn(address) -> + cc_tasks = email.cc |> Enum.map(fn(address) -> cc_envelope = %Mailman.Email{email | to: [address]} - Adapter.deliver(context.config, cc_envelope, message) + Adapter.deliver(context.config, cc_envelope, message, opts) end) - bcc_tasks = bcc_list |> Enum.map(fn(address) -> + bcc_tasks = bcc_list |> Enum.map(fn(address) -> bcc_envelope = %Mailman.Email{email | to: [address]} bcc_message = %Mailman.Email{email | bcc: [address]} message = Mailman.Render.render(bcc_message, context.composer) - Adapter.deliver(context.config, bcc_envelope, message) + Adapter.deliver(context.config, bcc_envelope, message, opts) end) to_task ++ cc_tasks ++ bcc_tasks end + + def deliver(email, context, :send_cc_and_bcc) do + deliver(email, context, :send_cc_and_bcc, []) + end + + @doc "Delivers given email and returns a Task" + def deliver(email, context, opts \\ []) do + message = Mailman.Render.render(email, context.composer) + Adapter.deliver(Mailman.Context.get_config(context), email, message, opts) + end end diff --git a/lib/mailman/external_smtp_adapter.ex b/lib/mailman/external_smtp_adapter.ex index 0d7f536..a8618bd 100644 --- a/lib/mailman/external_smtp_adapter.ex +++ b/lib/mailman/external_smtp_adapter.ex @@ -1,8 +1,10 @@ defmodule Mailman.ExternalSmtpAdapter do @moduledoc "Adapter for sending email via external SMTP server" + @default_validator ~r/([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/ + @doc "Delivers an email based on specified config" - def deliver(config, email, message) do + def deliver(config, email, message, opts \\ []) do relay_config = [ relay: config.relay, username: config.username, @@ -12,8 +14,15 @@ defmodule Mailman.ExternalSmtpAdapter do tls: config.tls, auth: config.auth ] - from_envelope_address = envelope_email(email.from) - to_envelope_address = Enum.map(email.to, &(envelope_email(&1))) + + validator = if opts[:validator] == nil do + @default_validator + else + opts[:validator] + end + + from_envelope_address = envelope_email(email.from, validator) + to_envelope_address = Enum.map(email.to, &(envelope_email(&1, validator))) ret = :gen_smtp_client.send_blocking { from_envelope_address, to_envelope_address, @@ -27,10 +36,9 @@ defmodule Mailman.ExternalSmtpAdapter do end - defp envelope_email(email_address) do - pure_from = Regex.run(~r/([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/, email_address) + defp envelope_email(email_address, validator) do + pure_from = Regex.run(~r/([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/, email_address) |> Enum.at(1) end end - diff --git a/lib/mailman/local_smtp_adapter.ex b/lib/mailman/local_smtp_adapter.ex index a19efc0..c72d46d 100644 --- a/lib/mailman/local_smtp_adapter.ex +++ b/lib/mailman/local_smtp_adapter.ex @@ -2,9 +2,9 @@ defmodule Mailman.LocalSmtpAdapter do @moduledoc "Adapter for using locally spawned SMTP server" @doc "Delivers an email through a locally running process" - def deliver(config, email, message) do + def deliver(config, email, message, opts \\ []) do Mailman.ExternalSmtpAdapter.deliver external_for(config), - email, message + email, message, opts end def external_for(config) do diff --git a/lib/mailman/local_smtp_config.ex b/lib/mailman/local_smtp_config.ex index da30c5c..297a904 100644 --- a/lib/mailman/local_smtp_config.ex +++ b/lib/mailman/local_smtp_config.ex @@ -5,7 +5,7 @@ defmodule Mailman.LocalSmtpConfig do end defimpl Mailman.Adapter, for: Mailman.LocalSmtpConfig do - def deliver(config, email, message) do - Mailman.LocalSmtpAdapter.deliver(config, email, message) + def deliver(config, email, message, opts \\ []) do + Mailman.LocalSmtpAdapter.deliver(config, email, message, opts) end end diff --git a/lib/mailman/smtp_config.ex b/lib/mailman/smtp_config.ex index 6471648..651cd07 100644 --- a/lib/mailman/smtp_config.ex +++ b/lib/mailman/smtp_config.ex @@ -12,7 +12,7 @@ defmodule Mailman.SmtpConfig do end defimpl Mailman.Adapter, for: Mailman.SmtpConfig do - def deliver(config, email, message) do - Mailman.ExternalSmtpAdapter.deliver(config, email, message) + def deliver(config, email, message, opts \\ []) do + Mailman.ExternalSmtpAdapter.deliver(config, email, message, opts) end end diff --git a/lib/mailman/test_config.ex b/lib/mailman/test_config.ex index b4fa836..c7f8ab8 100644 --- a/lib/mailman/test_config.ex +++ b/lib/mailman/test_config.ex @@ -5,7 +5,7 @@ defmodule Mailman.TestConfig do end defimpl Mailman.Adapter, for: Mailman.TestConfig do - def deliver(config, email, message) do - Mailman.TestingAdapter.deliver(config, email, message) + def deliver(config, email, message, opts \\ []) do + Mailman.TestingAdapter.deliver(config, email, message, opts) end end diff --git a/lib/mailman/testing_adapter.ex b/lib/mailman/testing_adapter.ex index fe42384..14fbb35 100644 --- a/lib/mailman/testing_adapter.ex +++ b/lib/mailman/testing_adapter.ex @@ -1,7 +1,7 @@ defmodule Mailman.TestingAdapter do @moduledoc "Implementation of the testing SMTP adapter" - def deliver(config, _email, message) do + def deliver(config, _email, message, _opts \\ []) do Task.async fn -> if config.store_deliveries do Mailman.TestServer.register_delivery message diff --git a/mix.lock b/mix.lock index 6017e88..68c74d4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,7 +1,7 @@ %{"amrita": {:git, "git://github.com/josephwilk/amrita.git", "7570eb766fa0506e4c08d241f5359dff9135f961", []}, "apprentice": {:git, "git://github.com/ElixirCasts/apprentice.git", "b9306b8316385c63d1e18492623a5cd3dc33df16", []}, "earmark": {:hex, :earmark, "0.1.13"}, - "eiconv": {:git, "git://github.com/zotonic/eiconv.git", "644fb5e7bd6640fbd073f4d28957914ea979aea0", []}, + "eiconv": {:git, "https://github.com/zotonic/eiconv.git", "644fb5e7bd6640fbd073f4d28957914ea979aea0", []}, "ex_doc": {:hex, :ex_doc, "0.7.1"}, "gen_smtp": {:hex, :gen_smtp, "0.9.0"}, "meck": {:git, "git://github.com/eproxus/meck.git", "62265e4a89297b3415502351a35082933225d1af", [branch: "develop"]}, diff --git a/test/mailman_test.exs b/test/mailman_test.exs index 79d33a8..89990c0 100644 --- a/test/mailman_test.exs +++ b/test/mailman_test.exs @@ -98,34 +98,34 @@ Pictures! assert MyApp.Mailer.deliver(testing_email).__struct__ == Task end - test "#deliver/2 returns list of Tasks if it includes :send_cc_and_bcc atom" do + test "#deliver/2 returns list of Tasks if it includes :send_cc_and_bcc atom" do assert MyApp.Mailer.deliver(testing_email, :send_cc_and_bcc) |> is_list == true assert MyApp.Mailer.deliver(testing_email, :send_cc_and_bcc) |> List.first |> is_map == true end - test "#deliver/2 sends emails to all address in CC and BCC list" do + test "#deliver/2 sends emails to all address in CC and BCC list" do Mailman.TestServer.clear_deliveries MyApp.Mailer.deliver(cc_and_bcc_testing_email, :send_cc_and_bcc) - |> Enum.map( fn(task) -> + |> Enum.map( fn(task) -> Task.await task end) assert (Mailman.TestServer.deliveries |> Enum.count) == 4 end - test "#deliver/2 redactes the BCC email from the TO message" do + test "#deliver/2 redactes the BCC email from the TO message" do Mailman.TestServer.clear_deliveries MyApp.Mailer.deliver(cc_and_bcc_testing_email, :send_cc_and_bcc) - |> Enum.map( fn(task) -> + |> Enum.map( fn(task) -> Task.await task end) to_email = Mailman.TestServer.deliveries |> List.last |> Mailman.Email.parse! assert to_email.bcc == [] end - test "#deliver/2 adds the BCC email to a BCC receiver" do + test "#deliver/2 adds the BCC email to a BCC receiver" do Mailman.TestServer.clear_deliveries MyApp.Mailer.deliver(cc_and_bcc_testing_email, :send_cc_and_bcc) - |> Enum.map( fn(task) -> + |> Enum.map( fn(task) -> Task.await task end) bcc_email = Mailman.TestServer.deliveries |> List.first |> Mailman.Email.parse! @@ -219,7 +219,7 @@ Pictures! {:ok, message} = Task.await(MyApp.ExternalTextMailer.deliver( email_with_external_text)) email = Mailman.Email.parse! message - assert email.text == + assert email.text == EEx.eval_file(email_with_external_text.text, email_with_external_text.data) end @@ -238,7 +238,7 @@ Pictures! } end end - + def email_with_external_html do %Mailman.Email{ subject: "Hello Mailman!", @@ -259,7 +259,7 @@ Pictures! {:ok, message} = Task.await(MyApp.ExternalHTMLMailer.deliver( email_with_external_html)) email = Mailman.Email.parse! message - assert email.html == + assert email.html == EEx.eval_file(email_with_external_html.html, email_with_external_html.data) end @@ -281,7 +281,7 @@ Pictures! } end end - + def email_with_template_paths do %Mailman.Email{ subject: "Hello Mailman!", @@ -297,12 +297,12 @@ Pictures! html: "email.html.eex" } end - + test "should load email parts from external file based on x_file_path" do {:ok, message} = Task.await(MyApp.ExternalTemplatesMailer.deliver( email_with_template_paths)) email = Mailman.Email.parse! message - assert email.html == + assert email.html == EEx.eval_file("test/templates/#{email_with_template_paths.html}", email_with_template_paths.data) assert email.text ==