Better docs

Signed-off-by: Thomas Citharel <tcit@tcit.fr>

Nicer docs

No 3rd stage

Add mix.deps get before docs

Add :ex_doc on test env so that it runs into CI
This commit is contained in:
Thomas Citharel
2019-03-14 15:00:34 +01:00
parent c20eaa379c
commit bba6629046
19 changed files with 772 additions and 150 deletions

View File

@@ -0,0 +1,45 @@
defmodule Mobilizon.Service.Users.Activation do
@moduledoc false
alias Mobilizon.{Mailer, Users}
alias Mobilizon.Users.User
alias Mobilizon.Email.User, as: UserEmail
alias Mobilizon.Service.Users.Tools
require Logger
@doc false
def check_confirmation_token(token) when is_binary(token) do
with %User{} = user <- Users.get_user_by_activation_token(token),
{:ok, %User{} = user} <-
Users.update_user(user, %{
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
"confirmation_sent_at" => nil,
"confirmation_token" => nil
}) do
Logger.info("User #{user.email} has been confirmed")
{:ok, user}
else
_err ->
{:error, :invalid_token}
end
end
def resend_confirmation_email(%User{} = user, locale \\ "en") do
with :ok <- Tools.we_can_send_email(user, :confirmation_sent_at),
{:ok, user} <-
Users.update_user(user, %{
"confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
}) do
send_confirmation_email(user, locale)
Logger.info("Sent confirmation email again to #{user.email}")
{:ok, user.email}
end
end
def send_confirmation_email(%User{} = user, locale \\ "en") do
user
|> UserEmail.confirmation_email(locale)
|> Mailer.deliver_later()
end
end

View File

@@ -0,0 +1,60 @@
defmodule Mobilizon.Service.Users.ResetPassword do
@moduledoc false
require Logger
alias Mobilizon.Users.User
alias Mobilizon.{Mailer, Repo, Users}
alias Mobilizon.Email.User, as: UserEmail
alias Mobilizon.Service.Users.Tools
@doc """
Check that the provided token is correct and update provided password
"""
@spec check_reset_password_token(String.t(), String.t()) :: tuple
def check_reset_password_token(password, token) do
with %User{} = user <- Users.get_user_by_reset_password_token(token),
{:ok, %User{} = user} <-
Repo.update(
User.password_reset_changeset(user, %{
"password" => password,
"reset_password_sent_at" => nil,
"reset_password_token" => nil
})
) do
{:ok, user}
else
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
{:error,
"The password you have choosen is too short. Please make sure your password contains at least 6 charaters."}
_err ->
{:error,
"The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."}
end
end
@doc """
Send the email reset password, if it's not too soon since the last send
"""
@spec send_password_reset_email(User.t(), String.t()) :: tuple
def send_password_reset_email(%User{} = user, locale \\ "en") do
with :ok <- Tools.we_can_send_email(user, :reset_password_sent_at),
{:ok, %User{} = user_updated} <-
Repo.update(
User.send_password_reset_changeset(user, %{
"reset_password_token" => Tools.random_string(30),
"reset_password_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
})
) do
mail =
user_updated
|> UserEmail.reset_password_email(locale)
|> Mailer.deliver_later()
{:ok, mail}
else
{:error, reason} -> {:error, reason}
end
end
end

View File

@@ -0,0 +1,43 @@
defmodule Mobilizon.Service.Users.Tools do
@moduledoc """
Common functions for actors services
"""
alias Mobilizon.Users.User
@spec we_can_send_email(User.t(), atom()) :: :ok | {:error, :email_too_soon}
def we_can_send_email(%User{} = user, key \\ :reset_password_sent_at) do
case Map.get(user, key) do
nil ->
:ok
_ ->
case Timex.before?(
Timex.shift(Map.get(user, key), hours: 1),
DateTime.utc_now() |> DateTime.truncate(:second)
) do
true ->
:ok
false ->
{:error, :email_too_soon}
end
end
end
@spec random_string(integer) :: String.t()
def random_string(length) do
length
|> :crypto.strong_rand_bytes()
|> Base.url_encode64()
end
end
defmodule Mobilizon.Users.Guards do
@moduledoc """
Guards for users
"""
defguard is_admin(role) when is_atom(role) and role == :administrator
defguard is_moderator(role) when is_atom(role) and role in [:administrator, :moderator]
end