Add anonymous and remote participations
This commit is contained in:
@@ -97,20 +97,6 @@ defmodule Mobilizon.Actors.Actor do
|
||||
@remote_actor_creation_attrs @remote_actor_creation_required_attrs ++
|
||||
@remote_actor_creation_optional_attrs
|
||||
|
||||
@relay_creation_attrs [
|
||||
:type,
|
||||
:name,
|
||||
:summary,
|
||||
:url,
|
||||
:keys,
|
||||
:preferred_username,
|
||||
:domain,
|
||||
:inbox_url,
|
||||
:followers_url,
|
||||
:following_url,
|
||||
:shared_inbox_url
|
||||
]
|
||||
|
||||
@group_creation_required_attrs [:url, :outbox_url, :inbox_url, :type, :preferred_username]
|
||||
@group_creation_optional_attrs [:shared_inbox_url, :name, :domain, :summary]
|
||||
@group_creation_attrs @group_creation_required_attrs ++ @group_creation_optional_attrs
|
||||
@@ -277,16 +263,6 @@ defmodule Mobilizon.Actors.Actor do
|
||||
|> validate_format(:preferred_username, ~r/[a-z0-9_]+/)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Changeset for relay creation.
|
||||
"""
|
||||
@spec relay_creation_changeset(map) :: Ecto.Changeset.t()
|
||||
def relay_creation_changeset(attrs) do
|
||||
relay_creation_attrs = build_relay_creation_attrs(attrs)
|
||||
|
||||
cast(%__MODULE__{}, relay_creation_attrs, @relay_creation_attrs)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Changeset for group creation
|
||||
"""
|
||||
@@ -349,6 +325,10 @@ defmodule Mobilizon.Actors.Actor do
|
||||
|
||||
def build_url(username, :inbox, _args), do: "#{build_url(username, :page)}/inbox"
|
||||
|
||||
# Relay has a special URI
|
||||
def build_url("relay", :page, _args),
|
||||
do: Endpoint |> Routes.activity_pub_url(:relay) |> URI.decode()
|
||||
|
||||
def build_url(preferred_username, :page, args) do
|
||||
Endpoint
|
||||
|> Routes.page_url(:actor, preferred_username, args)
|
||||
@@ -362,24 +342,40 @@ defmodule Mobilizon.Actors.Actor do
|
||||
|> URI.decode()
|
||||
end
|
||||
|
||||
@spec build_relay_creation_attrs(map) :: map
|
||||
defp build_relay_creation_attrs(%{url: url, preferred_username: preferred_username}) do
|
||||
%{
|
||||
@spec build_relay_creation_attrs :: Ecto.Changeset.t()
|
||||
def build_relay_creation_attrs do
|
||||
data = %{
|
||||
"name" => Config.get([:instance, :name], "Mobilizon"),
|
||||
"summary" =>
|
||||
Config.get(
|
||||
[:instance, :description],
|
||||
"An internal service actor for this Mobilizon instance"
|
||||
),
|
||||
"url" => url,
|
||||
"keys" => Crypto.generate_rsa_2048_private_key(),
|
||||
"preferred_username" => preferred_username,
|
||||
"preferred_username" => "relay",
|
||||
"domain" => nil,
|
||||
"inbox_url" => "#{Endpoint.url()}/inbox",
|
||||
"followers_url" => "#{url}/followers",
|
||||
"following_url" => "#{url}/following",
|
||||
"shared_inbox_url" => "#{Endpoint.url()}/inbox",
|
||||
"type" => :Application
|
||||
}
|
||||
|
||||
%__MODULE__{}
|
||||
|> Ecto.Changeset.cast(data, @attrs)
|
||||
|> build_urls()
|
||||
|> put_change(:inbox_url, "#{Endpoint.url()}/inbox")
|
||||
end
|
||||
|
||||
@spec build_anonymous_actor_creation_attrs :: Ecto.Changeset.t()
|
||||
def build_anonymous_actor_creation_attrs do
|
||||
data = %{
|
||||
"name" => "Mobilizon Anonymous Actor",
|
||||
"summary" => "A fake person for anonymous participations",
|
||||
"keys" => Crypto.generate_rsa_2048_private_key(),
|
||||
"preferred_username" => "anonymous",
|
||||
"domain" => nil,
|
||||
"type" => :Person
|
||||
}
|
||||
|
||||
%__MODULE__{}
|
||||
|> Ecto.Changeset.cast(data, @attrs)
|
||||
|> build_urls()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -499,17 +499,22 @@ defmodule Mobilizon.Actors do
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@spec get_or_create_instance_actor_by_url(String.t(), String.t()) ::
|
||||
{:ok, Actor.t()} | {:error, Ecto.Changeset.t()}
|
||||
def get_or_create_instance_actor_by_url(url, preferred_username \\ "relay") do
|
||||
case get_actor_by_url(url) do
|
||||
@spec get_or_create_internal_actor(String.t()) :: {:ok, Actor.t()}
|
||||
def get_or_create_internal_actor(username) do
|
||||
case username |> Actor.build_url(:page) |> get_actor_by_url() do
|
||||
{:ok, %Actor{} = actor} ->
|
||||
{:ok, actor}
|
||||
|
||||
_ ->
|
||||
%{url: url, preferred_username: preferred_username}
|
||||
|> Actor.relay_creation_changeset()
|
||||
|> Repo.insert()
|
||||
case username do
|
||||
"anonymous" ->
|
||||
Actor.build_anonymous_actor_creation_attrs()
|
||||
|> Repo.insert()
|
||||
|
||||
"relay" ->
|
||||
Actor.build_relay_creation_attrs()
|
||||
|> Repo.insert()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ defmodule Mobilizon.Admin do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.{Admin, Users}
|
||||
alias Mobilizon.Admin.ActionLog
|
||||
alias Mobilizon.Admin.Setting
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
@@ -18,6 +19,8 @@ defmodule Mobilizon.Admin do
|
||||
"delete"
|
||||
])
|
||||
|
||||
alias Ecto.Multi
|
||||
|
||||
@doc """
|
||||
Creates a action_log.
|
||||
"""
|
||||
@@ -71,4 +74,48 @@ defmodule Mobilizon.Admin do
|
||||
end
|
||||
|
||||
defp stringify_struct(struct), do: struct
|
||||
|
||||
def get_admin_setting_value(group, name, fallback \\ nil)
|
||||
when is_bitstring(group) and is_bitstring(name) do
|
||||
case Repo.get_by(Setting, group: group, name: name) do
|
||||
nil -> fallback
|
||||
%Setting{value: ""} -> fallback
|
||||
%Setting{value: nil} -> fallback
|
||||
%Setting{value: value} -> value
|
||||
end
|
||||
end
|
||||
|
||||
def set_admin_setting_value(group, name, value) do
|
||||
Setting
|
||||
|> Setting.changeset(%{group: group, name: name, value: value})
|
||||
|> Repo.insert(on_conflict: :replace_all, conflict_target: [:group, :name])
|
||||
end
|
||||
|
||||
def save_settings(group, args) do
|
||||
Multi.new()
|
||||
|> do_save_setting(group, args)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
defp do_save_setting(transaction, _group, args) when args == %{}, do: transaction
|
||||
|
||||
defp do_save_setting(transaction, group, args) do
|
||||
key = hd(Map.keys(args))
|
||||
{val, rest} = Map.pop(args, key)
|
||||
|
||||
transaction =
|
||||
Multi.insert(
|
||||
transaction,
|
||||
key,
|
||||
Setting.changeset(%Setting{}, %{
|
||||
group: group,
|
||||
name: Atom.to_string(key),
|
||||
value: to_string(val)
|
||||
}),
|
||||
on_conflict: :replace_all,
|
||||
conflict_target: [:group, :name]
|
||||
)
|
||||
|
||||
do_save_setting(transaction, group, rest)
|
||||
end
|
||||
end
|
||||
|
||||
27
lib/mobilizon/admin/setting.ex
Normal file
27
lib/mobilizon/admin/setting.ex
Normal file
@@ -0,0 +1,27 @@
|
||||
defmodule Mobilizon.Admin.Setting do
|
||||
@moduledoc """
|
||||
A Key-Value settings table for basic settings
|
||||
"""
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@required_attrs [:group, :name]
|
||||
@optional_attrs [:value]
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
schema "admin_settings" do
|
||||
field(:group, :string)
|
||||
field(:name, :string)
|
||||
field(:value, :string)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(setting, attrs) do
|
||||
setting
|
||||
|> cast(attrs, @attrs)
|
||||
|> validate_required(@required_attrs)
|
||||
|> unique_constraint(:group, name: :admin_settings_group_name_index)
|
||||
end
|
||||
end
|
||||
@@ -3,14 +3,44 @@ defmodule Mobilizon.Config do
|
||||
Configuration wrapper.
|
||||
"""
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
|
||||
@spec instance_config :: keyword
|
||||
def instance_config, do: Application.get_env(:mobilizon, :instance)
|
||||
|
||||
@spec instance_name :: String.t()
|
||||
def instance_name, do: instance_config()[:name]
|
||||
def instance_name,
|
||||
do:
|
||||
Mobilizon.Admin.get_admin_setting_value(
|
||||
"instance",
|
||||
"instance_name",
|
||||
instance_config()[:name]
|
||||
)
|
||||
|
||||
@spec instance_description :: String.t()
|
||||
def instance_description, do: instance_config()[:description]
|
||||
def instance_description,
|
||||
do:
|
||||
Mobilizon.Admin.get_admin_setting_value(
|
||||
"instance",
|
||||
"instance_description",
|
||||
instance_config()[:description]
|
||||
)
|
||||
|
||||
@spec instance_terms(String.t()) :: String.t()
|
||||
def instance_terms(locale \\ "en") do
|
||||
Mobilizon.Admin.get_admin_setting_value("instance", "instance_terms", generate_terms(locale))
|
||||
end
|
||||
|
||||
@spec instance_terms :: String.t()
|
||||
def instance_terms_type do
|
||||
Mobilizon.Admin.get_admin_setting_value("instance", "instance_terms_type", "DEFAULT")
|
||||
end
|
||||
|
||||
@spec instance_terms :: String.t()
|
||||
def instance_terms_url do
|
||||
Mobilizon.Admin.get_admin_setting_value("instance", "instance_terms_url")
|
||||
end
|
||||
|
||||
@spec instance_version :: String.t()
|
||||
def instance_version, do: Mix.Project.config()[:version]
|
||||
@@ -19,7 +49,15 @@ defmodule Mobilizon.Config do
|
||||
def instance_hostname, do: instance_config()[:hostname]
|
||||
|
||||
@spec instance_registrations_open? :: boolean
|
||||
def instance_registrations_open?, do: to_boolean(instance_config()[:registrations_open])
|
||||
def instance_registrations_open?,
|
||||
do:
|
||||
to_boolean(
|
||||
Mobilizon.Admin.get_admin_setting_value(
|
||||
"instance",
|
||||
"registrations_open",
|
||||
instance_config()[:registrations_open]
|
||||
)
|
||||
)
|
||||
|
||||
@spec instance_registrations_whitelist :: list(String.t())
|
||||
def instance_registrations_whitelist, do: instance_config()[:registration_email_whitelist]
|
||||
@@ -58,6 +96,51 @@ defmodule Mobilizon.Config do
|
||||
def instance_maps_tiles_attribution,
|
||||
do: Application.get_env(:mobilizon, :maps)[:tiles][:attribution]
|
||||
|
||||
@spec anonymous_participation? :: boolean
|
||||
def anonymous_participation?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:participation][:allowed]
|
||||
|
||||
@spec anonymous_participation_email_required? :: boolean
|
||||
def anonymous_participation_email_required?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:participation][:validation][:email][:enabled]
|
||||
|
||||
@spec anonymous_participation_email_confirmation_required? :: boolean
|
||||
def anonymous_participation_email_confirmation_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:participation][:validation][:email][
|
||||
:confirmation_required
|
||||
]
|
||||
|
||||
@spec anonymous_participation_email_captcha_required? :: boolean
|
||||
def anonymous_participation_email_captcha_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:participation][:validation][:captcha][:enabled]
|
||||
|
||||
@spec anonymous_event_creation? :: boolean
|
||||
def anonymous_event_creation?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:event_creation][:allowed]
|
||||
|
||||
@spec anonymous_event_creation_email_required? :: boolean
|
||||
def anonymous_event_creation_email_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:event_creation][:validation][:email][:enabled]
|
||||
|
||||
@spec anonymous_event_creation_email_confirmation_required? :: boolean
|
||||
def anonymous_event_creation_email_confirmation_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:event_creation][:validation][:email][
|
||||
:confirmation_required
|
||||
]
|
||||
|
||||
@spec anonymous_event_creation_email_captcha_required? :: boolean
|
||||
def anonymous_event_creation_email_captcha_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:event_creation][:validation][:captcha][
|
||||
:enabled
|
||||
]
|
||||
|
||||
def anonymous_actor_id, do: get_cached_value(:anonymous_actor_id)
|
||||
|
||||
@spec get(module | atom) :: any
|
||||
def get(key), do: get(key, nil)
|
||||
|
||||
@@ -99,4 +182,38 @@ defmodule Mobilizon.Config do
|
||||
|
||||
@spec to_boolean(boolean | String.t()) :: boolean
|
||||
defp to_boolean(boolean), do: "true" == String.downcase("#{boolean}")
|
||||
|
||||
defp get_cached_value(key) do
|
||||
case Cachex.fetch(:config, key, fn key ->
|
||||
case create_cache(key) do
|
||||
value when not is_nil(value) -> {:commit, value}
|
||||
err -> {:ignore, err}
|
||||
end
|
||||
end) do
|
||||
{status, value} when status in [:ok, :commit] -> value
|
||||
_err -> nil
|
||||
end
|
||||
end
|
||||
|
||||
@spec create_cache(atom()) :: integer()
|
||||
defp create_cache(:anonymous_actor_id) do
|
||||
with {:ok, %Actor{id: actor_id}} <- Actors.get_or_create_internal_actor("anonymous") do
|
||||
actor_id
|
||||
end
|
||||
end
|
||||
|
||||
def clear_config_cache do
|
||||
Cachex.clear(:config)
|
||||
end
|
||||
|
||||
def generate_terms(locale) do
|
||||
import Mobilizon.Web.Gettext
|
||||
put_locale(locale)
|
||||
|
||||
Phoenix.View.render_to_string(
|
||||
Mobilizon.Web.APIView,
|
||||
"terms.html",
|
||||
[]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,6 +17,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
maximum_attendee_capacity: integer,
|
||||
remaining_attendee_capacity: integer,
|
||||
show_remaining_attendee_capacity: boolean,
|
||||
anonymous_participation: boolean,
|
||||
attendees: [String.t()],
|
||||
program: String.t(),
|
||||
comment_moderation: CommentModeration.t(),
|
||||
@@ -31,6 +32,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
:maximum_attendee_capacity,
|
||||
:remaining_attendee_capacity,
|
||||
:show_remaining_attendee_capacity,
|
||||
:anonymous_participation,
|
||||
:attendees,
|
||||
:program,
|
||||
:comment_moderation,
|
||||
@@ -45,6 +47,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
field(:maximum_attendee_capacity, :integer)
|
||||
field(:remaining_attendee_capacity, :integer)
|
||||
field(:show_remaining_attendee_capacity, :boolean)
|
||||
field(:anonymous_participation, :boolean)
|
||||
field(:attendees, {:array, :string})
|
||||
field(:program, :string)
|
||||
field(:comment_moderation, CommentModeration)
|
||||
|
||||
@@ -8,6 +8,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
not_approved: integer(),
|
||||
not_confirmed: integer(),
|
||||
rejected: integer(),
|
||||
participant: integer(),
|
||||
moderator: integer(),
|
||||
@@ -17,6 +18,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
|
||||
@attrs [
|
||||
:not_approved,
|
||||
:not_confirmed,
|
||||
:rejected,
|
||||
:participant,
|
||||
:moderator,
|
||||
@@ -29,6 +31,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
@derive Jason.Encoder
|
||||
embedded_schema do
|
||||
field(:not_approved, :integer, default: 0)
|
||||
field(:not_confirmed, :integer, default: 0)
|
||||
field(:rejected, :integer, default: 0)
|
||||
field(:participant, :integer, default: 0)
|
||||
field(:moderator, :integer, default: 0)
|
||||
@@ -47,6 +50,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
defp validate_stats(%Ecto.Changeset{} = changeset) do
|
||||
changeset
|
||||
|> validate_number(:not_approved, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:not_confirmed, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:rejected, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:participant, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:moderator, greater_than_or_equal_to: 0)
|
||||
|
||||
@@ -76,6 +76,7 @@ defmodule Mobilizon.Events do
|
||||
|
||||
defenum(ParticipantRole, :participant_role, [
|
||||
:not_approved,
|
||||
:not_confirmed,
|
||||
:rejected,
|
||||
:participant,
|
||||
:moderator,
|
||||
@@ -661,9 +662,39 @@ defmodule Mobilizon.Events do
|
||||
@doc """
|
||||
Gets a single participation for an event and actor.
|
||||
"""
|
||||
@spec get_participant(integer | String.t(), integer | String.t()) ::
|
||||
@spec get_participant(integer | String.t(), integer | String.t(), map()) ::
|
||||
{:ok, Participant.t()} | {:error, :participant_not_found}
|
||||
def get_participant(event_id, actor_id) do
|
||||
def get_participant(event_id, actor_id, params \\ %{})
|
||||
|
||||
# This one if to check someone doesn't go to the same event twice
|
||||
def get_participant(event_id, actor_id, %{email: email}) do
|
||||
case Participant
|
||||
|> where([p], event_id: ^event_id, actor_id: ^actor_id)
|
||||
|> where([p], fragment("? ->>'email' = ?", p.metadata, ^email))
|
||||
|> Repo.one() do
|
||||
%Participant{} = participant ->
|
||||
{:ok, participant}
|
||||
|
||||
nil ->
|
||||
{:error, :participant_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
# This one if for finding participants by their cancellation token when wanting to cancel a participation
|
||||
def get_participant(event_id, actor_id, %{cancellation_token: cancellation_token}) do
|
||||
case Participant
|
||||
|> where([p], event_id: ^event_id, actor_id: ^actor_id)
|
||||
|> where([p], fragment("? ->>'cancellation_token' = ?", p.metadata, ^cancellation_token))
|
||||
|> Repo.one() do
|
||||
%Participant{} = participant ->
|
||||
{:ok, participant}
|
||||
|
||||
nil ->
|
||||
{:error, :participant_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def get_participant(event_id, actor_id, %{}) do
|
||||
case Repo.get_by(Participant, event_id: event_id, actor_id: actor_id) do
|
||||
%Participant{} = participant ->
|
||||
{:ok, participant}
|
||||
@@ -673,6 +704,14 @@ defmodule Mobilizon.Events do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_participant_by_confirmation_token(String.t()) :: Participant.t()
|
||||
def get_participant_by_confirmation_token(confirmation_token) do
|
||||
Participant
|
||||
|> where([p], fragment("? ->>'confirmation_token' = ?", p.metadata, ^confirmation_token))
|
||||
|> preload([p], [:actor, :event])
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single participation for an event and actor.
|
||||
|
||||
@@ -706,7 +745,7 @@ defmodule Mobilizon.Events do
|
||||
|
||||
@doc """
|
||||
Returns the list of participants for an event.
|
||||
Default behaviour is to not return :not_approved participants
|
||||
Default behaviour is to not return :not_approved or :not_confirmed participants
|
||||
"""
|
||||
@spec list_participants_for_event(String.t(), list(atom()), integer | nil, integer | nil) ::
|
||||
[Participant.t()]
|
||||
|
||||
@@ -10,6 +10,7 @@ defmodule Mobilizon.Events.Participant do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.Events.{Event, ParticipantRole}
|
||||
alias Mobilizon.Web.Email.Checker
|
||||
|
||||
alias Mobilizon.Web.Endpoint
|
||||
|
||||
@@ -28,6 +29,12 @@ defmodule Mobilizon.Events.Participant do
|
||||
field(:role, ParticipantRole, default: :participant)
|
||||
field(:url, :string)
|
||||
|
||||
embeds_one :metadata, Metadata, on_replace: :delete do
|
||||
field(:email, :string)
|
||||
field(:confirmation_token, :string)
|
||||
field(:cancellation_token, :string)
|
||||
end
|
||||
|
||||
belongs_to(:event, Event, primary_key: true)
|
||||
belongs_to(:actor, Actor, primary_key: true)
|
||||
|
||||
@@ -55,11 +62,18 @@ defmodule Mobilizon.Events.Participant do
|
||||
def changeset(%__MODULE__{} = participant, attrs) do
|
||||
participant
|
||||
|> cast(attrs, @attrs)
|
||||
|> cast_embed(:metadata, with: &metadata_changeset/2)
|
||||
|> ensure_url()
|
||||
|> validate_required(@required_attrs)
|
||||
|> unique_constraint(:actor_id, name: :participants_event_id_actor_id_index)
|
||||
end
|
||||
|
||||
defp metadata_changeset(schema, params) do
|
||||
schema
|
||||
|> cast(params, [:email, :confirmation_token, :cancellation_token])
|
||||
|> Checker.validate_changeset()
|
||||
end
|
||||
|
||||
# If there's a blank URL that's because we're doing the first insert
|
||||
@spec ensure_url(Ecto.Changeset.t()) :: Ecto.Changeset.t()
|
||||
defp ensure_url(%Ecto.Changeset{data: %__MODULE__{url: nil}} = changeset) do
|
||||
|
||||
@@ -11,8 +11,7 @@ defmodule Mobilizon.Users.User do
|
||||
alias Mobilizon.Crypto
|
||||
alias Mobilizon.Events.FeedToken
|
||||
alias Mobilizon.Users.UserRole
|
||||
|
||||
alias Mobilizon.Web.Email
|
||||
alias Mobilizon.Web.Email.Checker
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
email: String.t(),
|
||||
@@ -79,7 +78,7 @@ defmodule Mobilizon.Users.User do
|
||||
|> cast(attrs, @attrs)
|
||||
|> validate_required(@required_attrs)
|
||||
|> unique_constraint(:email, message: "This email is already used.")
|
||||
|> validate_email()
|
||||
|> Checker.validate_changeset()
|
||||
|> validate_length(:password, min: 6, max: 200, message: "The chosen password is too short.")
|
||||
|
||||
if Map.has_key?(attrs, :default_actor) do
|
||||
@@ -171,25 +170,6 @@ defmodule Mobilizon.Users.User do
|
||||
|
||||
defp save_confirmation_token(%Ecto.Changeset{} = changeset), do: changeset
|
||||
|
||||
@spec validate_email(Ecto.Changeset.t()) :: Ecto.Changeset.t()
|
||||
defp validate_email(%Ecto.Changeset{} = changeset) do
|
||||
changeset = validate_length(changeset, :email, min: 3, max: 250)
|
||||
|
||||
case changeset do
|
||||
%Ecto.Changeset{valid?: true, changes: %{email: email}} ->
|
||||
case Email.Checker.valid?(email) do
|
||||
false ->
|
||||
add_error(changeset, :email, "Email doesn't fit required format")
|
||||
|
||||
true ->
|
||||
changeset
|
||||
end
|
||||
|
||||
_ ->
|
||||
changeset
|
||||
end
|
||||
end
|
||||
|
||||
@spec hash_password(Ecto.Changeset.t()) :: Ecto.Changeset.t()
|
||||
defp hash_password(%Ecto.Changeset{} = changeset) do
|
||||
case changeset do
|
||||
|
||||
Reference in New Issue
Block a user