Implement meilisearch auth
authorEkaterina Vaartis <vaartis@kotobank.ch>
Mon, 23 Aug 2021 16:35:21 +0000 (19:35 +0300)
committerFloatingGhost <hannah@coffee-and-dreams.uk>
Wed, 29 Jun 2022 19:48:29 +0000 (20:48 +0100)
lib/mix/tasks/pleroma/search/meilisearch.ex
lib/pleroma/search/meilisearch.ex

index 2485a441d8e1e152051bd12c8aaf70bc20f3d7d9..230be5aa127809c6bbe69b9d6d5206e814d7851b 100644 (file)
@@ -9,32 +9,30 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
   import Mix.Pleroma
   import Ecto.Query
 
+  import Pleroma.Search.Meilisearch, only: [meili_post!: 2, meili_delete!: 1]
+
   def run(["index"]) do
     start_pleroma()
 
-    endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
-
-    {:ok, _} =
-      Pleroma.HTTP.post(
-        "#{endpoint}/indexes/objects/settings/ranking-rules",
-        Jason.encode!([
-          "desc(published)",
-          "typo",
-          "words",
-          "proximity",
-          "attribute",
-          "wordsPosition",
-          "exactness"
-        ])
-      )
+    meili_post!(
+      "/indexes/objects/settings/ranking-rules",
+      [
+        "desc(published)",
+        "typo",
+        "words",
+        "proximity",
+        "attribute",
+        "wordsPosition",
+        "exactness"
+      ]
+    )
 
-    {:ok, _} =
-      Pleroma.HTTP.post(
-        "#{endpoint}/indexes/objects/settings/searchable-attributes",
-        Jason.encode!([
-          "content"
-        ])
-      )
+    meili_post!(
+      "/indexes/objects/settings/searchable-attributes",
+      [
+        "content"
+      ]
+    )
 
     chunk_size = 10_000
 
@@ -64,14 +62,14 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
           {[objects], new_acc}
         end)
         |> Stream.each(fn objects ->
-          {:ok, result} =
-            Pleroma.HTTP.post(
-              "#{endpoint}/indexes/objects/documents",
-              Jason.encode!(objects)
+          result =
+            meili_post!(
+              "/indexes/objects/documents",
+              objects
             )
 
-          if not Map.has_key?(Jason.decode!(result.body), "updateId") do
-            IO.puts("Failed to index: #{result}")
+          if not Map.has_key?(result, "updateId") do
+            IO.puts("Failed to index: #{inspect(result)}")
           end
         end)
         |> Stream.run()
@@ -85,11 +83,26 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
   def run(["clear"]) do
     start_pleroma()
 
+    meili_delete!("/indexes/objects/documents")
+  end
+
+  def run(["show-private-key", master_key]) do
+    start_pleroma()
+
     endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
 
-    {:ok, _} =
-      Pleroma.HTTP.request(:delete, "#{endpoint}/indexes/objects/documents", "", [],
-        timeout: :infinity
+    {:ok, result} =
+      Pleroma.HTTP.get(
+        Path.join(endpoint, "/keys"),
+        [{"X-Meili-API-Key", master_key}]
       )
+
+    decoded = Jason.decode!(result.body)
+
+    if decoded["private"] do
+      IO.puts(decoded["private"])
+    else
+      IO.puts("Error fetching the key, check the master key is correct: #{inspect(decoded)}")
+    end
   end
 end
index 10468e36c0bc9839f878b4ef918ae8449d399731..8745d539d799a3a4e6b12b06a5e7cae0f3e8fdd4 100644 (file)
@@ -7,20 +7,50 @@ defmodule Pleroma.Search.Meilisearch do
   import Pleroma.Activity.Search
   import Ecto.Query
 
-  def search(user, query, options \\ []) do
-    limit = Enum.min([Keyword.get(options, :limit), 40])
-    offset = Keyword.get(options, :offset, 0)
-    author = Keyword.get(options, :author)
+  defp meili_headers() do
+    private_key = Pleroma.Config.get([Pleroma.Search.Meilisearch, :private_key])
 
+    if is_nil(private_key), do: [], else: [{"X-Meili-API-Key", private_key}]
+  end
+
+  def meili_post!(path, params) do
     endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
 
     {:ok, result} =
       Pleroma.HTTP.post(
-        "#{endpoint}/indexes/objects/search",
-        Jason.encode!(%{q: query, offset: offset, limit: limit})
+        Path.join(endpoint, path),
+        Jason.encode!(params),
+        meili_headers()
+      )
+
+    Jason.decode!(result.body)
+  end
+
+  def meili_delete!(path) do
+    endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
+
+    {:ok, _} =
+      Pleroma.HTTP.request(
+        :delete,
+        Path.join(endpoint, path),
+        "",
+        meili_headers(),
+        timeout: :infinity
+      )
+  end
+
+  def search(user, query, options \\ []) do
+    limit = Enum.min([Keyword.get(options, :limit), 40])
+    offset = Keyword.get(options, :offset, 0)
+    author = Keyword.get(options, :author)
+
+    result =
+      meili_post!(
+        "/indexes/objects/search",
+        %{q: query, offset: offset, limit: limit}
       )
 
-    hits = Jason.decode!(result.body)["hits"] |> Enum.map(& &1["ap"])
+    hits = result["hits"] |> Enum.map(& &1["ap"])
 
     try do
       hits
@@ -73,30 +103,19 @@ defmodule Pleroma.Search.Meilisearch do
     maybe_search_data = object_to_search_data(activity)
 
     if activity.data["type"] == "Create" and maybe_search_data do
-      endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
-
-      {:ok, result} =
-        Pleroma.HTTP.post(
-          "#{endpoint}/indexes/objects/documents",
-          Jason.encode!([maybe_search_data])
+      result =
+        meili_post!(
+          "/indexes/objects/documents",
+          [maybe_search_data]
         )
 
-      if not Map.has_key?(Jason.decode!(result.body), "updateId") do
-        Logger.error("Failed to add activity #{activity.id} to index: #{result.body}")
+      if not Map.has_key?(result, "updateId") do
+        Logger.error("Failed to add activity #{activity.id} to index: #{inspect(result)}")
       end
     end
   end
 
   def remove_from_index(object) do
-    endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
-
-    {:ok, _} =
-      Pleroma.HTTP.request(
-        :delete,
-        "#{endpoint}/indexes/objects/documents/#{object.id}",
-        "",
-        [],
-        []
-      )
+    meili_delete!("/indexes/objects/documents/#{object.id}")
   end
 end