File size: 1,660 Bytes
8da2481 | 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 | defmodule Plausible.Site.SharedLink do
@moduledoc """
Schema for shared links.
"""
use Ecto.Schema
import Ecto.Changeset
@type t() :: %__MODULE__{}
schema "shared_links" do
belongs_to :site, Plausible.Site
field :name, :string
field :slug, :string
field :password_hash, :string
field :password, :string, virtual: true
belongs_to :segment, Plausible.Segments.Segment
timestamps()
end
def changeset(link, attrs \\ %{}, opts \\ []) do
link
|> cast(attrs, [:password, :name])
|> validate_required([:slug, :name])
|> validate_special_name(opts)
|> unique_constraint(:slug)
|> unique_constraint(:name, name: :shared_links_site_id_name_index)
|> foreign_key_constraint(:segment_id)
|> hash_password()
end
defp validate_special_name(changeset, opts) do
name = get_change(changeset, :name)
if name not in Plausible.Sites.shared_link_special_names() ||
Keyword.get(opts, :skip_special_name_check?, false) do
changeset
else
changeset |> add_error(:name, "This name is reserved. Please choose another one")
end
end
defp hash_password(link) do
case link.changes[:password] do
nil ->
link
password ->
hash = Plausible.Auth.Password.hash(password)
change(link, password_hash: hash)
end
end
def password_protected?(%__MODULE__{password_hash: hash}) when not is_nil(hash), do: true
def password_protected?(%__MODULE__{}), do: false
def limited_to_segment?(%__MODULE__{segment_id: segment_id}) when is_integer(segment_id),
do: true
def limited_to_segment?(%__MODULE__{}), do: false
end
|