aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/activity.ex6
-rw-r--r--lib/pleroma/formatter.ex6
-rw-r--r--lib/pleroma/upload.ex4
-rw-r--r--lib/pleroma/user.ex13
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex2
-rw-r--r--lib/pleroma/web/ostatus/handlers/delete_handler.ex1
-rw-r--r--lib/pleroma/web/ostatus/handlers/note_handler.ex5
-rw-r--r--lib/pleroma/web/router.ex34
-rw-r--r--lib/pleroma/web/salmon/salmon.ex2
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex53
-rw-r--r--lib/pleroma/web/twitter_api/representers/activity_representer.ex19
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api.ex6
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api_controller.ex43
-rw-r--r--lib/pleroma/web/twitter_api/utils.ex11
-rw-r--r--lib/pleroma/web/twitter_api/views/user_view.ex7
-rw-r--r--lib/pleroma/web/web_finger/web_finger.ex30
16 files changed, 206 insertions, 36 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 0b7188aba..f226c4c5f 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -15,11 +15,17 @@ defmodule Pleroma.Activity do
where: fragment("(?)->>'id' = ?", activity.data, ^to_string(ap_id)))
end
+ # Wrong name, only returns create activities
def all_by_object_ap_id_q(ap_id) do
from activity in Activity,
where: fragment("(?)->'object'->>'id' = ?", activity.data, ^to_string(ap_id))
end
+ def all_non_create_by_object_ap_id_q(ap_id) do
+ from activity in Activity,
+ where: fragment("(?)->>'object' = ?", activity.data, ^to_string(ap_id))
+ end
+
def all_by_object_ap_id(ap_id) do
Repo.all(all_by_object_ap_id_q(ap_id))
end
diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index 179c33560..e95a314b4 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -1,7 +1,7 @@
defmodule Pleroma.Formatter do
alias Pleroma.User
- @link_regex ~r/https?:\/\/[\w\.\/?=\-#%&]+[\w]/
+ @link_regex ~r/https?:\/\/[\w\.\/?=\-#%&]+[\w]/u
def linkify(text) do
Regex.replace(@link_regex, text, "<a href='\\0'>\\0</a>")
end
@@ -14,7 +14,7 @@ defmodule Pleroma.Formatter do
def parse_mentions(text) do
# Modified from https://www.w3.org/TR/html5/forms.html#valid-e-mail-address
- regex = ~r/@[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/
+ regex = ~r/@[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/u
Regex.scan(regex, text)
|> List.flatten
@@ -91,7 +91,7 @@ defmodule Pleroma.Formatter do
]
Enum.reduce(emoji_list, text, fn (emoji, text) ->
- String.replace(text, ":#{String.replace(emoji, "_", "")}:", "<img height='32px' width='32px' alt='#{emoji}' title='#{emoji}' src='#{Pleroma.Web.Endpoint.static_url}/finmoji/128px/#{emoji}-128.png' />")
+ String.replace(text, ":#{String.replace(emoji, "_", "")}:", "<img height='32px' width='32px' alt='#{emoji}' title='#{String.replace(emoji, "_", "")}' src='#{Pleroma.Web.Endpoint.static_url}/finmoji/128px/#{emoji}-128.png' />")
end)
end
end
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
index 9275eff87..2717377a3 100644
--- a/lib/pleroma/upload.ex
+++ b/lib/pleroma/upload.ex
@@ -13,7 +13,7 @@ defmodule Pleroma.Upload do
"url" => [%{
"type" => "Link",
"mediaType" => file.content_type,
- "href" => url_for(Path.join(uuid, file.filename))
+ "href" => url_for(Path.join(uuid, :cow_uri.urlencode(file.filename)))
}],
"name" => file.filename,
"uuid" => uuid
@@ -38,7 +38,7 @@ defmodule Pleroma.Upload do
"url" => [%{
"type" => "Link",
"mediaType" => content_type,
- "href" => url_for(Path.join(uuid, filename))
+ "href" => url_for(Path.join(uuid, :cow_uri.urlencode(filename)))
}],
"name" => filename,
"uuid" => uuid
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index f28f0deb0..4f5fcab5b 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -80,6 +80,15 @@ defmodule Pleroma.User do
end
end
+ def update_changeset(struct, params \\ %{}) do
+ changeset = struct
+ |> cast(params, [:bio, :name])
+ |> unique_constraint(:nickname)
+ |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
+ |> validate_length(:bio, min: 1, max: 1000)
+ |> validate_length(:name, min: 1, max: 100)
+ end
+
def register_changeset(struct, params \\ %{}) do
changeset = struct
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
@@ -89,8 +98,8 @@ defmodule Pleroma.User do
|> unique_constraint(:nickname)
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|> validate_format(:email, @email_regex)
- |> validate_length(:bio, max: 1000)
- |> validate_length(:name, max: 100)
+ |> validate_length(:bio, min: 1, max: 1000)
+ |> validate_length(:name, min: 1, max: 100)
if changeset.valid? do
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 69a2d8f4e..fbe259f50 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -119,7 +119,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def fetch_activities(recipients, opts \\ %{}) do
base_query = from activity in Activity,
limit: 20,
- order_by: [desc: :inserted_at]
+ order_by: [desc: :id]
base_query
|> restrict_recipients(recipients)
diff --git a/lib/pleroma/web/ostatus/handlers/delete_handler.ex b/lib/pleroma/web/ostatus/handlers/delete_handler.ex
index 2e5f9469b..f54a037a0 100644
--- a/lib/pleroma/web/ostatus/handlers/delete_handler.ex
+++ b/lib/pleroma/web/ostatus/handlers/delete_handler.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.OStatus.DeleteHandler do
with id <- XML.string_from_xpath("//id", entry),
object when not is_nil(object) <- Object.get_by_ap_id(id) do
Repo.delete(object)
+ Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id))
Repo.delete_all(Activity.all_by_object_ap_id_q(id))
nil
end
diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex
index e67f67b37..f9aa463a0 100644
--- a/lib/pleroma/web/ostatus/handlers/note_handler.ex
+++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex
@@ -55,8 +55,9 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
end
def get_mentions(entry) do
- get_people_mentions(entry)
- ++ get_collection_mentions(entry)
+ (get_people_mentions(entry)
+ ++ get_collection_mentions(entry))
+ |> Enum.filter(&(&1))
end
def make_to_list(actor, mentions) do
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 34207a62f..2b22140ee 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -23,11 +23,31 @@ defmodule Pleroma.Web.Router do
plug :accepts, ["xml", "xrd+xml"]
end
+ pipeline :config do
+ plug :accepts, ["json", "xml"]
+ end
+
+ pipeline :masto_config do
+ plug :accepts, ["json"]
+ end
+
+ scope "/api/v1", Pleroma.Web do
+ pipe_through :masto_config
+ # TODO: Move this
+ get "/instance", TwitterAPI.UtilController, :masto_instance
+ end
+
scope "/api", Pleroma.Web do
- pipe_through :api
+ pipe_through :config
get "/help/test", TwitterAPI.UtilController, :help_test
+ post "/help/test", TwitterAPI.UtilController, :help_test
get "/statusnet/config", TwitterAPI.UtilController, :config
+ get "/statusnet/version", TwitterAPI.UtilController, :version
+ end
+
+ scope "/api", Pleroma.Web do
+ pipe_through :api
get "/statuses/public_timeline", TwitterAPI.Controller, :public_timeline
get "/statuses/public_and_external_timeline", TwitterAPI.Controller, :public_and_external_timeline
@@ -49,6 +69,10 @@ defmodule Pleroma.Web.Router do
get "/account/verify_credentials", TwitterAPI.Controller, :verify_credentials
post "/account/verify_credentials", TwitterAPI.Controller, :verify_credentials
+ post "/account/update_profile", TwitterAPI.Controller, :update_profile
+ post "/account/update_profile_banner", TwitterAPI.Controller, :update_banner
+ post "/qvitter/update_background_image", TwitterAPI.Controller, :update_background
+
post "/account/most_recent_notification", TwitterAPI.Controller, :update_most_recent_notification
get "/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline
@@ -107,5 +131,11 @@ end
defmodule Fallback.RedirectController do
use Pleroma.Web, :controller
- def redirector(conn, _params), do: (if Mix.env != :test, do: send_file(conn, 200, "priv/static/index.html"))
+ def redirector(conn, _params) do
+ if Mix.env != :test do
+ conn
+ |> put_resp_content_type("text/html")
+ |> send_file(200, "priv/static/index.html")
+ end
+ end
end
diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex
index eadf0773b..4f6dfed65 100644
--- a/lib/pleroma/web/salmon/salmon.ex
+++ b/lib/pleroma/web/salmon/salmon.ex
@@ -60,7 +60,7 @@ defmodule Pleroma.Web.Salmon do
[modulus, exponent] = magickey
|> String.split(".")
- |> Enum.map(&Base.url_decode64!/1)
+ |> Enum.map(fn (n) -> Base.url_decode64!(n, padding: false) end)
|> Enum.map(make_integer)
{:RSAPublicKey, modulus, exponent}
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
index 6d6fd2202..285b4d105 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -7,12 +7,51 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
def config(conn, _params) do
- json(conn, %{
- site: %{
- name: Web.base_url,
- server: Web.base_url,
- textlimit: -1
- }
- })
+ case get_format(conn) do
+ "xml" ->
+ response = """
+ <config>
+ <site>
+ <name>#{Web.base_url}</name>
+ <site>#{Web.base_url}</site>
+ <textlimit>5000</textlimit>
+ </site>
+ </config>
+ """
+ conn
+ |> put_resp_content_type("application/xml")
+ |> send_resp(200, response)
+ _ ->
+ json(conn, %{
+ site: %{
+ name: Web.base_url,
+ server: Web.base_url,
+ textlimit: 5000
+ }
+ })
+ end
+ end
+
+ def version(conn, _params) do
+ case get_format(conn) do
+ "xml" ->
+ response = "<version>Pleroma Dev</version>"
+ conn
+ |> put_resp_content_type("application/xml")
+ |> send_resp(200, response)
+ _ -> json(conn, "Pleroma Dev")
+ end
+ end
+
+ # TODO: Move this
+ def masto_instance(conn, _params) do
+ response = %{
+ uri: Web.base_url,
+ title: Web.base_url,
+ description: "A Pleroma instance, an alternative fediverse server",
+ version: "dev"
+ }
+
+ json(conn, response)
end
end
diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
index 10aab919a..bc3de0e90 100644
--- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex
+++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
@@ -29,7 +29,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"created_at" => created_at,
"retweeted_status" => retweeted_status,
"statusnet_conversation_id" => conversation_id(announced_activity),
- "external_url" => activity.data["id"]
+ "external_url" => activity.data["id"],
+ "activity_type" => "repeat"
}
end
@@ -49,7 +50,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"uri" => "tag:#{activity.data["id"]}:objectType=Favourite",
"created_at" => created_at,
"in_reply_to_status_id" => liked_activity.id,
- "external_url" => activity.data["id"]
+ "external_url" => activity.data["id"],
+ "activity_type" => "like"
}
end
@@ -68,7 +70,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"is_post_verb" => false,
"created_at" => created_at,
"in_reply_to_status_id" => nil,
- "external_url" => activity.data["id"]
+ "external_url" => activity.data["id"],
+ "activity_type" => "follow"
}
end
@@ -88,7 +91,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"is_post_verb" => false,
"created_at" => created_at,
"in_reply_to_status_id" => nil,
- "external_url" => activity.data["id"]
+ "external_url" => activity.data["id"],
+ "activity_type" => "undo"
}
end
@@ -108,6 +112,9 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
conversation_id = conversation_id(activity)
+ tags = activity.data["object"]["tag"] || []
+ possibly_sensitive = Enum.member?(tags, "nsfw")
+
%{
"id" => activity.id,
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
@@ -125,7 +132,9 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"favorited" => to_boolean(favorited),
"repeated" => to_boolean(repeated),
"external_url" => object["external_url"],
- "tags" => activity.data["object"]["tag"] || []
+ "tags" => tags,
+ "activity_type" => "post",
+ "possibly_sensitive" => possibly_sensitive
}
end
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index dc66e27ad..de39834ca 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -270,7 +270,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
user = User.get_cached_by_ap_id(actor)
# mentioned_users = Repo.all(from user in User, where: user.ap_id in ^activity.data["to"])
mentioned_users = Enum.map(activity.data["to"] || [], fn (ap_id) ->
- User.get_cached_by_ap_id(ap_id)
+ if ap_id do
+ User.get_cached_by_ap_id(ap_id)
+ else
+ nil
+ end
end)
|> Enum.filter(&(&1))
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index 9b1c74a3f..3580e48d2 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -6,6 +6,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Ecto.Changeset
+ require Logger
+
def verify_credentials(%{assigns: %{user: user}} = conn, _params) do
render(conn, UserView, "show.json", %{user: user})
end
@@ -188,6 +190,30 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
render(conn, UserView, "show.json", %{user: user, for: user})
end
+ def update_banner(%{assigns: %{user: user}} = conn, params) do
+ with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}),
+ new_info <- Map.put(user.info, "banner", object.data),
+ change <- User.info_changeset(user, %{info: new_info}),
+ {:ok, user} <- Repo.update(change) do
+ %{"url" => [ %{ "href" => href } | t ]} = object.data
+ response = %{ url: href } |> Poison.encode!
+ conn
+ |> json_reply(200, response)
+ end
+ end
+
+ def update_background(%{assigns: %{user: user}} = conn, params) do
+ with {:ok, object} <- ActivityPub.upload(params),
+ new_info <- Map.put(user.info, "background", object.data),
+ change <- User.info_changeset(user, %{info: new_info}),
+ {:ok, user} <- Repo.update(change) do
+ %{"url" => [ %{ "href" => href } | t ]} = object.data
+ response = %{ url: href } |> Poison.encode!
+ conn
+ |> json_reply(200, response)
+ end
+ end
+
def external_profile(%{assigns: %{user: current_user}} = conn, %{"profileurl" => uri}) do
with {:ok, user_map} <- TwitterAPI.get_external_profile(current_user, uri),
response <- Poison.encode!(user_map) do
@@ -226,6 +252,23 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end
end
+ def update_profile(%{assigns: %{user: user}} = conn, params) do
+ params = if bio = params["description"] do
+ Map.put(params, "bio", bio)
+ else
+ params
+ end
+
+ with changeset <- User.update_changeset(user, params),
+ {:ok, user} <- Repo.update(changeset) do
+ render(conn, UserView, "user.json", %{user: user, for: user})
+ else
+ error ->
+ Logger.debug("Can't update user: #{inspect(error)}")
+ bad_request_reply(conn, "Can't update user")
+ end
+ end
+
defp bad_request_reply(conn, error_message) do
json = error_json(conn, error_message)
json_reply(conn, 400, json)
diff --git a/lib/pleroma/web/twitter_api/utils.ex b/lib/pleroma/web/twitter_api/utils.ex
index 2c3507dfb..055588031 100644
--- a/lib/pleroma/web/twitter_api/utils.ex
+++ b/lib/pleroma/web/twitter_api/utils.ex
@@ -9,10 +9,19 @@ defmodule Pleroma.Web.TwitterAPI.Utils do
end)
end
+ defp shortname(name) do
+ if String.length(name) < 30 do
+ name
+ else
+ String.slice(name, 0..30) <> "…"
+ end
+ end
+
def add_attachments(text, attachments) do
attachment_text = Enum.map(attachments, fn
(%{"url" => [%{"href" => href} | _]}) ->
- "<a href=\"#{URI.encode(href)}\" class='attachment'>#{Path.basename(href)}</a>"
+ name = URI.decode(Path.basename(href))
+ "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
_ -> ""
end)
Enum.join([text | attachment_text], "<br>\n")
diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex
index 24d2981fa..932c018a6 100644
--- a/lib/pleroma/web/twitter_api/views/user_view.ex
+++ b/lib/pleroma/web/twitter_api/views/user_view.ex
@@ -11,6 +11,9 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
render_many(users, Pleroma.Web.TwitterAPI.UserView, "user.json", for: user)
end
+ defp image_url(%{"url" => [ %{ "href" => href } | t ]}), do: href
+ defp image_url(_), do: nil
+
def render("user.json", %{user: user = %User{}} = assigns) do
image = User.avatar_url(user)
following = if assigns[:for] do
@@ -37,7 +40,9 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
"rights" => %{},
"screen_name" => user.nickname,
"statuses_count" => user_info[:note_count],
- "statusnet_profile_url" => user.ap_id
+ "statusnet_profile_url" => user.ap_id,
+ "cover_photo" => image_url(user.info["banner"]),
+ "background_image" => image_url(user.info["background"])
}
end
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index 7ae413c26..da38f662c 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -82,20 +82,34 @@ defmodule Pleroma.Web.WebFinger do
{:ok, data}
end
- def finger(account, getter \\ &@httpoison.get/3) do
+ def get_template_from_xml(body) do
+ xpath = "//Link[@rel='lrdd' and @type='application/xrd+xml']/@template"
+ with doc when doc != :error <- XML.parse_document(body),
+ template when template != nil <- XML.string_from_xpath(xpath, doc) do
+ {:ok, template}
+ end
+ end
+
+ def find_lrdd_template(domain) do
+ with {:ok, %{status_code: status_code, body: body}} <- @httpoison.get("http://#{domain}/.well-known/host-meta", [], follow_redirect: true) do
+ get_template_from_xml(body)
+ else
+ e -> {:error, "Can't find lrdd template: #{inspect(e)}"}
+ end
+ end
+
+ def finger(account) do
domain = with [_name, domain] <- String.split(account, "@") do
domain
else _e ->
URI.parse(account).host
end
- address = webfinger_address(domain)
- # try https first
- response = with {:ok, result} <- getter.("https:" <> address, ["Accept": "application/xrd+xml"], [params: [resource: account]]) do
- {:ok, result}
- else _ ->
- getter.("http:" <> address, ["Accept": "application/xrd+xml"], [params: [resource: account], follow_redirect: true])
- end
+ {:ok, template} = find_lrdd_template(domain)
+
+ address = String.replace(template, "{uri}", URI.encode(account))
+
+ response = @httpoison.get(address, ["Accept": "application/xrd+xml"])
with {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- response,
doc when doc != :error<- XML.parse_document(body),