Merge remote-tracking branch 'pleroma/develop' into cycles-constants
authorAlex Gleason <alex@alexgleason.me>
Tue, 1 Jun 2021 16:32:30 +0000 (11:32 -0500)
committerAlex Gleason <alex@alexgleason.me>
Tue, 1 Jun 2021 16:33:11 +0000 (11:33 -0500)
1  2 
lib/pleroma/web/activity_pub/builder.ex
lib/pleroma/web/activity_pub/object_validators/announce_validator.ex
lib/pleroma/web/activity_pub/utils.ex
lib/pleroma/web/common_api/utils.ex
test/pleroma/web/mastodon_api/controllers/status_controller_test.exs

index f74888b67d17b7f07dc657c437afb340590ce60b,91a45836fbbf925bc9e33c32e2e11cee15e7e369..cde4777103d3330aa3356f604698c1f6fe79345b
@@@ -223,7 -223,7 +223,7 @@@ defmodule Pleroma.Web.ActivityPub.Build
            [actor.follower_address]
  
          public? and Visibility.is_local_public?(object) ->
 -          [actor.follower_address, object.data["actor"], Pleroma.Constants.as_local_public()]
 +          [actor.follower_address, object.data["actor"], Utils.as_local_public()]
  
          public? ->
            [actor.follower_address, object.data["actor"], Pleroma.Constants.as_public()]
         "context" => object.data["context"]
       }, []}
    end
+   @spec pin(User.t(), Object.t()) :: {:ok, map(), keyword()}
+   def pin(%User{} = user, object) do
+     {:ok,
+      %{
+        "id" => Utils.generate_activity_id(),
+        "target" => pinned_url(user.nickname),
+        "object" => object.data["id"],
+        "actor" => user.ap_id,
+        "type" => "Add",
+        "to" => [Pleroma.Constants.as_public()],
+        "cc" => [user.follower_address]
+      }, []}
+   end
+   @spec unpin(User.t(), Object.t()) :: {:ok, map, keyword()}
+   def unpin(%User{} = user, object) do
+     {:ok,
+      %{
+        "id" => Utils.generate_activity_id(),
+        "target" => pinned_url(user.nickname),
+        "object" => object.data["id"],
+        "actor" => user.ap_id,
+        "type" => "Remove",
+        "to" => [Pleroma.Constants.as_public()],
+        "cc" => [user.follower_address]
+      }, []}
+   end
+   defp pinned_url(nickname) when is_binary(nickname) do
+     Pleroma.Web.Router.Helpers.activity_pub_url(Pleroma.Web.Endpoint, :pinned, nickname)
+   end
  end
index 0045007422dde95379332cb2bc9ea388b55a4954,5763417903056c2f79f994bf4cc806f049276a20..a2f752ac3ce2836f46d08b8514423aadbab6e355
@@@ -50,7 -50,7 +50,7 @@@ defmodule Pleroma.Web.ActivityPub.Objec
      cng
    end
  
-   def validate_data(data_cng) do
+   defp validate_data(data_cng) do
      data_cng
      |> validate_inclusion(:type, ["Announce"])
      |> validate_required([:id, :type, :object, :actor, :to, :cc])
@@@ -68,7 -68,7 +68,7 @@@
           false <- Visibility.is_public?(object) do
        same_actor = object.data["actor"] == actor.ap_id
        recipients = get_field(cng, :to) ++ get_field(cng, :cc)
 -      local_public = Pleroma.Constants.as_local_public()
 +      local_public = Utils.as_local_public()
  
        is_public =
          Enum.member?(recipients, Pleroma.Constants.as_public()) or
index 984f39aa7628d3fc81837d51b65de95f1fe334e1,0513498aa5baa53862a5efecb1697409d7ef95ae..1df53f79ad75f20dc1f8b7ef193e7c52d1d8b9a9
@@@ -12,7 -12,6 +12,6 @@@ defmodule Pleroma.Web.ActivityPub.Util
    alias Pleroma.Object
    alias Pleroma.Repo
    alias Pleroma.User
-   alias Pleroma.Web
    alias Pleroma.Web.ActivityPub.ActivityPub
    alias Pleroma.Web.ActivityPub.Visibility
    alias Pleroma.Web.AdminAPI.AccountView
@@@ -38,8 -37,6 +37,8 @@@
    @supported_report_states ~w(open closed resolved)
    @valid_visibilities ~w(public unlisted private direct)
  
-   def as_local_public, do: Web.base_url() <> "/#Public"
++  def as_local_public, do: Endpoint.url() <> "/#Public"
 +
    # Some implementations send the actor URI as the actor field, others send the entire actor object,
    # so figure out what the actor's URI is based on what we have.
    def get_ap_id(%{"id" => id} = _), do: id
          !label_in_collection?(ap_id, params["cc"])
  
      if need_splice? do
-       cc_list = extract_list(params["cc"])
-       Map.put(params, "cc", [ap_id | cc_list])
+       cc = [ap_id | extract_list(params["cc"])]
+       params
+       |> Map.put("cc", cc)
+       |> Maps.safe_put_in(["object", "cc"], cc)
      else
        params
      end
      %{
        "@context" => [
          "https://www.w3.org/ns/activitystreams",
-         "#{Web.base_url()}/schemas/litepub-0.1.jsonld",
+         "#{Endpoint.url()}/schemas/litepub-0.1.jsonld",
          %{
            "@language" => "und"
          }
    end
  
    def generate_id(type) do
-     "#{Web.base_url()}/#{type}/#{UUID.generate()}"
+     "#{Endpoint.url()}/#{type}/#{UUID.generate()}"
    end
  
    def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do
index 93bb8e8fa5f85f228aa46f0d134b8075b988a60f,94a378e11e4abc8d23dd3ce60039b29c838e2a34..4cc34002d11ae3c0a073abae3ddb6141a5983f24
@@@ -69,7 -69,7 +69,7 @@@ defmodule Pleroma.Web.CommonAPI.Utils d
      to =
        case visibility do
          "public" -> [Pleroma.Constants.as_public() | draft.mentions]
 -        "local" -> [Pleroma.Constants.as_local_public() | draft.mentions]
 +        "local" -> [Utils.as_local_public() | draft.mentions]
        end
  
      cc = [draft.user.follower_address]
      draft.status
      |> format_input(content_type, options)
      |> maybe_add_attachments(draft.attachments, attachment_links)
-     |> maybe_add_nsfw_tag(draft.params)
    end
  
    defp get_content_type(content_type) do
      end
    end
  
-   defp maybe_add_nsfw_tag({text, mentions, tags}, %{"sensitive" => sensitive})
-        when sensitive in [true, "True", "true", "1"] do
-     {text, mentions, [{"#nsfw", "nsfw"} | tags]}
-   end
-   defp maybe_add_nsfw_tag(data, _), do: data
    def make_context(_, %Participation{} = participation) do
      Repo.preload(participation, :conversation).conversation.ap_id
    end
    def format_input(text, "text/markdown", options) do
      text
      |> Formatter.mentions_escape(options)
-     |> Earmark.as_html!(%Earmark.Options{renderer: Pleroma.EarmarkRenderer})
+     |> Formatter.markdown_to_html()
      |> Formatter.linkify(options)
      |> Formatter.html_escape("text/html")
    end
index fe0a5c28d7a5b1437bad6566449bc60b3362d9d0,99ad87d051c44b685eb3f35044a28d07b2e57e6e..055dd4bea21230fc4a4627d7158c26f23bb6e5f5
@@@ -14,7 -14,6 +14,7 @@@ defmodule Pleroma.Web.MastodonAPI.Statu
    alias Pleroma.Tests.ObanHelpers
    alias Pleroma.User
    alias Pleroma.Web.ActivityPub.ActivityPub
 +  alias Pleroma.Web.ActivityPub.Utils
    alias Pleroma.Web.CommonAPI
  
    import Pleroma.Factory
        assert activity.data["cc"] == []
      end
  
-     @tag :skip
      test "discloses application metadata when enabled" do
        user = insert(:user, disclose_client: true)
        %{user: _user, token: token, conn: conn} = oauth_access(["write:statuses"], user: user)
            "status" => "cofe is my copilot"
          })
  
+       assert %{
+                "content" => "cofe is my copilot"
+              } = json_response_and_validate_schema(result, 200)
+       activity = result.assigns.activity.id
+       result =
+         conn
+         |> get("api/v1/statuses/#{activity}")
        assert %{
                 "content" => "cofe is my copilot",
                 "application" => %{
            "status" => "club mate is my wingman"
          })
  
+       assert %{"content" => "club mate is my wingman"} =
+                json_response_and_validate_schema(result, 200)
+       activity = result.assigns.activity.id
+       result =
+         conn
+         |> get("api/v1/statuses/#{activity}")
        assert %{
                 "content" => "club mate is my wingman",
                 "application" => nil
      setup do: clear_config([:instance, :max_pinned_statuses], 1)
  
      test "pin status", %{conn: conn, user: user, activity: activity} do
-       id_str = to_string(activity.id)
+       id = activity.id
  
-       assert %{"id" => ^id_str, "pinned" => true} =
+       assert %{"id" => ^id, "pinned" => true} =
                 conn
                 |> put_req_header("content-type", "application/json")
                 |> post("/api/v1/statuses/#{activity.id}/pin")
                 |> json_response_and_validate_schema(200)
  
-       assert [%{"id" => ^id_str, "pinned" => true}] =
+       assert [%{"id" => ^id, "pinned" => true}] =
                 conn
                 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
                 |> json_response_and_validate_schema(200)
      end
  
+     test "non authenticated user", %{activity: activity} do
+       assert build_conn()
+              |> put_req_header("content-type", "application/json")
+              |> post("/api/v1/statuses/#{activity.id}/pin")
+              |> json_response(403) == %{"error" => "Invalid credentials."}
+     end
      test "/pin: returns 400 error when activity is not public", %{conn: conn, user: user} do
        {:ok, dm} = CommonAPI.post(user, %{status: "test", visibility: "direct"})
  
          |> put_req_header("content-type", "application/json")
          |> post("/api/v1/statuses/#{dm.id}/pin")
  
-       assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not pin"}
+       assert json_response_and_validate_schema(conn, 422) == %{
+                "error" => "Non-public status cannot be pinned"
+              }
+     end
+     test "pin by another user", %{activity: activity} do
+       %{conn: conn} = oauth_access(["write:accounts"])
+       assert conn
+              |> put_req_header("content-type", "application/json")
+              |> post("/api/v1/statuses/#{activity.id}/pin")
+              |> json_response(422) == %{"error" => "Someone else's status cannot be pinned"}
      end
  
      test "unpin status", %{conn: conn, user: user, activity: activity} do
                 |> json_response_and_validate_schema(200)
      end
  
-     test "/unpin: returns 400 error when activity is not exist", %{conn: conn} do
-       conn =
-         conn
-         |> put_req_header("content-type", "application/json")
-         |> post("/api/v1/statuses/1/unpin")
-       assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not unpin"}
+     test "/unpin: returns 404 error when activity doesn't exist", %{conn: conn} do
+       assert conn
+              |> put_req_header("content-type", "application/json")
+              |> post("/api/v1/statuses/1/unpin")
+              |> json_response_and_validate_schema(404) == %{"error" => "Record not found"}
      end
  
      test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
          "visibility" => "local"
        })
  
 -    local = Pleroma.Constants.as_local_public()
 +    local = Utils.as_local_public()
  
      assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
               json_response(conn_one, 200)