webhook.ex 2.23 KB
Newer Older
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Webhook do
  use Ecto.Schema

  import Ecto.Changeset
  import Ecto.Query

  alias Pleroma.EctoType.ActivityPub.ObjectValidators
  alias Pleroma.Repo

  @event_types [:"account.created", :"report.created"]

  schema "webhooks" do
    field(:url, ObjectValidators.Uri, null: false)
    field(:events, {:array, Ecto.Enum}, values: @event_types, null: false, default: [])
    field(:secret, :string, null: false, default: "")
    field(:enabled, :boolean, null: false, default: true)

    timestamps()
  end

  def get(id), do: Repo.get(__MODULE__, id)

  def get_by_type(type) do
    __MODULE__
    |> where([w], ^type in w.events)
    |> Repo.all()
  end

  def changeset(%__MODULE__{} = webhook, params) do
    webhook
    |> cast(params, [:url, :events, :enabled])
    |> validate_required([:url, :events])
    |> unique_constraint(:url)
    |> strip_events()
    |> put_secret()
  end

  def update_changeset(%__MODULE__{} = webhook, params \\ %{}) do
    webhook
    |> cast(params, [:url, :events, :enabled])
    |> unique_constraint(:url)
    |> strip_events()
  end

  def create(params) do
    {:ok, webhook} =
      %__MODULE__{}
      |> changeset(params)
      |> Repo.insert()

    webhook
  end

  def update(%__MODULE{} = webhook, params) do
    {:ok, webhook} =
      webhook
      |> update_changeset(params)
      |> Repo.update()

    webhook
  end

  def delete(webhook), do: webhook |> Repo.delete()

  def rotate_secret(%__MODULE__{} = webhook) do
    webhook
    |> cast(%{}, [])
    |> put_secret()
    |> Repo.update()
  end

  def set_enabled(%__MODULE__{} = webhook, enabled) do
    webhook
    |> cast(%{enabled: enabled}, [:enabled])
    |> Repo.update()
  end

  defp strip_events(params) do
    if Map.has_key?(params, :events) do
      params
      |> Map.put(:events, Enum.filter(params[:events], &Enum.member?(@event_types, &1)))
    else
      params
    end
  end

  defp put_secret(changeset) do
    changeset
    |> put_change(:secret, generate_secret())
  end

  defp generate_secret do
    Base.encode16(:crypto.strong_rand_bytes(20))
    |> String.downcase()
  end
end