From e278d470232f4e8081bbbe358137400074673e75 Mon Sep 17 00:00:00 2001 From: link0ff Date: Fri, 22 Feb 2019 15:03:43 +0200 Subject: OpenLDAP support --- lib/pleroma/ldap.ex | 84 +++++++++++++++++++++++++++++++ lib/pleroma/web/oauth/oauth_controller.ex | 27 +++++++++- 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 lib/pleroma/ldap.ex (limited to 'lib') diff --git a/lib/pleroma/ldap.ex b/lib/pleroma/ldap.ex new file mode 100644 index 000000000..282d8e553 --- /dev/null +++ b/lib/pleroma/ldap.ex @@ -0,0 +1,84 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.LDAP do + alias Pleroma.User + + require Logger + + @connection_timeout 10_000 + @search_timeout 10_000 + + def get_user(name, password) do + ldap = Pleroma.Config.get(:ldap, []) + host = Keyword.get(ldap, :host, "localhost") + port = Keyword.get(ldap, :port, 389) + ssl = Keyword.get(ldap, :ssl, false) + sslopts = Keyword.get(ldap, :sslopts, []) + + options = + [{:port, port}, {:ssl, ssl}, {:timeout, @connection_timeout}] ++ + if sslopts != [], do: [{:sslopts, sslopts}], else: [] + + case :eldap.open([to_charlist(host)], options) do + {:ok, connection} -> + try do + uid = Keyword.get(ldap, :uid, "cn") + base = Keyword.get(ldap, :base) + + case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do + :ok -> + case User.get_by_nickname_or_email(name) do + %User{} = user -> + user + + _ -> + register_user(connection, base, uid, name, password) + end + + error -> + error + end + after + :eldap.close(connection) + end + + {:error, error} -> + Logger.error("Could not open LDAP connection: #{inspect(error)}") + {:error, {:ldap_connection_error, error}} + end + end + + def register_user(connection, base, uid, name, password) do + case :eldap.search(connection, [ + {:base, to_charlist(base)}, + {:filter, :eldap.equalityMatch(to_charlist(uid), to_charlist(name))}, + {:scope, :eldap.wholeSubtree()}, + {:timeout, @search_timeout} + ]) do + {:ok, {:eldap_search_result, [{:eldap_entry, _, attributes}], _}} -> + with {_, [mail]} <- List.keyfind(attributes, 'mail', 0) do + params = %{ + email: :erlang.list_to_binary(mail), + name: name, + nickname: name, + password: password, + password_confirmation: password + } + + changeset = User.register_changeset(%User{}, params) + + case User.register(changeset) do + {:ok, user} -> user + error -> error + end + else + _ -> {:error, :ldap_registration_missing_attributes} + end + + error -> + error + end + end +end diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 7c1a3adbd..654beb2c4 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -130,8 +130,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do %{"grant_type" => "password", "username" => name, "password" => password} = params ) do with %App{} = app <- get_app_from_request(conn, params), - %User{} = user <- User.get_by_nickname_or_email(name), - true <- Pbkdf2.checkpw(password, user.password_hash), + %User{} = user <- get_user(name, password), {:auth_active, true} <- {:auth_active, User.auth_active?(user)}, scopes <- oauth_scopes(params, app.scopes), [] <- scopes -- app.scopes, @@ -215,4 +214,28 @@ defmodule Pleroma.Web.OAuth.OAuthController do nil end end + + defp get_user(name, password) do + if Pleroma.Config.get([:ldap, :enabled]) do + case Pleroma.LDAP.get_user(name, password) do + %User{} = user -> + user + + {:error, {:ldap_connection_error, _}} -> + # When LDAP is unavailable, try default login + with %User{} = user <- User.get_by_nickname_or_email(name), + true <- Pbkdf2.checkpw(password, user.password_hash) do + user + end + + error -> + error + end + else + with %User{} = user <- User.get_by_nickname_or_email(name), + true <- Pbkdf2.checkpw(password, user.password_hash) do + user + end + end + end end -- cgit v1.2.3 From 88a672fe88deae53d5459d651859be65555e6af2 Mon Sep 17 00:00:00 2001 From: link0ff Date: Sun, 3 Mar 2019 21:20:36 +0200 Subject: Move LDAP code to LDAPAuthenticator. Use Authenticator for token_exchange with grant_type as well --- lib/pleroma/ldap.ex | 84 ------------------ lib/pleroma/web/auth/ldap_authenticator.ex | 120 ++++++++++++++++++++++++++ lib/pleroma/web/auth/pleroma_authenticator.ex | 9 +- lib/pleroma/web/oauth/oauth_controller.ex | 31 +------ 4 files changed, 131 insertions(+), 113 deletions(-) delete mode 100644 lib/pleroma/ldap.ex create mode 100644 lib/pleroma/web/auth/ldap_authenticator.ex (limited to 'lib') diff --git a/lib/pleroma/ldap.ex b/lib/pleroma/ldap.ex deleted file mode 100644 index 282d8e553..000000000 --- a/lib/pleroma/ldap.ex +++ /dev/null @@ -1,84 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.LDAP do - alias Pleroma.User - - require Logger - - @connection_timeout 10_000 - @search_timeout 10_000 - - def get_user(name, password) do - ldap = Pleroma.Config.get(:ldap, []) - host = Keyword.get(ldap, :host, "localhost") - port = Keyword.get(ldap, :port, 389) - ssl = Keyword.get(ldap, :ssl, false) - sslopts = Keyword.get(ldap, :sslopts, []) - - options = - [{:port, port}, {:ssl, ssl}, {:timeout, @connection_timeout}] ++ - if sslopts != [], do: [{:sslopts, sslopts}], else: [] - - case :eldap.open([to_charlist(host)], options) do - {:ok, connection} -> - try do - uid = Keyword.get(ldap, :uid, "cn") - base = Keyword.get(ldap, :base) - - case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do - :ok -> - case User.get_by_nickname_or_email(name) do - %User{} = user -> - user - - _ -> - register_user(connection, base, uid, name, password) - end - - error -> - error - end - after - :eldap.close(connection) - end - - {:error, error} -> - Logger.error("Could not open LDAP connection: #{inspect(error)}") - {:error, {:ldap_connection_error, error}} - end - end - - def register_user(connection, base, uid, name, password) do - case :eldap.search(connection, [ - {:base, to_charlist(base)}, - {:filter, :eldap.equalityMatch(to_charlist(uid), to_charlist(name))}, - {:scope, :eldap.wholeSubtree()}, - {:timeout, @search_timeout} - ]) do - {:ok, {:eldap_search_result, [{:eldap_entry, _, attributes}], _}} -> - with {_, [mail]} <- List.keyfind(attributes, 'mail', 0) do - params = %{ - email: :erlang.list_to_binary(mail), - name: name, - nickname: name, - password: password, - password_confirmation: password - } - - changeset = User.register_changeset(%User{}, params) - - case User.register(changeset) do - {:ok, user} -> user - error -> error - end - else - _ -> {:error, :ldap_registration_missing_attributes} - end - - error -> - error - end - end -end diff --git a/lib/pleroma/web/auth/ldap_authenticator.ex b/lib/pleroma/web/auth/ldap_authenticator.ex new file mode 100644 index 000000000..56f2f5aed --- /dev/null +++ b/lib/pleroma/web/auth/ldap_authenticator.ex @@ -0,0 +1,120 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Auth.LDAPAuthenticator do + alias Pleroma.User + + require Logger + + @behaviour Pleroma.Web.Auth.Authenticator + + @connection_timeout 10_000 + @search_timeout 10_000 + + def get_user(%Plug.Conn{} = conn) do + if Pleroma.Config.get([:ldap, :enabled]) do + {name, password} = + case conn.params do + %{"authorization" => %{"name" => name, "password" => password}} -> + {name, password} + + %{"grant_type" => "password", "username" => name, "password" => password} -> + {name, password} + end + + case ldap_user(name, password) do + %User{} = user -> + {:ok, user} + + {:error, {:ldap_connection_error, _}} -> + # When LDAP is unavailable, try default authenticator + Pleroma.Web.Auth.PleromaAuthenticator.get_user(conn) + + error -> + error + end + else + # Fall back to default authenticator + Pleroma.Web.Auth.PleromaAuthenticator.get_user(conn) + end + end + + def handle_error(%Plug.Conn{} = _conn, error) do + error + end + + def auth_template, do: nil + + defp ldap_user(name, password) do + ldap = Pleroma.Config.get(:ldap, []) + host = Keyword.get(ldap, :host, "localhost") + port = Keyword.get(ldap, :port, 389) + ssl = Keyword.get(ldap, :ssl, false) + sslopts = Keyword.get(ldap, :sslopts, []) + + options = + [{:port, port}, {:ssl, ssl}, {:timeout, @connection_timeout}] ++ + if sslopts != [], do: [{:sslopts, sslopts}], else: [] + + case :eldap.open([to_charlist(host)], options) do + {:ok, connection} -> + try do + uid = Keyword.get(ldap, :uid, "cn") + base = Keyword.get(ldap, :base) + + case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do + :ok -> + case User.get_by_nickname_or_email(name) do + %User{} = user -> + user + + _ -> + register_user(connection, base, uid, name, password) + end + + error -> + error + end + after + :eldap.close(connection) + end + + {:error, error} -> + Logger.error("Could not open LDAP connection: #{inspect(error)}") + {:error, {:ldap_connection_error, error}} + end + end + + defp register_user(connection, base, uid, name, password) do + case :eldap.search(connection, [ + {:base, to_charlist(base)}, + {:filter, :eldap.equalityMatch(to_charlist(uid), to_charlist(name))}, + {:scope, :eldap.wholeSubtree()}, + {:timeout, @search_timeout} + ]) do + {:ok, {:eldap_search_result, [{:eldap_entry, _, attributes}], _}} -> + with {_, [mail]} <- List.keyfind(attributes, 'mail', 0) do + params = %{ + email: :erlang.list_to_binary(mail), + name: name, + nickname: name, + password: password, + password_confirmation: password + } + + changeset = User.register_changeset(%User{}, params) + + case User.register(changeset) do + {:ok, user} -> user + error -> error + end + else + _ -> {:error, :ldap_registration_missing_attributes} + end + + error -> + error + end + end +end diff --git a/lib/pleroma/web/auth/pleroma_authenticator.ex b/lib/pleroma/web/auth/pleroma_authenticator.ex index 3cc19af01..360772895 100644 --- a/lib/pleroma/web/auth/pleroma_authenticator.ex +++ b/lib/pleroma/web/auth/pleroma_authenticator.ex @@ -9,7 +9,14 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do @behaviour Pleroma.Web.Auth.Authenticator def get_user(%Plug.Conn{} = conn) do - %{"authorization" => %{"name" => name, "password" => password}} = conn.params + {name, password} = + case conn.params do + %{"authorization" => %{"name" => name, "password" => password}} -> + {name, password} + + %{"grant_type" => "password", "username" => name, "password" => password} -> + {name, password} + end with {_, %User{} = user} <- {:user, User.get_by_nickname_or_email(name)}, {_, true} <- {:checkpw, Pbkdf2.checkpw(password, user.password_hash)} do diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index c2b6dd477..7d5a5b9c5 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -11,7 +11,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do alias Pleroma.Web.OAuth.App alias Pleroma.Repo alias Pleroma.User - alias Comeonin.Pbkdf2 import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2] @@ -126,10 +125,10 @@ defmodule Pleroma.Web.OAuth.OAuthController do def token_exchange( conn, - %{"grant_type" => "password", "username" => name, "password" => password} = params + %{"grant_type" => "password"} = params ) do - with %App{} = app <- get_app_from_request(conn, params), - %User{} = user <- get_user(name, password), + with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn)}, + %App{} = app <- get_app_from_request(conn, params), {:auth_active, true} <- {:auth_active, User.auth_active?(user)}, scopes <- oauth_scopes(params, app.scopes), [] <- scopes -- app.scopes, @@ -213,28 +212,4 @@ defmodule Pleroma.Web.OAuth.OAuthController do nil end end - - defp get_user(name, password) do - if Pleroma.Config.get([:ldap, :enabled]) do - case Pleroma.LDAP.get_user(name, password) do - %User{} = user -> - user - - {:error, {:ldap_connection_error, _}} -> - # When LDAP is unavailable, try default login - with %User{} = user <- User.get_by_nickname_or_email(name), - true <- Pbkdf2.checkpw(password, user.password_hash) do - user - end - - error -> - error - end - else - with %User{} = user <- User.get_by_nickname_or_email(name), - true <- Pbkdf2.checkpw(password, user.password_hash) do - user - end - end - end end -- cgit v1.2.3 From 9338f061a303ae3d57a8ea1af524c2ca51929f8d Mon Sep 17 00:00:00 2001 From: link0ff Date: Tue, 12 Mar 2019 18:20:02 +0200 Subject: Support LDAP method start_tls --- lib/pleroma/web/auth/ldap_authenticator.ex | 55 +++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/auth/ldap_authenticator.ex b/lib/pleroma/web/auth/ldap_authenticator.ex index 56f2f5aed..88217aab8 100644 --- a/lib/pleroma/web/auth/ldap_authenticator.ex +++ b/lib/pleroma/web/auth/ldap_authenticator.ex @@ -60,22 +60,23 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do case :eldap.open([to_charlist(host)], options) do {:ok, connection} -> try do - uid = Keyword.get(ldap, :uid, "cn") - base = Keyword.get(ldap, :base) - - case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do - :ok -> - case User.get_by_nickname_or_email(name) do - %User{} = user -> - user - - _ -> - register_user(connection, base, uid, name, password) - end - - error -> - error + if Keyword.get(ldap, :tls, false) do + :application.ensure_all_started(:ssl) + + case :eldap.start_tls( + connection, + Keyword.get(ldap, :tlsopts, []), + @connection_timeout + ) do + :ok -> + :ok + + error -> + Logger.error("Could not start TLS: #{inspect(error)}") + end end + + bind_user(connection, ldap, name, password) after :eldap.close(connection) end @@ -86,11 +87,31 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do end end + defp bind_user(connection, ldap, name, password) do + uid = Keyword.get(ldap, :uid, "cn") + base = Keyword.get(ldap, :base) + + case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do + :ok -> + case User.get_by_nickname_or_email(name) do + %User{} = user -> + user + + _ -> + register_user(connection, base, uid, name, password) + end + + error -> + error + end + end + defp register_user(connection, base, uid, name, password) do case :eldap.search(connection, [ {:base, to_charlist(base)}, {:filter, :eldap.equalityMatch(to_charlist(uid), to_charlist(name))}, {:scope, :eldap.wholeSubtree()}, + {:attributes, ['mail', 'email']}, {:timeout, @search_timeout} ]) do {:ok, {:eldap_search_result, [{:eldap_entry, _, attributes}], _}} -> @@ -110,7 +131,9 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do error -> error end else - _ -> {:error, :ldap_registration_missing_attributes} + _ -> + Logger.error("Could not find LDAP attribute mail: #{inspect(attributes)}") + {:error, :ldap_registration_missing_attributes} end error -> -- cgit v1.2.3 From f86f7dbb8f7bd72bd4037b03224b2840de4a4292 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:04:52 +0000 Subject: activitypub: utils: rework make_flag_data to accept either activity payloads or IRIs --- lib/pleroma/web/activity_pub/utils.ex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 182f9cacb..9881b7bbb 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -621,7 +621,12 @@ defmodule Pleroma.Web.ActivityPub.Utils do #### Flag-related helpers def make_flag_data(params, additional) do - status_ap_ids = Enum.map(params.statuses || [], & &1.data["id"]) + status_ap_ids = + Enum.map(params.statuses || [], fn + act when is_map(act) -> act["id"] + act when is_binary(act) -> act + end) + object = [params.account.ap_id] ++ status_ap_ids %{ -- cgit v1.2.3 From 0f3ecb2bfbb42ce16eb3144d62a932bfc32ce656 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:06:02 +0000 Subject: activitypub: transmogrifier: accept remote Flag activities --- lib/pleroma/web/activity_pub/transmogrifier.ex | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 1247e4b61..8e4bf7b47 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -355,6 +355,40 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end + # Flag objects are placed ahead of the ID check because Mastodon 2.8 and earlier send them + # with nil ID. + def handle_incoming(%{"type" => "Flag", "object" => objects, "actor" => actor} = data) do + with context <- data["context"] || Utils.generate_context_id(), + content <- data["content"] || "", + %User{} = actor <- User.get_cached_by_ap_id(actor), + + # Reduce the object list to find the reported user. + %User{} = account <- + Enum.reduce_while(objects, nil, fn ap_id, _ -> + with %User{} = user <- User.get_cached_by_ap_id(ap_id) do + {:halt, user} + else + _ -> {:cont, nil} + end + end), + + # Remove the reported user from the object list. + statuses <- Enum.filter(objects, fn ap_id -> ap_id != account.ap_id end) do + params = %{ + actor: actor, + context: context, + account: account, + statuses: statuses, + content: content, + additional: %{ + "cc" => [account.ap_id] + } + } + + ActivityPub.flag(params) + end + end + # disallow objects with bogus IDs def handle_incoming(%{"id" => nil}), do: :error def handle_incoming(%{"id" => ""}), do: :error -- cgit v1.2.3 From 379442ad17cab9c27863be2c885d10f8b6eadeca Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:29:04 +0000 Subject: activitypub: utils: also match Activity objects --- lib/pleroma/web/activity_pub/utils.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 9881b7bbb..af317245f 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -623,6 +623,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do def make_flag_data(params, additional) do status_ap_ids = Enum.map(params.statuses || [], fn + %Activity{} = act -> act.data["id"] act when is_map(act) -> act["id"] act when is_binary(act) -> act end) -- cgit v1.2.3 From 3b48d5f0c27b42a6ea409fffbdc6b831da2ff4ca Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:29:33 +0000 Subject: common api: add support for forwarding reports --- lib/pleroma/web/common_api/common_api.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index de0759fb0..ead4928b5 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -284,7 +284,8 @@ defmodule Pleroma.Web.CommonAPI do actor: user, account: account, statuses: statuses, - content: content_html + content: content_html, + forward: data["forward"] || false }) do Enum.each(User.all_superusers(), fn superuser -> superuser -- cgit v1.2.3 From 64b0120d678b106f33d5c903749fcac5ed5a1ed7 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:29:47 +0000 Subject: activitypub: add support for forwarding reports --- lib/pleroma/web/activity_pub/activity_pub.ex | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 70db419ca..7d21fe65f 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -370,20 +370,32 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do content: content } = params ) do - additional = params[:additional] || %{} - # only accept false as false value local = !(params[:local] == false) + forward = !(params[:forward] == false) + + additional = params[:additional] || %{} - %{ + params = %{ actor: actor, context: context, account: account, statuses: statuses, content: content } - |> make_flag_data(additional) - |> insert(local) + + additional = + if forward do + Map.merge(additional, %{"to" => [], "cc" => [account.ap_id]}) + else + additional + end + + with flag_data <- make_flag_data(params, additional), + {:ok, activity} <- insert(flag_data, local), + :ok <- maybe_federate(activity) do + {:ok, activity} + end end def fetch_activities_for_context(context, opts \\ %{}) do -- cgit v1.2.3 From 5c7b774f09d86414e6a8ef6494ccd2e6a76c1396 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:38:46 +0000 Subject: reports: unify sending e-mail for both remote and local reports --- lib/pleroma/web/activity_pub/activity_pub.ex | 6 ++++++ lib/pleroma/web/common_api/common_api.ex | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 7d21fe65f..32f69e0fa 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -394,6 +394,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with flag_data <- make_flag_data(params, additional), {:ok, activity} <- insert(flag_data, local), :ok <- maybe_federate(activity) do + Enum.each(User.all_superusers(), fn superuser -> + superuser + |> Pleroma.AdminEmail.report(actor, account, statuses, content) + |> Pleroma.Mailer.deliver_async() + end) + {:ok, activity} end end diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index ead4928b5..edbcd3397 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -287,12 +287,6 @@ defmodule Pleroma.Web.CommonAPI do content: content_html, forward: data["forward"] || false }) do - Enum.each(User.all_superusers(), fn superuser -> - superuser - |> Pleroma.AdminEmail.report(user, account, statuses, content_html) - |> Pleroma.Mailer.deliver_async() - end) - {:ok, activity} else {:error, err} -> {:error, err} -- cgit v1.2.3 From 423fd07928d64dd7810ac408265a37ae1274956f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 14 Mar 2019 19:52:08 +0000 Subject: activitypub: inject to/cc fields on non-forwarded reports since Flag activities are now Forwardable --- lib/pleroma/web/activity_pub/activity_pub.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 32f69e0fa..45a030ca3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -388,7 +388,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do if forward do Map.merge(additional, %{"to" => [], "cc" => [account.ap_id]}) else - additional + Map.merge(additional, %{"to" => [], "cc" => []}) end with flag_data <- make_flag_data(params, additional), -- cgit v1.2.3 From 958227d5563d76f4f983b7cabb6948897d93bd4b Mon Sep 17 00:00:00 2001 From: rinpatch Date: Fri, 15 Mar 2019 01:36:29 +0300 Subject: MediaProxy: parse filename from content-disposition for non-whitelisted types --- lib/pleroma/reverse_proxy.ex | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index 6298b92f4..39ede8619 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -311,7 +311,25 @@ defmodule Pleroma.ReverseProxy do end if attachment? do - disposition = "attachment; filename=" <> Keyword.get(opts, :attachment_name, "attachment") + name = + try do + {{"content-disposition", content_disposition_string}, _} = + List.keytake(headers, "content-disposition", 0) + + [name] = + Regex.run( + ~r/filename=\"(.*)\"/u, + content_disposition_string || "", + capture: :all_but_first + ) + + name + rescue + MatchError -> Keyword.get(opts, :attachment_name, "attachment") + end + + disposition = "attachment; filename=" <> name + List.keystore(headers, "content-disposition", 0, {"content-disposition", disposition}) else headers -- cgit v1.2.3 From d02f1120f9fe8e048bac6665e95e51648a50c53b Mon Sep 17 00:00:00 2001 From: rinpatch Date: Fri, 15 Mar 2019 08:29:51 +0300 Subject: Content-Disposition regex improvements --- lib/pleroma/reverse_proxy.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index 39ede8619..a3f177fec 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -316,9 +316,9 @@ defmodule Pleroma.ReverseProxy do {{"content-disposition", content_disposition_string}, _} = List.keytake(headers, "content-disposition", 0) - [name] = + [name | _] = Regex.run( - ~r/filename=\"(.*)\"/u, + ~r/filename="((?:[^"\\]|\\.)*)"/u, content_disposition_string || "", capture: :all_but_first ) @@ -328,7 +328,7 @@ defmodule Pleroma.ReverseProxy do MatchError -> Keyword.get(opts, :attachment_name, "attachment") end - disposition = "attachment; filename=" <> name + disposition = "attachment; filename=\"#{name}\"" List.keystore(headers, "content-disposition", 0, {"content-disposition", disposition}) else -- cgit v1.2.3 From c8f31e0bc2764c924a4045e007e828052c837ac2 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Sat, 9 Mar 2019 14:08:41 +0100 Subject: Implement mastodon's reblog hiding feature --- lib/pleroma/user.ex | 4 ++++ lib/pleroma/user/info.ex | 13 +++++++++++++ lib/pleroma/web/activity_pub/activity_pub.ex | 10 +++++++++- lib/pleroma/web/common_api/common_api.ex | 16 ++++++++++++++++ lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 13 +++++++++++++ lib/pleroma/web/mastodon_api/views/account_view.ex | 2 +- 6 files changed, 56 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1ce9882f6..467cb910b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1385,4 +1385,8 @@ defmodule Pleroma.User do offset: ^((page - 1) * page_size) ) end + + def showing_reblogs?(%User{} = user, %User{} = target) do + target.id not in user.info.muted_reblogs + end end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index e3fd65a6e..35586e212 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -21,6 +21,7 @@ defmodule Pleroma.User.Info do field(:blocks, {:array, :string}, default: []) field(:domain_blocks, {:array, :string}, default: []) field(:mutes, {:array, :string}, default: []) + field(:muted_reblogs, {:array, :string}, default: []) field(:deactivated, :boolean, default: false) field(:no_rich_text, :boolean, default: false) field(:ap_enabled, :boolean, default: false) @@ -259,4 +260,16 @@ defmodule Pleroma.User.Info do moderator: is_moderator } end + + def add_reblog_mute(info, id) do + params = %{muted_reblogs: info.muted_reblogs ++ [id]} + + cast(info, params, [:muted_reblogs]) + end + + def remove_reblog_mute(info, id) do + params = %{muted_reblogs: List.delete(info.muted_reblogs, id)} + + cast(info, params, [:muted_reblogs]) + end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 70db419ca..779ee139b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -951,9 +951,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do entire_thread_visible_for_user?(activity, user) end + # filter out muted threads + def contain_muted_boosts(%Activity{data: %{"type" => "Announce"}} = activity, %User{} = user) do + id = User.get_by_ap_id(activity.actor).id + id not in user.info.muted_reblogs + end + + def contain_muted_boosts(%Activity{} = _activity, %User{} = _user), do: true + # do post-processing on a specific activity def contain_activity(%Activity{} = activity, %User{} = user) do - contain_broken_threads(activity, user) + contain_broken_threads(activity, user) and contain_muted_boosts(activity, user) end # do post-processing on a timeline diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index de0759fb0..035c59387 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -299,4 +299,20 @@ defmodule Pleroma.Web.CommonAPI do {:account, nil} -> {:error, "Account not found"} end end + + def hide_reblogs(user, id) do + if id not in user.info.muted_reblogs do + info_changeset = User.Info.add_reblog_mute(user.info, id) + changeset = Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset) + User.update_and_set_cache(changeset) + end + end + + def show_reblogs(user, id) do + if id in user.info.muted_reblogs do + info_changeset = User.Info.remove_reblog_mute(user.info, id) + changeset = Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset) + User.update_and_set_cache(changeset) + end + end end diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 265bf837e..570bf0c0f 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -723,11 +723,24 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), + false <- User.following?(follower, followed), {:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do conn |> put_view(AccountView) |> render("relationship.json", %{user: follower, target: followed}) else + true -> + case conn.params["reblogs"] do + true -> CommonAPI.show_reblogs(follower, id) + false -> CommonAPI.hide_reblogs(follower, id) + end + + followed = Repo.get(User, id) + + conn + |> put_view(AccountView) + |> render("relationship.json", %{user: follower, target: followed}) + {:error, message} -> conn |> put_resp_content_type("application/json") diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index c32f27be2..b5f3bbb9d 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -55,7 +55,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do muting_notifications: false, requested: requested, domain_blocking: false, - showing_reblogs: false, + showing_reblogs: User.showing_reblogs?(user, target), endorsed: false } end -- cgit v1.2.3 From fe4c1d26fcbe5ce260bde94e75f617ae0fcb338f Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Sat, 9 Mar 2019 16:24:32 +0100 Subject: Add ActivityPub.contain_activity checks to streamer --- lib/pleroma/web/streamer.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 5850a9579..bd91e1f50 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.Streamer do alias Pleroma.User alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.MastodonAPI.NotificationView + alias Pleroma.Web.ActivityPub.ActivityPub @keepalive_interval :timer.seconds(30) @@ -203,7 +204,9 @@ defmodule Pleroma.Web.Streamer do parent = Object.normalize(item.data["object"]) unless is_nil(parent) or item.actor in blocks or item.actor in mutes or - parent.data["actor"] in blocks or parent.data["actor"] in mutes do + not ActivityPub.contain_activity(item, user) or + parent.data["actor"] in blocks or + parent.data["actor"] in mutes do send(socket.transport_pid, {:text, represent_update(item, user)}) end else @@ -233,7 +236,8 @@ defmodule Pleroma.Web.Streamer do blocks = user.info.blocks || [] mutes = user.info.mutes || [] - unless item.actor in blocks or item.actor in mutes do + unless item.actor in blocks or item.actor in mutes or + not ActivityPub.contain_activity(item, user) do send(socket.transport_pid, {:text, represent_update(item, user)}) end else -- cgit v1.2.3 From aa71139e4a9913cc5baf3f5f567bcef4ae59a8c0 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Sat, 9 Mar 2019 16:31:53 +0100 Subject: Fix elixir 1.8 vs 1.7 format conflict --- lib/pleroma/web/streamer.ex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index bd91e1f50..a04ee1b6e 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -204,8 +204,7 @@ defmodule Pleroma.Web.Streamer do parent = Object.normalize(item.data["object"]) unless is_nil(parent) or item.actor in blocks or item.actor in mutes or - not ActivityPub.contain_activity(item, user) or - parent.data["actor"] in blocks or + not ActivityPub.contain_activity(item, user) or parent.data["actor"] in blocks or parent.data["actor"] in mutes do send(socket.transport_pid, {:text, represent_update(item, user)}) end -- cgit v1.2.3 From 15b21d1983fad08e71f6fd7adffbcfd6f2d8cba1 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Mon, 11 Mar 2019 16:57:54 +0100 Subject: refactor filtering mechanism --- lib/pleroma/web/activity_pub/activity_pub.ex | 21 ++++++++++++++------- .../web/mastodon_api/mastodon_api_controller.ex | 2 +- lib/pleroma/web/streamer.ex | 2 ++ 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 779ee139b..5d9ce7fd7 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -679,6 +679,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_pinned(query, _), do: query + defp restrict_muted_reblogs(query, %{"muting_user" => %User{info: info}}) do + muted_reblogs = info.muted_reblogs || [] + + from( + activity in query, + where: fragment("not ?->>'type' = 'Announce'", activity.data), + where: fragment("not ? = ANY(?)", activity.actor, ^muted_reblogs) + ) + end + + defp restrict_muted_reblogs(query, _), do: query + def fetch_activities_query(recipients, opts \\ %{}) do base_query = from( @@ -706,6 +718,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_replies(opts) |> restrict_reblogs(opts) |> restrict_pinned(opts) + |> restrict_muted_reblogs(opts) end def fetch_activities(recipients, opts \\ %{}) do @@ -951,17 +964,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do entire_thread_visible_for_user?(activity, user) end - # filter out muted threads - def contain_muted_boosts(%Activity{data: %{"type" => "Announce"}} = activity, %User{} = user) do - id = User.get_by_ap_id(activity.actor).id - id not in user.info.muted_reblogs - end - def contain_muted_boosts(%Activity{} = _activity, %User{} = _user), do: true # do post-processing on a specific activity def contain_activity(%Activity{} = activity, %User{} = user) do - contain_broken_threads(activity, user) and contain_muted_boosts(activity, user) + contain_broken_threads(activity, user) end # do post-processing on a timeline diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 570bf0c0f..68b7d8b49 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -735,7 +735,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do false -> CommonAPI.hide_reblogs(follower, id) end - followed = Repo.get(User, id) + followed = User.get_cached_by_id(id) conn |> put_view(AccountView) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index a04ee1b6e..b87db941b 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -200,10 +200,12 @@ defmodule Pleroma.Web.Streamer do user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) blocks = user.info.blocks || [] mutes = user.info.mutes || [] + reblog_mutes = user.info.reblog_mutes || [] parent = Object.normalize(item.data["object"]) unless is_nil(parent) or item.actor in blocks or item.actor in mutes or + item.actor in reblog_mutes or not ActivityPub.contain_activity(item, user) or parent.data["actor"] in blocks or parent.data["actor"] in mutes do send(socket.transport_pid, {:text, represent_update(item, user)}) -- cgit v1.2.3 From be465c762be19eda6725d4f323798caa23241715 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Mon, 11 Mar 2019 19:59:25 +0100 Subject: formatting --- lib/pleroma/web/streamer.ex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index b87db941b..fa0fb2ac8 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -205,9 +205,8 @@ defmodule Pleroma.Web.Streamer do parent = Object.normalize(item.data["object"]) unless is_nil(parent) or item.actor in blocks or item.actor in mutes or - item.actor in reblog_mutes or - not ActivityPub.contain_activity(item, user) or parent.data["actor"] in blocks or - parent.data["actor"] in mutes do + item.actor in reblog_mutes or not ActivityPub.contain_activity(item, user) or + parent.data["actor"] in blocks or parent.data["actor"] in mutes do send(socket.transport_pid, {:text, represent_update(item, user)}) end else -- cgit v1.2.3 From da53c079db91ce5d7ba14809f5e99b10d3ae307a Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Fri, 15 Mar 2019 14:06:58 +0100 Subject: Refactor to store user ap_id, add tests --- lib/pleroma/user.ex | 2 +- lib/pleroma/user/info.ex | 8 ++++---- lib/pleroma/web/common_api/common_api.ex | 16 ++++++++++------ lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 11 ++++++----- lib/pleroma/web/streamer.ex | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 467cb910b..692ae836c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1387,6 +1387,6 @@ defmodule Pleroma.User do end def showing_reblogs?(%User{} = user, %User{} = target) do - target.id not in user.info.muted_reblogs + target.ap_id not in user.info.muted_reblogs end end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 35586e212..70b72710b 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -261,14 +261,14 @@ defmodule Pleroma.User.Info do } end - def add_reblog_mute(info, id) do - params = %{muted_reblogs: info.muted_reblogs ++ [id]} + def add_reblog_mute(info, ap_id) do + params = %{muted_reblogs: info.muted_reblogs ++ [ap_id]} cast(info, params, [:muted_reblogs]) end - def remove_reblog_mute(info, id) do - params = %{muted_reblogs: List.delete(info.muted_reblogs, id)} + def remove_reblog_mute(info, ap_id) do + params = %{muted_reblogs: List.delete(info.muted_reblogs, ap_id)} cast(info, params, [:muted_reblogs]) end diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 035c59387..84d66efc9 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -300,17 +300,21 @@ defmodule Pleroma.Web.CommonAPI do end end - def hide_reblogs(user, id) do - if id not in user.info.muted_reblogs do - info_changeset = User.Info.add_reblog_mute(user.info, id) + def hide_reblogs(user, muted) do + ap_id = muted.ap_id + + if ap_id not in user.info.muted_reblogs do + info_changeset = User.Info.add_reblog_mute(user.info, ap_id) changeset = Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset) User.update_and_set_cache(changeset) end end - def show_reblogs(user, id) do - if id in user.info.muted_reblogs do - info_changeset = User.Info.remove_reblog_mute(user.info, id) + def show_reblogs(user, muted) do + ap_id = muted.ap_id + + if ap_id in user.info.muted_reblogs do + info_changeset = User.Info.remove_reblog_mute(user.info, ap_id) changeset = Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset) User.update_and_set_cache(changeset) end diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 68b7d8b49..952aa2453 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -730,13 +730,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> render("relationship.json", %{user: follower, target: followed}) else true -> - case conn.params["reblogs"] do - true -> CommonAPI.show_reblogs(follower, id) - false -> CommonAPI.hide_reblogs(follower, id) - end - followed = User.get_cached_by_id(id) + {:ok, follower} = + case conn.params["reblogs"] do + true -> CommonAPI.show_reblogs(follower, followed) + false -> CommonAPI.hide_reblogs(follower, followed) + end + conn |> put_view(AccountView) |> render("relationship.json", %{user: follower, target: followed}) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index fa0fb2ac8..a0863a062 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -200,7 +200,7 @@ defmodule Pleroma.Web.Streamer do user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) blocks = user.info.blocks || [] mutes = user.info.mutes || [] - reblog_mutes = user.info.reblog_mutes || [] + reblog_mutes = user.info.muted_reblogs || [] parent = Object.normalize(item.data["object"]) -- cgit v1.2.3 From 094e1ef048f972fc3ead8d597ac9dbe6f5f62f34 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Fri, 15 Mar 2019 14:28:14 +0100 Subject: formatting --- lib/pleroma/user/info.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 70b72710b..740a46727 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -260,7 +260,7 @@ defmodule Pleroma.User.Info do moderator: is_moderator } end - + def add_reblog_mute(info, ap_id) do params = %{muted_reblogs: info.muted_reblogs ++ [ap_id]} -- cgit v1.2.3 From dfeb3aec44efb9ffdbe9e6409a79aa50b7e268a8 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Fri, 15 Mar 2019 14:36:07 +0100 Subject: fix credo warning --- lib/pleroma/web/streamer.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index a0863a062..7425bfb54 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -10,9 +10,9 @@ defmodule Pleroma.Web.Streamer do alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User + alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.MastodonAPI.NotificationView - alias Pleroma.Web.ActivityPub.ActivityPub @keepalive_interval :timer.seconds(30) -- cgit v1.2.3 From d8244c2a1bfc54b9dfa70be3ce49db961205f883 Mon Sep 17 00:00:00 2001 From: Karen Konou Date: Fri, 15 Mar 2019 15:03:03 +0100 Subject: remove unused function --- lib/pleroma/web/activity_pub/activity_pub.ex | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5d9ce7fd7..a65d6e020 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -964,8 +964,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do entire_thread_visible_for_user?(activity, user) end - def contain_muted_boosts(%Activity{} = _activity, %User{} = _user), do: true - # do post-processing on a specific activity def contain_activity(%Activity{} = activity, %User{} = user) do contain_broken_threads(activity, user) -- cgit v1.2.3 From 43fb03be5a8968c1df23938ed4f5a93825ab476c Mon Sep 17 00:00:00 2001 From: eugenijm Date: Fri, 15 Mar 2019 20:06:28 +0300 Subject: Allow to mark a single notification as read --- lib/pleroma/notification.ex | 14 ++++++++++++++ lib/pleroma/web/router.ex | 6 ++++++ lib/pleroma/web/twitter_api/controllers/util_controller.ex | 12 ++++++++++++ 3 files changed, 32 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index fe8181d8b..765191275 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Notification do alias Pleroma.Web.CommonAPI.Utils import Ecto.Query + import Ecto.Changeset schema "notifications" do field(:seen, :boolean, default: false) @@ -22,6 +23,11 @@ defmodule Pleroma.Notification do timestamps() end + def changeset(%Notification{} = notification, attrs) do + notification + |> cast(attrs, [:seen]) + end + # TODO: Make generic and unify (see activity_pub.ex) defp restrict_max(query, %{"max_id" => max_id}) do from(activity in query, where: activity.id < ^max_id) @@ -68,6 +74,14 @@ defmodule Pleroma.Notification do Repo.update_all(query, []) end + def read_one(%User{} = user, notification_id) do + with {:ok, %Notification{} = notification} <- get(user, notification_id) do + notification + |> changeset(%{seen: true}) + |> Repo.update() + end + end + def get(%{id: user_id} = _user, id) do query = from( diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index c56e4a421..befd382ba 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -190,6 +190,12 @@ defmodule Pleroma.Web.Router do post("/blocks_import", UtilController, :blocks_import) post("/follow_import", UtilController, :follow_import) end + + scope [] do + pipe_through(:oauth_read) + + post("/notifications/read", UtilController, :notifications_read) + end end scope "/oauth", Pleroma.Web.OAuth do diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 8ed02a93f..320ec778c 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -9,6 +9,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do alias Comeonin.Pbkdf2 alias Pleroma.Emoji + alias Pleroma.Notification alias Pleroma.PasswordResetToken alias Pleroma.Repo alias Pleroma.User @@ -142,6 +143,17 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end + def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do + with {:ok, _} <- Notification.read_one(user, notification_id) do + json(conn, %{status: "success"}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end + def config(conn, _params) do instance = Pleroma.Config.get(:instance) instance_fe = Pleroma.Config.get(:fe) -- cgit v1.2.3 From e0edc706cfe1a625ce5bf35e1935cfdc8b251edc Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 16 Mar 2019 01:12:50 +0000 Subject: oauth: add me property to token responses --- lib/pleroma/web/oauth/oauth_controller.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index ec70b7ccc..a2c876627 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -105,6 +105,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do fixed_token = fix_padding(params["code"]), %Authorization{} = auth <- Repo.get_by(Authorization, token: fixed_token, app_id: app.id), + %User{} = user <- Repo.get(User, auth.user_id), {:ok, token} <- Token.exchange_token(app, auth), {:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do response = %{ @@ -113,7 +114,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do refresh_token: token.refresh_token, created_at: DateTime.to_unix(inserted_at), expires_in: 60 * 10, - scope: Enum.join(token.scopes, " ") + scope: Enum.join(token.scopes, " "), + me: user.ap_id } json(conn, response) @@ -142,7 +144,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do access_token: token.token, refresh_token: token.refresh_token, expires_in: 60 * 10, - scope: Enum.join(token.scopes, " ") + scope: Enum.join(token.scopes, " "), + me: user.ap_id } json(conn, response) -- cgit v1.2.3 From 4ed2618f6c732ba1009510f5698a5d981a151925 Mon Sep 17 00:00:00 2001 From: Fong-Wan Chau Date: Sun, 17 Mar 2019 09:46:46 -0400 Subject: Allow 'rel' attribute on `` link with specific values (for hashtag recognition). --- lib/pleroma/html.ex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index 05253157e..5b152d926 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -95,6 +95,13 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do Meta.allow_tag_with_uri_attributes("a", ["href", "data-user", "data-tag"], @valid_schemes) Meta.allow_tag_with_these_attributes("a", ["name", "title", "class"]) + Meta.allow_tag_with_this_attribute_values("a", "rel", [ + "tag", + "nofollow", + "noopener", + "noreferrer" + ]) + # paragraphs and linebreaks Meta.allow_tag_with_these_attributes("br", []) Meta.allow_tag_with_these_attributes("p", []) @@ -137,6 +144,13 @@ defmodule Pleroma.HTML.Scrubber.Default do Meta.allow_tag_with_uri_attributes("a", ["href", "data-user", "data-tag"], @valid_schemes) Meta.allow_tag_with_these_attributes("a", ["name", "title", "class"]) + Meta.allow_tag_with_this_attribute_values("a", "rel", [ + "tag", + "nofollow", + "noopener", + "noreferrer" + ]) + Meta.allow_tag_with_these_attributes("abbr", ["title"]) Meta.allow_tag_with_these_attributes("b", []) -- cgit v1.2.3