X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fuser.ex;h=f10cdfbc8ee21b6c78eb147948af94ac88aa22c0;hb=7d9ddbe6894a29dd41789ab584b2cd9f0e686c47;hp=3984e610ecb88eaf1ae0ed6c55df6265313a502f;hpb=7bcb6a183a13cabd32bafd0e3ca20f8ca543565b;p=akkoma diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 3984e610e..f10cdfbc8 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -9,6 +9,13 @@ defmodule Pleroma.User do alias Pleroma.Web.{OStatus, Websub, OAuth} alias Pleroma.Web.ActivityPub.{Utils, ActivityPub} + @type t :: %__MODULE__{} + + @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ + + @strict_local_nickname_regex ~r/^[a-zA-Z\d]+$/ + @extended_local_nickname_regex ~r/^[a-zA-Z\d_]+$/ + schema "users" do field(:bio, :string) field(:email, :string) @@ -63,10 +70,6 @@ defmodule Pleroma.User do |> validate_required([:following]) end - def info_changeset(struct, params \\ %{}) do - raise "NOT VALID ANYMORE" - end - def user_info(%User{} = user) do oneself = if user.local, do: 1, else: 0 @@ -79,7 +82,6 @@ defmodule Pleroma.User do } end - @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ def remote_user_creation(params) do params = params @@ -119,7 +121,7 @@ defmodule Pleroma.User do struct |> cast(params, [:bio, :name, :avatar]) |> unique_constraint(:nickname) - |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/) + |> validate_format(:nickname, local_nickname_regex()) |> validate_length(:bio, max: 5000) |> validate_length(:name, min: 1, max: 100) end @@ -136,7 +138,7 @@ defmodule Pleroma.User do struct |> cast(params, [:bio, :name, :follower_address, :avatar, :last_refreshed_at]) |> unique_constraint(:nickname) - |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/) + |> validate_format(:nickname, local_nickname_regex()) |> validate_length(:bio, max: 5000) |> validate_length(:name, max: 100) |> put_embed(:info, info_cng) @@ -174,7 +176,7 @@ defmodule Pleroma.User do |> validate_confirmation(:password) |> unique_constraint(:email) |> unique_constraint(:nickname) - |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/) + |> validate_format(:nickname, local_nickname_regex()) |> validate_format(:email, @email_regex) |> validate_length(:bio, max: 1000) |> validate_length(:name, min: 1, max: 100) @@ -214,14 +216,14 @@ defmodule Pleroma.User do end def maybe_direct_follow(%User{} = follower, %User{} = followed) do - if !User.ap_enabled?(followed) do + if not User.ap_enabled?(followed) do follow(follower, followed) else {:ok, follower} end end - def maybe_follow(%User{} = follower, %User{info: info} = followed) do + def maybe_follow(%User{} = follower, %User{info: _info} = followed) do if not following?(follower, followed) do follow(follower, followed) else @@ -283,6 +285,7 @@ defmodule Pleroma.User do end end + @spec following?(User.t(), User.t()) :: boolean def following?(%User{} = follower, %User{} = followed) do Enum.member?(follower.following, followed.follower_address) end @@ -737,7 +740,8 @@ defmodule Pleroma.User do source_data: %{"publicKey" => %{"publicKeyPem" => public_key_pem}} }) do key = - :public_key.pem_decode(public_key_pem) + public_key_pem + |> :public_key.pem_decode() |> hd() |> :public_key.pem_entry_decode() @@ -775,13 +779,10 @@ defmodule Pleroma.User do def ap_enabled?(%User{info: info}), do: info.ap_enabled def ap_enabled?(_), do: false - def get_or_fetch(uri_or_nickname) do - if String.starts_with?(uri_or_nickname, "http") do - get_or_fetch_by_ap_id(uri_or_nickname) - else - get_or_fetch_by_nickname(uri_or_nickname) - end - end + @doc "Gets or fetch a user by uri or nickname." + @spec get_or_fetch(String.t()) :: User.t() + def get_or_fetch("http" <> _host = uri), do: get_or_fetch_by_ap_id(uri) + def get_or_fetch(nickname), do: get_or_fetch_by_nickname(nickname) # wait a period of time and return newest version of the User structs # this is because we have synchronous follow APIs and need to simulate them @@ -807,7 +808,11 @@ defmodule Pleroma.User do end end - def parse_bio(bio, user \\ %User{info: %{source_data: %{}}}) do + def parse_bio(bio, user \\ %User{info: %{source_data: %{}}}) + def parse_bio(nil, _user), do: "" + def parse_bio(bio, _user) when bio == "", do: bio + + def parse_bio(bio, user) do mentions = Formatter.parse_mentions(bio) tags = Formatter.parse_tags(bio) @@ -818,47 +823,54 @@ defmodule Pleroma.User do {String.trim(name, ":"), url} end) - CommonUtils.format_input(bio, mentions, tags, "text/plain") |> Formatter.emojify(emoji) + bio + |> CommonUtils.format_input(mentions, tags, "text/plain") + |> Formatter.emojify(emoji) end - def tag(user_identifiers, tags), do: tag_or_untag(user_identifiers, tags, :tag) - - def untag(user_identifiers, tags), do: tag_or_untag(user_identifiers, tags, :untag) + def tag(user_identifiers, tags) when is_list(user_identifiers) do + Repo.transaction(fn -> + for user_identifier <- user_identifiers, do: tag(user_identifier, tags) + end) + end - defp tag_or_untag(user_identifier, tags, action) when not is_list(user_identifier), - do: tag_or_untag([user_identifier], tags, action) + def tag(nickname, tags) when is_binary(nickname), + do: tag(User.get_by_nickname(nickname), tags) - defp tag_or_untag([hd | _] = nicknames, tags, action) when is_binary(hd) do - users = Repo.all(from(u in User, where: u.nickname in ^nicknames)) + def tag(%User{} = user, tags), + do: update_tags(user, Enum.uniq(user.tags ++ normalize_tags(tags))) - if length(users) == length(nicknames) do - tag_or_untag(users, tags, action) - else - {:error, :not_found} - end + def untag(user_identifiers, tags) when is_list(user_identifiers) do + Repo.transaction(fn -> + for user_identifier <- user_identifiers, do: untag(user_identifier, tags) + end) end - defp tag_or_untag([hd | _] = users, tags, action) when is_map(hd) do - tags = - [tags] - |> List.flatten() - |> Enum.map(&String.downcase(&1)) + def untag(nickname, tags) when is_binary(nickname), + do: untag(User.get_by_nickname(nickname), tags) - Repo.transaction(fn -> - for user <- users do - new_tags = mutate_tags(user, tags, action) + def untag(%User{} = user, tags), do: update_tags(user, user.tags -- normalize_tags(tags)) - {:ok, updated_user} = - user - |> change(%{tags: new_tags}) - |> Repo.update() + defp update_tags(%User{} = user, new_tags) do + {:ok, updated_user} = + user + |> change(%{tags: new_tags}) + |> Repo.update() - updated_user - end - end) + updated_user end - defp mutate_tags(user, tags, :tag), do: Enum.uniq(user.tags ++ tags) + defp normalize_tags(tags) do + [tags] + |> List.flatten() + |> Enum.map(&String.downcase(&1)) + end - defp mutate_tags(user, tags, :untag), do: user.tags -- tags + defp local_nickname_regex() do + if Pleroma.Config.get([:instance, :extended_nickname_format]) do + @extended_local_nickname_regex + else + @strict_local_nickname_regex + end + end end