Skip to content

Commit

Permalink
Merge branch 'master' of github.com:FGRibreau/mailchecker
Browse files Browse the repository at this point in the history
  • Loading branch information
FGRibreau committed Oct 18, 2015
2 parents e5148a0 + ada8ab0 commit a71e5b5
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
language: ruby
rvm:
- 2.2.2
before_install: gem install bundler -v 1.10.6
script: ruby test/platform.ruby.test.rb
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ MailChecker currently supports:
* [PHP](https://github.com/FGRibreau/mailchecker/tree/master/platform/php)
* [Python](https://github.com/FGRibreau/mailchecker/tree/master/platform/python)
* [Ruby](https://github.com/FGRibreau/mailchecker/tree/master/platform/ruby)
* [Elixir](https://github.com/FGRibreau/mailchecker/tree/master/platform/elixir)
* [Clojure](https://github.com/FGRibreau/mailchecker/tree/master/platform/clojure)
* **Easily add support for your own language with MailChecker template system and [send us a pull-request!](https://github.com/FGRibreau/mailchecker/fork_select)**

-------------------------
Expand Down Expand Up @@ -74,6 +76,20 @@ if(!MailChecker('myemail.com')){
}
```

### Elixir

```elixir
Code.require_file("mail_checker.ex", "mailchecker/platform/elixir/")

unless MailChecker.valid?("myemail@yopmail.com") do
raise "O RLY !"
end

unless MailChecker.valid?("myemail.com") do
raise "O RLY !"
end
```

### Python

```python
Expand All @@ -85,7 +101,7 @@ if not m.is_valid('bla@example.com'):
print "O RLY !"
```

### Ruby
### Ruby [![Build Status](https://travis-ci.org/FGRibreau/mailchecker.svg)](https://travis-ci.org/FGRibreau/mailchecker)

```ruby
require 'mail_checker'
Expand All @@ -99,6 +115,19 @@ unless MailChecker.valid?('myemail@yopmail.com')
end
```

### Clojure

```clojure
; no package yet; just drop in mailchecker.clj where you want to use it.
(load-file "platform/clojure/mailchecker.clj")

(if (not (mailchecker/valid? "myemail@yopmail.com"))
(throw (Throwable. "O RLY!")))

(if (not (mailchecker/valid? "myemail.com"))
(throw (Throwable. "O RLY!")))
```

--------------------


Expand Down
59 changes: 59 additions & 0 deletions platform/clojure/mailchecker.clj

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions platform/clojure/mailchecker.tmpl.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
(ns mailchecker)

(require '[clojure.string :as str])

(def ^:const blacklist (set [{{& listSTR }}]))

; Source: https://github.com/scstarkey/noir/blob/998e846dd44f42b8e01a6977e6d22a3eff5e4542/src/noir/validation.clj#L37-L40
; Modified to return true/false
(defn is-email?
"Returns true if email is an email address"
[email]
(if (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)
true false))

(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))))
28 changes: 28 additions & 0 deletions platform/elixir/mail_checker.ex

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions platform/elixir/mail_checker.tmpl.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule MailChecker do
def valid?(email) do
valid_address?(email) && !in_blacklist?(email)
end

def in_blacklist?(email) do
set = Enum.into(blacklist, HashSet.new)

member = HashSet.member?(set, extract_top_domain(email))
member
end

def blacklist do
[{{& listSTR }}]
end

def extract_top_domain(email) do
domain = String.split(email, "@") |> List.last
domain_parts = String.split(domain, ".")
top_domain_part = Enum.slice(domain_parts, -2..2)
Enum.join(top_domain_part, ".")
end

def valid_address?(email) do
Regex.match?(~r/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/i, email)
end

end
39 changes: 39 additions & 0 deletions test/platform.clojure.test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; Run test with the lein-exec plugin:
; $ lein exec test/platform.clojure.test.clj
(load-file "platform/clojure/mailchecker.clj")

(ns clojure.test.example
(:use clojure.test))

; Valid
(deftest true-for-valid-1
(is (= true (mailchecker/valid? "plop@plop.com"))))
(deftest true-for-valid-2
(is (= true (mailchecker/valid? "my.ok@ok.plop.com"))))
(deftest true-for-valid-3
(is (= true (mailchecker/valid? "my+ok@ok.plop.com"))))
(deftest true-for-valid-4
(is (= true (mailchecker/valid? "my=ok@ok.plop.com"))))
(deftest true-for-valid-5
(is (= true (mailchecker/valid? "ok@gmail.com"))))
(deftest true-for-valid-6
(is (= true (mailchecker/valid? "ok@hotmail.com"))))

; Invalid
(deftest false-for-invalid-1
(is(= false (mailchecker/valid? "plopplop.com"))))
(deftest false-for-invalid-2
(is(= false (mailchecker/valid? "my+ok@ok=plop.com"))))
(deftest false-for-invalid-3
(is(= false (mailchecker/valid? "my,ok@ok.plop.com"))))

(deftest false-for-spam-1
(is(= false (mailchecker/valid? "ok@tmail.com"))))
(deftest false-for-spam-2
(is(= false (mailchecker/valid? "ok@33mail.com"))))
(deftest false-for-spam-3
(is(= false (mailchecker/valid? "ok@ok.33mail.com"))))
(deftest false-for-spam-4
(is(= false (mailchecker/valid? "ok@guerrillamailblock.com"))))

(run-all-tests)
36 changes: 36 additions & 0 deletions test/platform.elixir.test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Run tests from the repository root directory:
# $ elixir test/platform.elixir.test.exs
ExUnit.start

try do
Code.require_file("mail_checker.ex", "platform/elixir/")
rescue
_ -> raise ArgumentError, message: "You must be in the repository root directory in order to run the tests."
end

defmodule MailCheckerTest do
use ExUnit.Case

test "should return true if the email is valid" do
assert MailChecker.valid?("plop@plop.com")
assert MailChecker.valid?("my.ok@ok.plop.com")
assert MailChecker.valid?("my+ok@ok.plop.com")
assert MailChecker.valid?("my=ok@ok.plop.com")
assert MailChecker.valid?("ok@gmail.com")
assert MailChecker.valid?("ok@hotmail.com")
end

test "should return false if the email is invalid" do
assert MailChecker.valid?("plopplop.com") == false
assert MailChecker.valid?("my+ok@ok°plop.com") == false
assert MailChecker.valid?("my+ok@ok=plop.com") == false
assert MailChecker.valid?("my,ok@ok.plop.com") == false
assert MailChecker.valid?("ok@tmail.com") == false
end

test "should return false if the email come from a throwable domain" do
assert MailChecker.valid?("ok@33mail.com") == false
assert MailChecker.valid?("ok@ok.33mail.com") == false
end

end

0 comments on commit a71e5b5

Please sign in to comment.