defmodule GitGud.Avatars.Avatar do
@moduledoc """
An uploaded avatar for a user, organization or repository.
Polymorphic on `{owner_type, owner_id}`, the same shape `Labels`
uses — the three owners want identical fields, and one table means
the serving path and the settings form exist once rather than three
times.
The bytes are in `GitGud.Storage`; this row is the pointer plus what
a response needs without fetching them.
"""
use Ecto.Schema
import Ecto.Changeset
@owner_types ~w(user organization repository)
# What a browser will actually render, and nothing that can carry
# script. SVG is deliberately absent: it is a document format with
# script and external references in it, and serving one from the
# forge's own origin would be a stored XSS with extra steps.
@content_types ~w(image/png image/jpeg image/gif image/webp)
schema "avatars" do
field :owner_type, :string
field :owner_id, :integer
field :storage_bucket, :string
field :storage_key, :string
field :content_type, :string
field :size, :integer, default: 0
field :sha256, :string
timestamps(type: :utc_datetime)
end
@doc false
def changeset(avatar, attrs) do
avatar
|> cast(attrs, [
:owner_type,
:owner_id,
:storage_bucket,
:storage_key,
:content_type,
:size,
:sha256
])
|> validate_required([
:owner_type,
:owner_id,
:storage_bucket,
:storage_key,
:content_type,
:sha256
])
|> validate_inclusion(:owner_type, @owner_types)
|> validate_inclusion(:content_type, @content_types,
message: "must be a PNG, JPEG, GIF or WebP image"
)
|> unique_constraint([:owner_type, :owner_id])
end
@doc "Owner kinds an avatar can belong to."
def owner_types, do: @owner_types
@doc "Image types accepted on upload."
def content_types, do: @content_types
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
1.9 KiB · text
History
4b2ca85