aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/user_block.ex
blob: bcf4b64d990b135ddf455ca46307fa9f8bf073b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.UserBlock do
  use Ecto.Schema

  import Ecto.Changeset
  import Ecto.Query

  alias Pleroma.Repo
  alias Pleroma.User
  alias Pleroma.UserBlock

  schema "user_blocks" do
    belongs_to(:blocker, User, type: FlakeId.Ecto.CompatType)
    belongs_to(:blockee, User, type: FlakeId.Ecto.CompatType)

    timestamps(updated_at: false)
  end

  def changeset(%UserBlock{} = user_block, params \\ %{}) do
    user_block
    |> cast(params, [:blocker_id, :blockee_id])
    |> validate_required([:blocker_id, :blockee_id])
    |> unique_constraint(:blockee_id, name: :user_blocks_blocker_id_blockee_id_index)
    |> validate_not_self_block()
  end

  def exists?(%User{} = blocker, %User{} = blockee) do
    UserBlock
    |> where(blocker_id: ^blocker.id, blockee_id: ^blockee.id)
    |> Repo.exists?()
  end

  def create(%User{} = blocker, %User{} = blockee) do
    %UserBlock{}
    |> changeset(%{blocker_id: blocker.id, blockee_id: blockee.id})
    |> Repo.insert(
      on_conflict: :replace_all_except_primary_key,
      conflict_target: [:blocker_id, :blockee_id]
    )
  end

  def delete(%User{} = blocker, %User{} = blockee) do
    attrs = %{blocker_id: blocker.id, blockee_id: blockee.id}

    case Repo.get_by(UserBlock, attrs) do
      %UserBlock{} = existing_record -> Repo.delete(existing_record)
      nil -> {:ok, nil}
    end
  end

  defp validate_not_self_block(%Ecto.Changeset{} = changeset) do
    changeset
    |> validate_change(:blockee_id, fn _, blockee_id ->
      if blockee_id == get_field(changeset, :blocker_id) do
        [blockee_id: "can't be equal to blocker_id"]
      else
        []
      end
    end)
    |> validate_change(:blocker_id, fn _, blocker_id ->
      if blocker_id == get_field(changeset, :blockee_id) do
        [blocker_id: "can't be equal to blockee_id"]
      else
        []
      end
    end)
  end
end