Merge remote-tracking branch 'origin/develop' into shigusegubu

This commit is contained in:
SGSGB 2018-08-04 18:24:38 +02:00
commit 2c15ffb421
43 changed files with 383 additions and 98 deletions

View file

@ -13,6 +13,21 @@ Instead, overload the settings by editing the following files:
* `dev.secret.exs`: custom additional configuration for `MIX_ENV=dev` * `dev.secret.exs`: custom additional configuration for `MIX_ENV=dev`
* `prod.secret.exs`: custom additional configuration for `MIX_ENV=prod` * `prod.secret.exs`: custom additional configuration for `MIX_ENV=prod`
## Uploads configuration
To configure where to upload files, and wether or not
you want to remove automatically EXIF data from pictures
being uploaded.
config :pleroma, Pleroma.Upload,
uploads: "uploads",
strip_exif: false
* `uploads`: where to put the uploaded files, relative to pleroma's main directory.
* `strip_exif`: whether or not to remove EXIF data from uploaded pics automatically.
This needs Imagemagick installed on the system ( apt install imagemagick ).
## Block functionality ## Block functionality
config :pleroma, :activitypub, config :pleroma, :activitypub,

View file

@ -10,7 +10,11 @@ config :pleroma, ecto_repos: [Pleroma.Repo]
config :pleroma, Pleroma.Repo, types: Pleroma.PostgresTypes config :pleroma, Pleroma.Repo, types: Pleroma.PostgresTypes
config :pleroma, Pleroma.Upload, uploads: "uploads" config :pleroma, Pleroma.Upload,
uploads: "uploads",
strip_exif: false
config :pleroma, :emoji, shortcode_globs: ["/emoji/custom/**/*.png"]
# Configures the endpoint # Configures the endpoint
config :pleroma, Pleroma.Web.Endpoint, config :pleroma, Pleroma.Web.Endpoint,
@ -50,6 +54,7 @@ config :pleroma, :instance,
version: version, version: version,
name: "Shigusegubu", name: "Shigusegubu",
email: "pleroma@hjkos.com", email: "pleroma@hjkos.com",
description: "SigSegV, a pleroma instance",
limit: 5000, limit: 5000,
upload_limit: 20_000_000, upload_limit: 20_000_000,
registrations_open: true, registrations_open: true,
@ -58,6 +63,19 @@ config :pleroma, :instance,
public: true, public: true,
quarantined_instances: ["pleroma.rareome.ga"] quarantined_instances: ["pleroma.rareome.ga"]
config :pleroma, :fe,
theme: "pleroma-dark",
logo: "/static/logo.png",
background: "/static/aurora_borealis.jpg",
redirect_root_no_login: "/main/all",
redirect_root_login: "/main/friends",
show_instance_panel: true,
show_who_to_follow_panel: false,
who_to_follow_provider:
"https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-osa-api.cgi?{{host}}+{{user}}",
who_to_follow_link: "https://vinayaka.distsn.org/?{{host}}+{{user}}",
scope_options_enabled: false
config :pleroma, :activitypub, config :pleroma, :activitypub,
accept_blocks: true, accept_blocks: true,
unfollow_blocked: true, unfollow_blocked: true,

View file

@ -78,4 +78,8 @@ defmodule Pleroma.Activity do
end end
def get_create_activity_by_object_ap_id(_), do: nil def get_create_activity_by_object_ap_id(_), do: nil
def normalize(obj) when is_map(obj), do: Activity.get_by_ap_id(obj["id"])
def normalize(ap_id) when is_binary(ap_id), do: Activity.get_by_ap_id(ap_id)
def normalize(_), do: nil
end end

View file

@ -116,7 +116,28 @@ defmodule Pleroma.Formatter do
_ -> [] _ -> []
end) end)
@emoji @finmoji_with_filenames ++ @emoji_from_file @emoji_from_globs (
static_path = Path.join(:code.priv_dir(:pleroma), "static")
globs =
Application.get_env(:pleroma, :emoji, [])
|> Keyword.get(:shortcode_globs, [])
paths =
Enum.map(globs, fn glob ->
Path.join(static_path, glob)
|> Path.wildcard()
end)
|> Enum.concat()
Enum.map(paths, fn path ->
shortcode = Path.basename(path, Path.extname(path))
external_path = Path.join("/", Path.relative_to(path, static_path))
{shortcode, external_path}
end)
)
@emoji @finmoji_with_filenames ++ @emoji_from_globs ++ @emoji_from_file
def emojify(text, emoji \\ @emoji) def emojify(text, emoji \\ @emoji)
def emojify(text, nil), do: text def emojify(text, nil), do: text

View file

@ -27,6 +27,10 @@ defmodule Pleroma.Object do
Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id))) Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id)))
end end
def normalize(obj) when is_map(obj), do: Object.get_by_ap_id(obj["id"])
def normalize(ap_id) when is_binary(ap_id), do: Object.get_by_ap_id(ap_id)
def normalize(_), do: nil
def get_cached_by_ap_id(ap_id) do def get_cached_by_ap_id(ap_id) do
if Mix.env() == :test do if Mix.env() == :test do
get_by_ap_id(ap_id) get_by_ap_id(ap_id)

View file

@ -0,0 +1,10 @@
defmodule Pleroma.Web.Plugs.DigestPlug do
alias Plug.Conn
require Logger
def read_body(conn, opts) do
{:ok, body, conn} = Conn.read_body(conn, opts)
digest = "SHA-256=" <> (:crypto.hash(:sha256, body) |> Base.encode64())
{:ok, body, Conn.assign(conn, :digest, digest)}
end
end

View file

@ -19,6 +19,8 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
cond do cond do
signature && String.contains?(signature, user) -> signature && String.contains?(signature, user) ->
# set (request-target) header to the appropriate value
# we also replace the digest header with the one we computed
conn = conn =
conn conn
|> put_req_header( |> put_req_header(
@ -26,6 +28,14 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
String.downcase("#{conn.method}") <> " #{conn.request_path}" String.downcase("#{conn.method}") <> " #{conn.request_path}"
) )
conn =
if conn.assigns[:digest] do
conn
|> put_req_header("digest", conn.assigns[:digest])
else
conn
end
assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn)) assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn))
signature -> signature ->

