Created
June 15, 2018 16:56
-
-
Save willricketts/4678dcd63606a8599c3a9f587a8f6f36 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule MyApp.ActivationToken do | |
import Ecto.Query | |
alias MyApp.Accounts.User | |
alias MyApp.Repo | |
@moduledoc """ | |
Responsible for generating uniuqe email activation tokens | |
""" | |
@length 64 | |
@query_limit 5 | |
@doc """ | |
Generates a unique random string for email activation | |
""" | |
def generate(acc \\ 0) do | |
@length | |
|> :crypto.strong_rand_bytes | |
|> Base.url_encode64 | |
|> binary_part(0, @length) | |
|> enforce_uniqueness(acc) | |
end | |
# Passes the generated token down to `is_unique?` and handles | |
# the result by either returning the token if unique, or calling | |
# generate again for another attempt at a unique token | |
defp enforce_uniqueness(token, acc) do | |
if acc >= @query_limit do | |
raise "Error. Something has gone terribly wrong in token generation" | |
end | |
case is_unique?(token) do | |
true -> token | |
_ -> generate(acc + 1) | |
end | |
end | |
# Passes the generated token down to `users_with_token` and | |
# verifies that the list returned is less than 1, returning | |
# a boolean | |
defp is_unique?(token) do | |
Enum.count(users_with_token(token)) <= 0 | |
end | |
# Queries the database for users whose activation token matches | |
# the newly generated one. Returns a list of those users | |
defp users_with_token(token) do | |
Repo.all( | |
from u in User, | |
where: u.activation_token == ^token | |
) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment