From 3f2c4e8c99db7d7117da050bbe44dfca719b9bec Mon Sep 17 00:00:00 2001 From: Jacob Burenstam Date: Fri, 2 Oct 2015 21:29:09 +0200 Subject: [PATCH] First draft of Clojure implementation --- platform/clojure/mailchecker.clj | 79 +++++++++++++++++++++++++++ platform/clojure/mailchecker.tmpl.clj | 79 +++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 platform/clojure/mailchecker.clj create mode 100644 platform/clojure/mailchecker.tmpl.clj diff --git a/platform/clojure/mailchecker.clj b/platform/clojure/mailchecker.clj new file mode 100644 index 00000000..d3972782 --- /dev/null +++ b/platform/clojure/mailchecker.clj @@ -0,0 +1,79 @@ +(ns mailchecker) + +(require '[clojure.string :as str]) + +(def ^:const blacklist (set ["a", "b"])) + +; Copied from https://github.com/scstarkey/noir/blob/998e846dd44f42b8e01a6977e6d22a3eff5e4542/src/noir/validation.clj#L37-L40 +(defn is-email? + "Returns true if email is an email address" + [email] + (re-matches #"(?i)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" email)) + +(defn at-split + "Returns list from string splitted on @ char" + [email] + (str/split email #"@")) + +(defn last-element + "Returns the last element of the arr" + [arr] + (first + (take-last 1 arr))) + +(defn domain-part + "Returns the domain part from email" + [email] + (last-element (at-split email))) + +(defn dot-join + "Returns string from arr joined with dot char" + [arr] + (str/join "." arr)) + +(defn dot-split + "Returns list from string splitted on dot char" + [string] + (str/split string #"\.")) + +(defn top-domain-part + "Returns the top domain for email" + [email] + (dot-join + (take-last 2 + (dot-split (domain-part email))))) + +(defn in-blacklist? + "Returns true if email domain is not in the blacklist" + [email] + (contains? blacklist (top-domain-part email))) + +(defn valid? + "Returns true if the email is valid" + [email] + (and + (is-email? email) + (not + (in-blacklist? email)))) + +; (println (valid? "test@example.com")) +; (println (valid? "example.com")) +; (println (top-domain-part "test@sub.example.com")) + +; Valid +(println (valid? "plop@plop.com")) +(println (valid? "my.ok@ok.plop.com")) +(println (valid? "my+ok@ok.plop.com")) +(println (valid? "my=ok@ok.plop.com")) +(println (valid? "ok@gmail.com")) +(println (valid? "ok@hotmail.com")) + +; Invalid +(println (not (valid? "plopplop.com"))) +(println (not (valid? "my+ok@ok=plop.com"))) +(println (not (valid? "my,ok@ok.plop.com"))) + +(println (not (valid? "ok@tmail.com"))) +(println (not (valid? "ok@33mail.com"))) +(println (not (valid? "ok@ok.33mail.com"))) +(println (not (valid? "ok@guerrillamailblock.com"))) diff --git a/platform/clojure/mailchecker.tmpl.clj b/platform/clojure/mailchecker.tmpl.clj new file mode 100644 index 00000000..4f402f3b --- /dev/null +++ b/platform/clojure/mailchecker.tmpl.clj @@ -0,0 +1,79 @@ +(ns mailchecker) + +(require '[clojure.string :as str]) + +(def ^:const blacklist (set [{{& listSTR }}])) + +; Copied from https://github.com/scstarkey/noir/blob/998e846dd44f42b8e01a6977e6d22a3eff5e4542/src/noir/validation.clj#L37-L40 +(defn is-email? + "Returns true if email is an email address" + [email] + (re-matches #"(?i)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" email)) + +(defn at-split + "Returns list from string splitted on @ char" + [email] + (str/split email #"@")) + +(defn last-element + "Returns the last element of the arr" + [arr] + (first + (take-last 1 arr))) + +(defn domain-part + "Returns the domain part from email" + [email] + (last-element (at-split email))) + +(defn dot-join + "Returns string from arr joined with dot char" + [arr] + (str/join "." arr)) + +(defn dot-split + "Returns list from string splitted on dot char" + [string] + (str/split string #"\.")) + +(defn top-domain-part + "Returns the top domain for email" + [email] + (dot-join + (take-last 2 + (dot-split (domain-part email))))) + +(defn in-blacklist? + "Returns true if email domain is not in the blacklist" + [email] + (contains? blacklist (top-domain-part email))) + +(defn valid? + "Returns true if the email is valid" + [email] + (and + (is-email? email) + (not + (in-blacklist? email)))) + +; (println (valid? "test@example.com")) +; (println (valid? "example.com")) +; (println (top-domain-part "test@sub.example.com")) + +; Valid +(println (valid? "plop@plop.com")) +(println (valid? "my.ok@ok.plop.com")) +(println (valid? "my+ok@ok.plop.com")) +(println (valid? "my=ok@ok.plop.com")) +(println (valid? "ok@gmail.com")) +(println (valid? "ok@hotmail.com")) + +; Invalid +(println (not (valid? "plopplop.com"))) +(println (not (valid? "my+ok@ok=plop.com"))) +(println (not (valid? "my,ok@ok.plop.com"))) + +(println (not (valid? "ok@tmail.com"))) +(println (not (valid? "ok@33mail.com"))) +(println (not (valid? "ok@ok.33mail.com"))) +(println (not (valid? "ok@guerrillamailblock.com")))