View file

@ -18,8 +18,10 @@ defmodule Pleroma.Upload do
File.cp!(file.path, result_file) File.cp!(file.path, result_file)
end end
strip_exif_data(content_type, result_file)
%{ %{
"type" => "Image", "type" => "Document",
"url" => [ "url" => [
%{ %{
"type" => "Link", "type" => "Link",
@ -67,6 +69,8 @@ defmodule Pleroma.Upload do
File.rename(uuidpath, result_file) File.rename(uuidpath, result_file)
end end
strip_exif_data(content_type, result_file)
%{ %{
"type" => "Image", "type" => "Image",
"url" => [ "url" => [
@ -80,6 +84,16 @@ defmodule Pleroma.Upload do
} }
end end
def strip_exif_data(content_type, file) do
settings = Application.get_env(:pleroma, Pleroma.Upload)
do_strip = Keyword.fetch!(settings, :strip_exif)
[filetype, ext] = String.split(content_type, "/")
if filetype == "image" and do_strip == true do
Mogrify.open(file) |> Mogrify.custom("strip") |> Mogrify.save(in_place: true)
end
end
def upload_path do def upload_path do
settings = Application.get_env(:pleroma, Pleroma.Upload) settings = Application.get_env(:pleroma, Pleroma.Upload)
Keyword.fetch!(settings, :uploads) Keyword.fetch!(settings, :uploads)

View file

@ -607,7 +607,7 @@ defmodule Pleroma.User do
|> Enum.each(fn activity -> |> Enum.each(fn activity ->
case activity.data["type"] do case activity.data["type"] do
"Create" -> "Create" ->
ActivityPub.delete(Object.get_by_ap_id(activity.data["object"]["id"])) ActivityPub.delete(Object.normalize(activity.data["object"]))
# TODO: Do something with likes, follows, repeats. # TODO: Do something with likes, follows, repeats.
_ -> _ ->

View file

@ -30,7 +30,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end end
def insert(map, local \\ true) when is_map(map) do def insert(map, local \\ true) when is_map(map) do
with nil <- Activity.get_by_ap_id(map["id"]), with nil <- Activity.normalize(map),
map <- lazy_put_activity_defaults(map), map <- lazy_put_activity_defaults(map),
:ok <- check_actor_is_active(map["actor"]), :ok <- check_actor_is_active(map["actor"]),
{:ok, map} <- MRF.filter(map), {:ok, map} <- MRF.filter(map),
@ -641,13 +641,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
Logger.info("Federating #{id} to #{inbox}") Logger.info("Federating #{id} to #{inbox}")
host = URI.parse(inbox).host host = URI.parse(inbox).host
digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
signature = signature =
Pleroma.Web.HTTPSignatures.sign(actor, %{host: host, "content-length": byte_size(json)}) Pleroma.Web.HTTPSignatures.sign(actor, %{
host: host,
"content-length": byte_size(json),
digest: digest
})
@httpoison.post( @httpoison.post(
inbox, inbox,
json, json,
[{"Content-Type", "application/activity+json"}, {"signature", signature}], [
{"Content-Type", "application/activity+json"},
{"signature", signature},
{"digest", digest}
],
hackney: [pool: :default] hackney: [pool: :default]
) )
end end
@ -670,7 +680,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
recv_timeout: 20000 recv_timeout: 20000
), ),
{:ok, data} <- Jason.decode(body), {:ok, data} <- Jason.decode(body),
nil <- Object.get_by_ap_id(data["id"]), nil <- Object.normalize(data),
params <- %{ params <- %{
"type" => "Create", "type" => "Create",
"to" => data["to"], "to" => data["to"],
@ -679,7 +689,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
"object" => data "object" => data
}, },
{:ok, activity} <- Transmogrifier.handle_incoming(params) do {:ok, activity} <- Transmogrifier.handle_incoming(params) do
{:ok, Object.get_by_ap_id(activity.data["object"]["id"])} {:ok, Object.normalize(activity.data["object"])}
else else
object = %Object{} -> object = %Object{} ->
{:ok, object} {:ok, object}
@ -688,7 +698,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
Logger.info("Couldn't get object via AP, trying out OStatus fetching...") Logger.info("Couldn't get object via AP, trying out OStatus fetching...")
case OStatus.fetch_activity_from_url(id) do case OStatus.fetch_activity_from_url(id) do
{:ok, [activity | _]} -> {:ok, Object.get_by_ap_id(activity.data["object"]["id"])} {:ok, [activity | _]} -> {:ok, Object.normalize(activity.data["object"])}
e -> e e -> e
end end
end end

View file

@ -13,12 +13,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
require Logger require Logger
def get_actor(%{"actor" => actor}) when is_binary(actor) do
actor
end
def get_actor(%{"actor" => actor}) when is_list(actor) do
Enum.at(actor, 0)
end
def get_actor(%{"actor" => actor_list}) do
Enum.find(actor_list, fn %{"type" => type} -> type == "Person" end)
|> Map.get("id")
end
@doc """ @doc """
Modifies an incoming AP object (mastodon format) to our internal format. Modifies an incoming AP object (mastodon format) to our internal format.
""" """
def fix_object(object) do def fix_object(object) do
object object
|> Map.put("actor", object["attributedTo"]) |> fix_actor
|> fix_attachments |> fix_attachments
|> fix_context |> fix_context
|> fix_in_reply_to |> fix_in_reply_to
@ -27,6 +40,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> fix_content_map |> fix_content_map
end end
def fix_actor(%{"attributedTo" => actor} = object) do
object
|> Map.put("actor", get_actor(%{"actor" => actor}))
end
def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object) def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object)
when not is_nil(in_reply_to_id) do when not is_nil(in_reply_to_id) do
case ActivityPub.fetch_object_from_id(in_reply_to_id) do case ActivityPub.fetch_object_from_id(in_reply_to_id) do
@ -122,7 +140,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# TODO: validate those with a Ecto scheme # TODO: validate those with a Ecto scheme
# - tags # - tags
# - emoji # - emoji
def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data)
when objtype in ["Article", "Note"] do
actor = get_actor(data)
data = Map.put(data, "actor", actor)
with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]),
%User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do
object = fix_object(data["object"]) object = fix_object(data["object"])
@ -412,7 +434,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def handle_incoming(_), do: :error def handle_incoming(_), do: :error
def get_obj_helper(id) do def get_obj_helper(id) do
if object = Object.get_by_ap_id(id), do: {:ok, object}, else: nil if object = Object.normalize(id), do: {:ok, object}, else: nil
end end
def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do
@ -460,14 +482,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# Mastodon Accept/Reject requires a non-normalized object containing the actor URIs, # Mastodon Accept/Reject requires a non-normalized object containing the actor URIs,
# because of course it does. # because of course it does.
def prepare_outgoing(%{"type" => "Accept"} = data) do def prepare_outgoing(%{"type" => "Accept"} = data) do
follow_activity_id = with follow_activity <- Activity.normalize(data["object"]) do
if is_binary(data["object"]) do
data["object"]
else
data["object"]["id"]
end
with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do
object = %{ object = %{
"actor" => follow_activity.actor, "actor" => follow_activity.actor,
"object" => follow_activity.data["object"], "object" => follow_activity.data["object"],
@ -485,14 +500,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
def prepare_outgoing(%{"type" => "Reject"} = data) do def prepare_outgoing(%{"type" => "Reject"} = data) do
follow_activity_id = with follow_activity <- Activity.normalize(data["object"]) do
if is_binary(data["object"]) do
data["object"]
else
data["object"]["id"]
end
with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do
object = %{ object = %{
"actor" => follow_activity.actor, "actor" => follow_activity.actor,
"object" => follow_activity.data["object"], "object" => follow_activity.data["object"],

View file

@ -128,7 +128,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
Inserts a full object if it is contained in an activity. Inserts a full object if it is contained in an activity.
""" """
def insert_full_object(%{"object" => %{"type" => type} = object_data}) def insert_full_object(%{"object" => %{"type" => type} = object_data})
when is_map(object_data) and type in ["Note"] do when is_map(object_data) and type in ["Article", "Note"] do
with {:ok, _} <- Object.create(object_data) do with {:ok, _} <- Object.create(object_data) do
:ok :ok
end end

View file

@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
def render("user.json", %{user: user}) do def render("user.json", %{user: user}) do
{:ok, user} = WebFinger.ensure_keys_present(user) {:ok, user} = WebFinger.ensure_keys_present(user)
{:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"]) {:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key]) public_key = :public_key.pem_encode([public_key])
%{ %{

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Web.CommonAPI do
def delete(activity_id, user) do def delete(activity_id, user) do
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id), with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
%Object{} = object <- Object.get_by_ap_id(object_id), %Object{} = object <- Object.normalize(object_id),
true <- user.info["is_moderator"] || user.ap_id == object.data["actor"], true <- user.info["is_moderator"] || user.ap_id == object.data["actor"],
{:ok, delete} <- ActivityPub.delete(object) do {:ok, delete} <- ActivityPub.delete(object) do
{:ok, delete} {:ok, delete}
@ -16,7 +16,7 @@ defmodule Pleroma.Web.CommonAPI do
def repeat(id_or_ap_id, user) do def repeat(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
object <- Object.get_by_ap_id(activity.data["object"]["id"]) do object <- Object.normalize(activity.data["object"]["id"]) do
ActivityPub.announce(user, object) ActivityPub.announce(user, object)
else else
_ -> _ ->
@ -26,7 +26,7 @@ defmodule Pleroma.Web.CommonAPI do
def unrepeat(id_or_ap_id, user) do def unrepeat(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
object <- Object.get_by_ap_id(activity.data["object"]["id"]) do object <- Object.normalize(activity.data["object"]["id"]) do
ActivityPub.unannounce(user, object) ActivityPub.unannounce(user, object)
else else
_ -> _ ->
@ -37,7 +37,7 @@ defmodule Pleroma.Web.CommonAPI do
def favorite(id_or_ap_id, user) do def favorite(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
false <- activity.data["actor"] == user.ap_id, false <- activity.data["actor"] == user.ap_id,
object <- Object.get_by_ap_id(activity.data["object"]["id"]) do object <- Object.normalize(activity.data["object"]["id"]) do
ActivityPub.like(user, object) ActivityPub.like(user, object)
else else
_ -> _ ->
@ -48,7 +48,7 @@ defmodule Pleroma.Web.CommonAPI do
def unfavorite(id_or_ap_id, user) do def unfavorite(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
false <- activity.data["actor"] == user.ap_id, false <- activity.data["actor"] == user.ap_id,
object <- Object.get_by_ap_id(activity.data["object"]["id"]) do object <- Object.normalize(activity.data["object"]["id"]) do
ActivityPub.unlike(user, object) ActivityPub.unlike(user, object)
else else
_ -> _ ->

View file

@ -35,7 +35,8 @@ defmodule Pleroma.Web.Endpoint do
parsers: [:urlencoded, :multipart, :json], parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"], pass: ["*/*"],
json_decoder: Jason, json_decoder: Jason,
length: Application.get_env(:pleroma, :instance) |> Keyword.get(:upload_limit) length: Application.get_env(:pleroma, :instance) |> Keyword.get(:upload_limit),
body_reader: {Pleroma.Web.Plugs.DigestPlug, :read_body, []}
) )
plug(Plug.MethodOverride) plug(Plug.MethodOverride)

View file

@ -95,7 +95,7 @@ defmodule Pleroma.Web.Federator do
params = Utils.normalize_params(params) params = Utils.normalize_params(params)
with {:ok, _user} <- ap_enabled_actor(params["actor"]), with {:ok, _user} <- ap_enabled_actor(params["actor"]),
nil <- Activity.get_by_ap_id(params["id"]), nil <- Activity.normalize(params["id"]),
{:ok, _activity} <- Transmogrifier.handle_incoming(params) do {:ok, _activity} <- Transmogrifier.handle_incoming(params) do
else else
%Activity{} -> %Activity{} ->

View file

@ -1,6 +1,6 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.{Repo, Activity, User, Notification, Stats} alias Pleroma.{Repo, Object, Activity, User, Notification, Stats}
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView} alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView}
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
@ -125,7 +125,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
response = %{ response = %{
uri: Web.base_url(), uri: Web.base_url(),
title: Keyword.get(@instance, :name), title: Keyword.get(@instance, :name),
description: "A Pleroma instance, an alternative fediverse server", description: Keyword.get(@instance, :description),
version: "#{@mastodon_api_level} (compatible; #{Keyword.get(@instance, :version)})", version: "#{@mastodon_api_level} (compatible; #{Keyword.get(@instance, :version)})",
email: Keyword.get(@instance, :email), email: Keyword.get(@instance, :email),
urls: %{ urls: %{
@ -428,16 +428,43 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
render(conn, AccountView, "relationships.json", %{user: user, targets: targets}) render(conn, AccountView, "relationships.json", %{user: user, targets: targets})
end end
def upload(%{assigns: %{user: _}} = conn, %{"file" => file}) do def update_media(%{assigns: %{user: _}} = conn, data) do
with {:ok, object} <- ActivityPub.upload(file) do with %Object{} = object <- Repo.get(Object, data["id"]),
true <- is_binary(data["description"]),
description <- data["description"] do
new_data = %{object.data | "name" => description}
change = Object.change(object, %{data: new_data})
{:ok, media_obj} = Repo.update(change)
data = data =
object.data new_data
|> Map.put("id", object.id) |> Map.put("id", object.id)
render(conn, StatusView, "attachment.json", %{attachment: data}) render(conn, StatusView, "attachment.json", %{attachment: data})
end end
end end
def upload(%{assigns: %{user: _}} = conn, %{"file" => file} = data) do
with {:ok, object} <- ActivityPub.upload(file) do
objdata =
if Map.has_key?(data, "description") do
Map.put(object.data, "name", data["description"])
else
object.data
end
change = Object.change(object, %{data: objdata})
{:ok, object} = Repo.update(change)
objdata =
objdata
|> Map.put("id", object.id)
render(conn, StatusView, "attachment.json", %{attachment: objdata})
end
end
def favourited_by(conn, %{"id" => id}) do def favourited_by(conn, %{"id" => id}) do
with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do
q = from(u in User, where: u.ap_id in ^likes) q = from(u in User, where: u.ap_id in ^likes)
@ -873,7 +900,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
}, },
compose: %{ compose: %{
me: "#{user.id}", me: "#{user.id}",
default_privacy: "public", default_privacy: user.info["default_scope"] || "public",
default_sensitive: false default_sensitive: false
}, },
media_attachments: %{ media_attachments: %{

View file

@ -54,8 +54,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
%{ %{
id: to_string(activity.id), id: to_string(activity.id),
uri: object, uri: object,
# TODO: This might be wrong, check with mastodon. url: object,
url: nil,
account: AccountView.render("account.json", %{user: user}), account: AccountView.render("account.json", %{user: user}),
in_reply_to_id: nil, in_reply_to_id: nil,
in_reply_to_account_id: nil, in_reply_to_account_id: nil,
@ -128,7 +127,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
in_reply_to_id: reply_to && to_string(reply_to.id), in_reply_to_id: reply_to && to_string(reply_to.id),
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id), in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id),
reblog: nil, reblog: nil,
content: HtmlSanitizeEx.basic_html(object["content"]), content: render_content(object),
created_at: created_at, created_at: created_at,
reblogs_count: announcement_count, reblogs_count: announcement_count,
favourites_count: like_count, favourites_count: like_count,
@ -170,7 +169,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
remote_url: href, remote_url: href,
preview_url: MediaProxy.url(href), preview_url: MediaProxy.url(href),
text_url: href, text_url: href,
type: type type: type,
description: attachment["name"]
} }
end end
@ -207,4 +207,21 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
"direct" "direct"
end end
end end
def render_content(%{"type" => "Article"} = object) do
summary = object["name"]
content =
if !!summary and summary != "" do
"<p><a href=\"#{object["url"]}\">#{summary}</a></p>#{object["content"]}"
else
object["content"]
end
HtmlSanitizeEx.basic_html(content)
end
def render_content(object) do
HtmlSanitizeEx.basic_html(object["content"])
end
end end

View file

@ -4,8 +4,6 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
alias Pleroma.Stats alias Pleroma.Stats
alias Pleroma.Web alias Pleroma.Web
@instance Application.get_env(:pleroma, :instance)
def schemas(conn, _params) do def schemas(conn, _params) do
response = %{ response = %{
links: [ links: [
@ -21,20 +19,22 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
# Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json # Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json
def nodeinfo(conn, %{"version" => "2.0"}) do def nodeinfo(conn, %{"version" => "2.0"}) do
instance = Application.get_env(:pleroma, :instance)
media_proxy = Application.get_env(:pleroma, :media_proxy)
stats = Stats.get_stats() stats = Stats.get_stats()
response = %{ response = %{
version: "2.0", version: "2.0",
software: %{ software: %{
name: "pleroma", name: "pleroma",
version: Keyword.get(@instance, :version) version: Keyword.get(instance, :version)
}, },
protocols: ["ostatus", "activitypub"], protocols: ["ostatus", "activitypub"],
services: %{ services: %{
inbound: [], inbound: [],
outbound: [] outbound: []
}, },
openRegistrations: Keyword.get(@instance, :registrations_open), openRegistrations: Keyword.get(instance, :registrations_open),
usage: %{ usage: %{
users: %{ users: %{
total: stats.user_count || 0 total: stats.user_count || 0
@ -42,7 +42,10 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
localPosts: stats.status_count || 0 localPosts: stats.status_count || 0
}, },
metadata: %{ metadata: %{
nodeName: Keyword.get(@instance, :name) nodeName: Keyword.get(instance, :name),
nodeDescription: Keyword.get(instance, :description),
mediaProxy: Keyword.get(media_proxy, :enabled),
private: !Keyword.get(instance, :public, true)
} }
} }

View file

@ -246,7 +246,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: [] author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
mentions = (activity.recipients || []) |> get_mentions mentions = (activity.recipients || []) |> get_mentions
follow_activity = Activity.get_by_ap_id(follow_activity["id"]) follow_activity = Activity.normalize(follow_activity)
[ [
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']}, {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Web.OStatus.DeleteHandler do
def handle_delete(entry, _doc \\ nil) do def handle_delete(entry, _doc \\ nil) do
with id <- XML.string_from_xpath("//id", entry), with id <- XML.string_from_xpath("//id", entry),
object when not is_nil(object) <- Object.get_by_ap_id(id), %Object{} = object <- Object.normalize(id),
{:ok, delete} <- ActivityPub.delete(object, false) do {:ok, delete} <- ActivityPub.delete(object, false) do
delete delete
end end

View file

@ -89,7 +89,7 @@ defmodule Pleroma.Web.OStatus do
def make_share(entry, doc, retweeted_activity) do def make_share(entry, doc, retweeted_activity) do
with {:ok, actor} <- find_make_or_update_user(doc), with {:ok, actor} <- find_make_or_update_user(doc),
%Object{} = object <- Object.get_by_ap_id(retweeted_activity.data["object"]["id"]), %Object{} = object <- Object.normalize(retweeted_activity.data["object"]),
id when not is_nil(id) <- string_from_xpath("/entry/id", entry), id when not is_nil(id) <- string_from_xpath("/entry/id", entry),
{:ok, activity, _object} = ActivityPub.announce(actor, object, id, false) do {:ok, activity, _object} = ActivityPub.announce(actor, object, id, false) do
{:ok, activity} {:ok, activity}
@ -107,7 +107,7 @@ defmodule Pleroma.Web.OStatus do
def make_favorite(entry, doc, favorited_activity) do def make_favorite(entry, doc, favorited_activity) do
with {:ok, actor} <- find_make_or_update_user(doc), with {:ok, actor} <- find_make_or_update_user(doc),
%Object{} = object <- Object.get_by_ap_id(favorited_activity.data["object"]["id"]), %Object{} = object <- Object.normalize(favorited_activity.data["object"]),
id when not is_nil(id) <- string_from_xpath("/entry/id", entry), id when not is_nil(id) <- string_from_xpath("/entry/id", entry),
{:ok, activity, _object} = ActivityPub.like(actor, object, id, false) do {:ok, activity, _object} = ActivityPub.like(actor, object, id, false) do
{:ok, activity} {:ok, activity}

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Web.{OStatus, Federator} alias Pleroma.Web.{OStatus, Federator}
alias Pleroma.Web.XML alias Pleroma.Web.XML
alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.ActivityPubController alias Pleroma.Web.ActivityPub.ActivityPubController
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
@ -90,7 +91,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case get_format(conn) do case get_format(conn) do
"html" -> redirect(conn, to: "/notice/#{activity.id}") "html" -> redirect(conn, to: "/notice/#{activity.id}")
_ -> represent_activity(conn, activity, user) _ -> represent_activity(conn, nil, activity, user)
end end
else else
{:public?, false} -> {:public?, false} ->
@ -107,12 +108,12 @@ defmodule Pleroma.Web.OStatus.OStatusController do
def activity(conn, %{"uuid" => uuid}) do def activity(conn, %{"uuid" => uuid}) do
with id <- o_status_url(conn, :activity, uuid), with id <- o_status_url(conn, :activity, uuid),
{_, %Activity{} = activity} <- {:activity, Activity.get_by_ap_id(id)}, {_, %Activity{} = activity} <- {:activity, Activity.normalize(id)},
{_, true} <- {:public?, ActivityPub.is_public?(activity)}, {_, true} <- {:public?, ActivityPub.is_public?(activity)},
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case get_format(conn) do case format = get_format(conn) do
"html" -> redirect(conn, to: "/notice/#{activity.id}") "html" -> redirect(conn, to: "/notice/#{activity.id}")
_ -> represent_activity(conn, activity, user) _ -> represent_activity(conn, format, activity, user)
end end
else else
{:public?, false} -> {:public?, false} ->
@ -130,14 +131,14 @@ defmodule Pleroma.Web.OStatus.OStatusController do
with {_, %Activity{} = activity} <- {:activity, Repo.get(Activity, id)}, with {_, %Activity{} = activity} <- {:activity, Repo.get(Activity, id)},
{_, true} <- {:public?, ActivityPub.is_public?(activity)}, {_, true} <- {:public?, ActivityPub.is_public?(activity)},
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case get_format(conn) do case format = get_format(conn) do
"html" -> "html" ->
conn conn
|> put_resp_content_type("text/html") |> put_resp_content_type("text/html")
|> send_file(200, "priv_sid/static/index.html") |> send_file(200, "priv_sid/static/index.html")
_ -> _ ->
represent_activity(conn, activity, user) represent_activity(conn, format, activity, user)
end end
else else
{:public?, false} -> {:public?, false} ->
@ -151,7 +152,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do
end end
end end
defp represent_activity(conn, activity, user) do defp represent_activity(conn, "activity+json", activity, user) do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(ObjectView.render("object.json", %{object: activity}))
end
defp represent_activity(conn, _, activity, user) do
response = response =
activity activity
|> ActivityRepresenter.to_simple_form(user, true) |> ActivityRepresenter.to_simple_form(user, true)

View file

@ -127,6 +127,7 @@ defmodule Pleroma.Web.Router do
get("/notifications/:id", MastodonAPIController, :get_notification) get("/notifications/:id", MastodonAPIController, :get_notification)
post("/media", MastodonAPIController, :upload) post("/media", MastodonAPIController, :upload)
put("/media/:id", MastodonAPIController, :update_media)
get("/lists", MastodonAPIController, :get_lists) get("/lists", MastodonAPIController, :get_lists)
get("/lists/:id", MastodonAPIController, :get_list) get("/lists/:id", MastodonAPIController, :get_list)

View file

@ -158,7 +158,7 @@ defmodule Pleroma.Web.Streamer do
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
blocks = user.info["blocks"] || [] blocks = user.info["blocks"] || []
parent = Object.get_by_ap_id(item.data["object"]) parent = Object.normalize(item.data["object"])
unless is_nil(parent) or item.actor in blocks or parent.data["actor"] in blocks do unless is_nil(parent) or item.actor in blocks or parent.data["actor"] in blocks do
send(socket.transport_pid, {:text, represent_update(item, user)}) send(socket.transport_pid, {:text, represent_update(item, user)})

View file

@ -126,6 +126,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end end
@instance Application.get_env(:pleroma, :instance) @instance Application.get_env(:pleroma, :instance)
@instance_fe Application.get_env(:pleroma, :fe)
@instance_chat Application.get_env(:pleroma, :chat)
def config(conn, _params) do def config(conn, _params) do
case get_format(conn) do case get_format(conn) do
"xml" -> "xml" ->
@ -148,9 +150,24 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
json(conn, %{ json(conn, %{
site: %{ site: %{
name: Keyword.get(@instance, :name), name: Keyword.get(@instance, :name),
description: Keyword.get(@instance, :description),
server: Web.base_url(), server: Web.base_url(),
textlimit: to_string(Keyword.get(@instance, :limit)), textlimit: to_string(Keyword.get(@instance, :limit)),
closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1") closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1"),
private: if(Keyword.get(@instance, :public, true), do: "0", else: "1"),
pleromafe: %{
theme: Keyword.get(@instance_fe, :theme),
background: Keyword.get(@instance_fe, :background),
logo: Keyword.get(@instance_fe, :logo),
redirectRootNoLogin: Keyword.get(@instance_fe, :redirect_root_no_login),
redirectRootLogin: Keyword.get(@instance_fe, :redirect_root_login),
chatDisabled: !Keyword.get(@instance_chat, :enabled),
showInstanceSpecificPanel: Keyword.get(@instance_fe, :show_instance_panel),
showWhoToFollowPanel: Keyword.get(@instance_fe, :show_who_to_follow_panel),
scopeOptionsEnabled: Keyword.get(@instance_fe, :scope_options_enabled),
whoToFollowProvider: Keyword.get(@instance_fe, :who_to_follow_provider),
whoToFollowLink: Keyword.get(@instance_fe, :who_to_follow_link)
}
} }
}) })
end end

View file

@ -4,7 +4,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
alias Pleroma.{Activity, User} alias Pleroma.{Activity, User}
alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView} alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView}
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Formatter alias Pleroma.Formatter
@ -164,14 +164,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
tags = if possibly_sensitive, do: Enum.uniq(["nsfw" | tags]), else: tags tags = if possibly_sensitive, do: Enum.uniq(["nsfw" | tags]), else: tags
summary = activity.data["object"]["summary"] {summary, content} = ActivityView.render_content(object)
content =
if !!summary and summary != "" do
"<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>"
else
content
end
html = html =
HtmlSanitizeEx.basic_html(content) HtmlSanitizeEx.basic_html(content)
@ -198,7 +191,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"tags" => tags, "tags" => tags,
"activity_type" => "post", "activity_type" => "post",
"possibly_sensitive" => possibly_sensitive, "possibly_sensitive" => possibly_sensitive,
"visibility" => Pleroma.Web.MastodonAPI.StatusView.get_visibility(object) "visibility" => Pleroma.Web.MastodonAPI.StatusView.get_visibility(object),
"summary" => object["summary"]
} }
end end

View file

@ -431,6 +431,19 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
user user
end end
user =
if default_scope = params["default_scope"] do
with new_info <- Map.put(user.info, "default_scope", default_scope),
change <- User.info_changeset(user, %{info: new_info}),
{:ok, user} <- User.update_and_set_cache(change) do
user
else
_e -> user
end
else
user
end
with changeset <- User.update_changeset(user, params), with changeset <- User.update_changeset(user, params),
{:ok, user} <- User.update_and_set_cache(changeset) do {:ok, user} <- User.update_and_set_cache(changeset) do
CommonAPI.update(user) CommonAPI.update(user)

View file

@ -228,15 +228,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
tags = if possibly_sensitive, do: Enum.uniq(["nsfw" | tags]), else: tags tags = if possibly_sensitive, do: Enum.uniq(["nsfw" | tags]), else: tags
summary = activity.data["object"]["summary"] {summary, content} = render_content(object)
content = object["content"]
content =
if !!summary and summary != "" do
"<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>"
else
content
end
html = html =
HtmlSanitizeEx.basic_html(content) HtmlSanitizeEx.basic_html(content)
@ -263,7 +255,41 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
"tags" => tags, "tags" => tags,
"activity_type" => "post", "activity_type" => "post",
"possibly_sensitive" => possibly_sensitive, "possibly_sensitive" => possibly_sensitive,
"visibility" => Pleroma.Web.MastodonAPI.StatusView.get_visibility(object) "visibility" => Pleroma.Web.MastodonAPI.StatusView.get_visibility(object),
"summary" => summary
} }
end end
def render_content(%{"type" => "Note"} = object) do
summary = object["summary"]
content =
if !!summary and summary != "" do
"<p>#{summary}</p>#{object["content"]}"
else
object["content"]
end
{summary, content}
end
def render_content(%{"type" => "Article"} = object) do
summary = object["name"] || object["summary"]
content =
if !!summary and summary != "" do
"<p><a href=\"#{object["url"]}\">#{summary}</a></p>#{object["content"]}"
else
object["content"]
end
{summary, content}
end
def render_content(object) do
summary = object["summary"] || "Unhandled activity type: #{object["type"]}"
content = "<p>#{summary}</p>#{object["content"]}"
{summary, content}
end
end end

View file

@ -52,7 +52,8 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
"cover_photo" => User.banner_url(user) |> MediaProxy.url(), "cover_photo" => User.banner_url(user) |> MediaProxy.url(),
"background_image" => image_url(user.info["background"]) |> MediaProxy.url(), "background_image" => image_url(user.info["background"]) |> MediaProxy.url(),
"is_local" => user.local, "is_local" => user.local,
"locked" => !!user.info["locked"] "locked" => !!user.info["locked"],
"default_scope" => user.info["default_scope"] || "public"
} }
if assigns[:token] do if assigns[:token] do

View file

@ -47,7 +47,8 @@ defmodule Pleroma.Mixfile do
{:jason, "~> 1.0"}, {:jason, "~> 1.0"},
{:ex_machina, "~> 2.0", only: :test}, {:ex_machina, "~> 2.0", only: :test},
{:credo, "~> 0.7", only: [:dev, :test]}, {:credo, "~> 0.7", only: [:dev, :test]},
{:mock, "~> 0.3.0", only: :test} {:mock, "~> 0.3.0", only: :test},
{:mogrify, "~> 0.6.1"}
] ]
end end

View file

@ -25,6 +25,7 @@
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"mochiweb": {:hex, :mochiweb, "2.15.0", "e1daac474df07651e5d17cc1e642c4069c7850dc4508d3db7263a0651330aacc", [:rebar3], [], "hexpm"}, "mochiweb": {:hex, :mochiweb, "2.15.0", "e1daac474df07651e5d17cc1e642c4069c7850dc4508d3db7263a0651330aacc", [:rebar3], [], "hexpm"},
"mock": {:hex, :mock, "0.3.1", "994f00150f79a0ea50dc9d86134cd9ebd0d177ad60bd04d1e46336cdfdb98ff9", [:mix], [{:meck, "~> 0.8.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, "mock": {:hex, :mock, "0.3.1", "994f00150f79a0ea50dc9d86134cd9ebd0d177ad60bd04d1e46336cdfdb98ff9", [:mix], [{:meck, "~> 0.8.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"mogrify": {:hex, :mogrify, "0.6.1", "de1b527514f2d95a7bbe9642eb556061afb337e220cf97adbf3a4e6438ed70af", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.3", "6706a148809a29c306062862c803406e88f048277f6e85b68faf73291e820b84", [:mix], [], "hexpm"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.3", "6706a148809a29c306062862c803406e88f048277f6e85b68faf73291e820b84", [:mix], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.3.2", "2a00d751f51670ea6bc3f2ba4e6eb27ecb8a2c71e7978d9cd3e5de5ccf7378bd", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix": {:hex, :phoenix, "1.3.2", "2a00d751f51670ea6bc3f2ba4e6eb27ecb8a2c71e7978d9cd3e5de5ccf7378bd", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","atomUri":"ostatus:atomUri","conversation":"ostatus:conversation","featured":"toot:featured","focalPoint":{"@container":"@list","@id":"toot:focalPoint"},"inReplyToAtomUri":"ostatus:inReplyToAtomUri","manuallyApprovesFollowers":"as:manuallyApprovesFollowers","movedTo":"as:movedTo","ostatus":"http://ostatus.org#","sensitive":"as:sensitive","toot":"http://joinmastodon.org/ns#"}],"endpoints":{"oauthAuthorizationEndpoint":null,"oauthTokenEndpoint":null,"provideClientKey":null,"proxyUrl":null,"sharedInbox":"https://baptiste.gelez.xyz/inbox/","signClientKey":null},"followers":null,"following":null,"id":"https://baptiste.gelez.xyz/@/BaptisteGelez","inbox":"https://baptiste.gelez.xyz/@/BaptisteGelez/inbox","liked":null,"likes":null,"name":"Baptiste Gelez","outbox":"https://baptiste.gelez.xyz/@/BaptisteGelez/outbox","preferredUsername":"BaptisteGelez","publicKey":{"id":"https://baptiste.gelez.xyz/@/BaptisteGelez#main-key","owner":"https://baptiste.gelez.xyz/@/BaptisteGelez","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA56vPlCAyxZDDy8hNiT1p\n0cdFKnUK/51LiP4nTAxGf5Eb8NmsB2ftDgiDWZfg3LiHkjNcfTDpmN0aZyRxnTg9\nZ4JiQagfynVEbMkcOQhO64OFZpB47GpLtxrb49IcUes/p4ngp/Wkp+arYZSpoSs6\n3I995mZp3ZJ78pNQf1/lV0VIdDe6SqvRj1GmBDXXcecxF0O7rN/WYNO7Jag4i/XA\nU1ToDAMeUFeijRioSNoD3CHkMIu7AN+gqAWzZ21H/ZUvmfxh3WqQi/MDNcUhhA+0\nXv7/dv4S20EGnHadtE7OrBC1IwiHEuRM41zZq0ze9cKpoXg3VK2fiSNrCHlYrA18\n2wIDAQAB\n-----END PUBLIC KEY-----\n"},"shares":null,"source":null,"streams":null,"summary":"Main Plume developer","type":"Person","uploadMedia":null,"url":"https://baptiste.gelez.xyz/@/BaptisteGelez"}

View file

@ -736,6 +736,22 @@ defmodule HTTPoisonMock do
}} }}
end end
def get("https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/", _, _) do
{:ok,
%Response{
status_code: 200,
body: File.read!("test/fixtures/httpoison_mock/baptiste.gelex.xyz-article.json")
}}
end
def get("https://baptiste.gelez.xyz/@/BaptisteGelez", _, _) do
{:ok,
%Response{
status_code: 200,
body: File.read!("test/fixtures/httpoison_mock/baptiste.gelex.xyz-user.json")
}}
end
def get(url, body, headers) do def get(url, body, headers) do
{:error, {:error,
"Not implemented the mock response for get #{inspect(url)}, #{inspect(body)}, #{ "Not implemented the mock response for get #{inspect(url)}, #{inspect(body)}, #{

View file

@ -476,6 +476,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end end
end end
test "it can fetch plume articles" do
{:ok, object} =
ActivityPub.fetch_object_from_id(
"https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/"
)
assert object
end
describe "update" do describe "update" do
test "it creates an update activity with the new user data" do test "it creates an update activity with the new user data" do
user = insert(:user) user = insert(:user)

View file

@ -13,6 +13,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
assert result["id"] == user.ap_id assert result["id"] == user.ap_id
assert result["preferredUsername"] == user.nickname assert result["preferredUsername"] == user.nickname
assert String.contains?(result["publicKey"]["publicKeyPem"], "BEGIN RSA PUBLIC KEY") assert String.contains?(result["publicKey"]["publicKeyPem"], "BEGIN PUBLIC KEY")
end end
end end

View file

@ -736,16 +736,19 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
filename: "an_image.jpg" filename: "an_image.jpg"
} }
desc = "Description of the image"
user = insert(:user) user = insert(:user)
conn = conn =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post("/api/v1/media", %{"file" => file}) |> post("/api/v1/media", %{"file" => file, "description" => desc})
assert media = json_response(conn, 200) assert media = json_response(conn, 200)
assert media["type"] == "image" assert media["type"] == "image"
assert media["description"] == desc
end end
test "hashtag timeline", %{conn: conn} do test "hashtag timeline", %{conn: conn} do

View file

@ -102,7 +102,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
url: "someurl", url: "someurl",
remote_url: "someurl", remote_url: "someurl",
preview_url: "someurl", preview_url: "someurl",
text_url: "someurl" text_url: "someurl",
description: nil
} }
assert expected == StatusView.render("attachment.json", %{attachment: object}) assert expected == StatusView.render("attachment.json", %{attachment: object})

View file

@ -155,6 +155,31 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
assert response(conn, 200) assert response(conn, 200)
end end
test "gets a notice in AS2 format", %{conn: conn} do
note_activity = insert(:note_activity)
url = "/notice/#{note_activity.id}"
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get(url)
assert json_response(conn, 200)
end
test "gets an activity in AS2 format", %{conn: conn} do
note_activity = insert(:note_activity)
[_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"]))
url = "/activities/#{uuid}"
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get(url)
assert json_response(conn, 200)
end
test "404s a private notice", %{conn: conn} do test "404s a private notice", %{conn: conn} do
note_activity = insert(:direct_note_activity) note_activity = insert(:direct_note_activity)
url = "/notice/#{note_activity.id}" url = "/notice/#{note_activity.id}"

View file

@ -126,7 +126,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
} }
expected_html = expected_html =
"<span>2hu</span><br />alert('YAY')Some <img height='32px' width='32px' alt='2hu' title='2hu' src='corndog.png' /> content mentioning <a href=\"#{ "<p>2hu</p>alert('YAY')Some <img height='32px' width='32px' alt='2hu' title='2hu' src='corndog.png' /> content mentioning <a href=\"#{
mentioned_user.ap_id mentioned_user.ap_id
}\">@shp</a>" }\">@shp</a>"
@ -155,7 +155,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
"activity_type" => "post", "activity_type" => "post",
"possibly_sensitive" => true, "possibly_sensitive" => true,
"uri" => activity.data["object"]["id"], "uri" => activity.data["object"]["id"],
"visibility" => "direct" "visibility" => "direct",
"summary" => "2hu"
} }
assert ActivityRepresenter.to_map(activity, %{ assert ActivityRepresenter.to_map(activity, %{

View file

@ -48,7 +48,8 @@ defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do
"text" => "Hey @shp!", "text" => "Hey @shp!",
"uri" => activity.data["object"]["id"], "uri" => activity.data["object"]["id"],
"user" => UserView.render("show.json", %{user: user}), "user" => UserView.render("show.json", %{user: user}),
"visibility" => "direct" "visibility" => "direct",
"summary" => nil
} }
assert result == expected assert result == expected

View file

@ -60,7 +60,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"cover_photo" => banner, "cover_photo" => banner,
"background_image" => nil, "background_image" => nil,
"is_local" => true, "is_local" => true,
"locked" => false "locked" => false,
"default_scope" => "public"
} }
assert represented == UserView.render("show.json", %{user: user}) assert represented == UserView.render("show.json", %{user: user})
@ -96,7 +97,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"cover_photo" => banner, "cover_photo" => banner,
"background_image" => nil, "background_image" => nil,
"is_local" => true, "is_local" => true,
"locked" => false "locked" => false,
"default_scope" => "public"
} }
assert represented == UserView.render("show.json", %{user: user, for: follower}) assert represented == UserView.render("show.json", %{user: user, for: follower})
@ -133,7 +135,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"cover_photo" => banner, "cover_photo" => banner,
"background_image" => nil, "background_image" => nil,
"is_local" => true, "is_local" => true,
"locked" => false "locked" => false,
"default_scope" => "public"
} }
assert represented == UserView.render("show.json", %{user: follower, for: user}) assert represented == UserView.render("show.json", %{user: follower, for: user})
@ -177,7 +180,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"cover_photo" => banner, "cover_photo" => banner,
"background_image" => nil, "background_image" => nil,
"is_local" => true, "is_local" => true,
"locked" => false "locked" => false,
"default_scope" => "public"
} }
blocker = Repo.get(User, blocker.id) blocker = Repo.get(User, blocker.id)