Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand DNP validation to all image tags, regardless of prefix #390

Merged
merged 1 commit into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 28 additions & 43 deletions lib/philomena/images/dnp_validator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,62 @@ defmodule Philomena.Images.DnpValidator do
import Ecto.Query
alias Philomena.Repo
alias Philomena.Tags.Tag
alias Philomena.ArtistLinks.ArtistLink
alias Philomena.DnpEntries.DnpEntry

def validate_dnp(changeset, uploader) do
tags =
changeset
|> get_field(:tags)
|> extract_tags()
|> Enum.map(& &1.name)

edit_present? = MapSet.member?(tags, "edit")
edit_present? = "edit" in tags

tags_with_dnp =
Tag
|> where([t], t.name in ^extract_artists(tags))
|> preload(dnp_entries: :requesting_user)
|> from(as: :tag)
|> where([t], t.name in ^tags)
|> where(exists(where(DnpEntry, [d], d.tag_id == parent_as(:tag).id)))
|> preload(dnp_entries: [tag: :verified_links])
|> Repo.all()
|> Enum.filter(&(length(&1.dnp_entries) > 0))

changeset
|> validate_artist_only(tags_with_dnp, uploader)
|> validate_no_edits(tags_with_dnp, uploader, edit_present?)
end

defp validate_artist_only(changeset, tags_with_dnp, uploader) do
Enum.reduce(tags_with_dnp, changeset, fn tag, changeset ->
case Enum.any?(
tag.dnp_entries,
&(&1.dnp_type == "Artist Upload Only" and not valid_user?(&1, uploader))
) do
true ->
add_error(changeset, :image, "DNP (Artist upload only)")

false ->
changeset
end
end)
validate_tags_with_dnp(changeset, tags_with_dnp, uploader, "Artist Upload Only")
end

defp validate_no_edits(changeset, _tags_with_dnp, _uploader, false), do: changeset
defp validate_no_edits(changeset, tags_with_dnp, uploader, edit_present?) do
if edit_present? do
validate_tags_with_dnp(changeset, tags_with_dnp, uploader, "No Edits")
else
changeset
end
end

defp validate_no_edits(changeset, tags_with_dnp, uploader, true) do
defp validate_tags_with_dnp(changeset, tags_with_dnp, uploader, dnp_type) do
Enum.reduce(tags_with_dnp, changeset, fn tag, changeset ->
case Enum.any?(
tag.dnp_entries,
&(&1.dnp_type == "No Edits" and not valid_user?(&1, uploader))
) do
tag.dnp_entries
|> Enum.any?(&(&1.dnp_type == dnp_type and not uploader_permitted?(&1, uploader)))
|> case do
true ->
add_error(changeset, :image, "DNP (No edits)")
add_error(changeset, :image, "DNP (#{dnp_type})")

false ->
_ ->
changeset
end
end)
end

defp valid_user?(_dnp_entry, nil), do: false

defp valid_user?(dnp_entry, user) do
ArtistLink
|> where(tag_id: ^dnp_entry.tag_id)
|> where(aasm_state: "verified")
|> where(user_id: ^user.id)
|> Repo.exists?()
end

defp extract_tags(tags) do
tags
|> Enum.map(& &1.name)
|> MapSet.new()
end
defp uploader_permitted?(dnp_entry, uploader) do
case uploader do
%{id: uploader_id} ->
Enum.any?(dnp_entry.tag.verified_links, &(&1.user_id == uploader_id))

defp extract_artists(tags) do
Enum.filter(tags, &String.starts_with?(&1, "artist:"))
_ ->
false
end
end
end
1 change: 1 addition & 0 deletions lib/philomena/tags/tag.ex
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ defmodule Philomena.Tags.Tag do
join_through: "tags_implied_tags",
join_keys: [implied_tag_id: :id, tag_id: :id]

has_many :verified_links, ArtistLink, where: [aasm_state: "verified"]
has_many :public_links, ArtistLink, where: [public: true, aasm_state: "verified"]
has_many :hidden_links, ArtistLink, where: [public: false, aasm_state: "verified"]
has_many :dnp_entries, DnpEntry, where: [aasm_state: "listed"]
Expand Down
Loading