support for tuples with more than 2 values
authorAlex S <alex.strizhakov@gmail.com>
Sat, 22 Jun 2019 14:30:53 +0000 (17:30 +0300)
committerAlex S <alex.strizhakov@gmail.com>
Sat, 22 Jun 2019 14:30:53 +0000 (17:30 +0300)
docs/api/admin_api.md
lib/pleroma/web/admin_api/config.ex
test/web/admin_api/admin_api_controller_test.exs
test/web/admin_api/config_test.exs

index 5dcc8d059952cad8ab9611f4d0c2928c9fff8fd3..63af338213fcf3a422eee088c029e835fe2485a2 100644 (file)
@@ -580,6 +580,8 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
 Module name can be passed as string, which starts with `Pleroma`, e.g. `"Pleroma.Upload"`.
 Atom or boolean value can be passed with `:` in the beginning, e.g. `":true"`, `":upload"`.
 Integer with `i:`, e.g. `"i:150"`.
+Tuple with more than 2 values with `{"tuple": ["first_val", Pleroma.Module, []]}`.
+`{"tuple": ["some_string", "Pleroma.Some.Module", []]}` will be converted to `{"some_string", Pleroma.Some.Module, []}`.
 
 Compile time settings (need instance reboot):
 - all settings by this keys:
@@ -619,6 +621,9 @@ Compile time settings (need instance reboot):
             "follow_redirect": ":true",
             "pool": ":upload"
           }
+        },
+        "dispatch": {
+          "tuple": ["/api/v1/streaming", "Pleroma.Web.MastodonAPI.WebsocketHandler", []]
         }
       }
      }
@@ -632,7 +637,7 @@ Compile time settings (need instance reboot):
   configs: [
     {
       "key": string,
-      "value": string or {} or []
+      "value": string or {} or [] or {"tuple": []}
      }
   ]
 }
index ddcfc87d5cbaabb716dc86b64e2bc2fdba958f89..2e149bf256182008e3fc40cd930efd44d3bc95dd 100644 (file)
@@ -77,6 +77,8 @@ defmodule Pleroma.Web.AdminAPI.Config do
   defp do_convert({k, v} = value) when is_tuple(value),
     do: %{k => do_convert(v)}
 
+  defp do_convert(value) when is_tuple(value), do: %{"tuple" => do_convert(Tuple.to_list(value))}
+
   defp do_convert(value) when is_binary(value) or is_map(value) or is_number(value), do: value
 
   defp do_convert(value) when is_atom(value) do
@@ -108,11 +110,16 @@ defmodule Pleroma.Web.AdminAPI.Config do
 
   defp do_transform(%Regex{} = value) when is_map(value), do: value
 
+  defp do_transform(%{"tuple" => [k, values] = entity}) when length(entity) == 2 do
+    {do_transform(k), do_transform(values)}
+  end
+
+  defp do_transform(%{"tuple" => values}) do
+    Enum.reduce(values, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end)
+  end
+
   defp do_transform(value) when is_map(value) do
-    values =
-      for {key, val} <- value,
-          into: [],
-          do: {String.to_atom(key), do_transform(val)}
+    values = for {key, val} <- value, into: [], do: {String.to_atom(key), do_transform(val)}
 
     Enum.sort(values)
   end
@@ -124,28 +131,27 @@ defmodule Pleroma.Web.AdminAPI.Config do
   defp do_transform(entity) when is_list(entity) and length(entity) == 1, do: hd(entity)
 
   defp do_transform(value) when is_binary(value) do
-    value = String.trim(value)
+    String.trim(value)
+    |> do_transform_string()
+  end
+
+  defp do_transform(value), do: value
 
-    case String.length(value) do
-      0 ->
-        nil
+  defp do_transform_string(value) when byte_size(value) == 0, do: nil
 
-      _ ->
-        cond do
-          String.starts_with?(value, "Pleroma") ->
-            String.to_existing_atom("Elixir." <> value)
+  defp do_transform_string(value) do
+    cond do
+      String.starts_with?(value, "Pleroma") or String.starts_with?(value, "Phoenix") ->
+        String.to_existing_atom("Elixir." <> value)
 
-          String.starts_with?(value, ":") ->
-            String.replace(value, ":", "") |> String.to_existing_atom()
+      String.starts_with?(value, ":") ->
+        String.replace(value, ":", "") |> String.to_existing_atom()
 
-          String.starts_with?(value, "i:") ->
-            String.replace(value, "i:", "") |> String.to_integer()
+      String.starts_with?(value, "i:") ->
+        String.replace(value, "i:", "") |> String.to_integer()
 
-          true ->
-            value
-        end
+      true ->
+        value
     end
   end
-
-  defp do_transform(value), do: value
 end
index 17a872b217f77d2d3c58ad5dcc2f61daea0f03a4..49889d6d7e18cad4171de2d242c7db31cb858f89 100644 (file)
@@ -1343,6 +1343,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
         Application.delete_env(:pleroma, :key4)
         Application.delete_env(:pleroma, :keyaa1)
         Application.delete_env(:pleroma, :keyaa2)
+        Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
+        Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
         :ok = File.rm(temp_file)
       end)
 
@@ -1469,7 +1471,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
         post(conn, "/api/pleroma/admin/config", %{
           configs: [
             %{
-              "key" => "Pleroma.Captcha",
+              "key" => "Pleroma.Captcha.NotReal",
               "value" => %{
                 "enabled" => ":false",
                 "method" => "Pleroma.Captcha.Kocaptcha",
@@ -1482,7 +1484,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
       assert json_response(conn, 200) == %{
                "configs" => [
                  %{
-                   "key" => "Pleroma.Captcha",
+                   "key" => "Pleroma.Captcha.NotReal",
                    "value" => [
                      %{"enabled" => false},
                      %{"method" => "Pleroma.Captcha.Kocaptcha"},
@@ -1492,5 +1494,119 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                ]
              }
     end
+
+    test "tuples with more than two values", %{conn: conn} do
+      conn =
+        post(conn, "/api/pleroma/admin/config", %{
+          configs: [
+            %{
+              "key" => "Pleroma.Web.Endpoint.NotReal",
+              "value" => [
+                %{
+                  "http" => %{
+                    "dispatch" => [
+                      %{
+                        "tuple" => [
+                          ":_",
+                          [
+                            %{
+                              "tuple" => [
+                                "/api/v1/streaming",
+                                "Pleroma.Web.MastodonAPI.WebsocketHandler",
+                                []
+                              ]
+                            },
+                            %{
+                              "tuple" => [
+                                "/websocket",
+                                "Phoenix.Endpoint.CowboyWebSocket",
+                                %{
+                                  "tuple" => [
+                                    "Phoenix.Transports.WebSocket",
+                                    %{
+                                      "tuple" => [
+                                        "Pleroma.Web.Endpoint",
+                                        "Pleroma.Web.UserSocket",
+                                        []
+                                      ]
+                                    }
+                                  ]
+                                }
+                              ]
+                            },
+                            %{
+                              "tuple" => [
+                                ":_",
+                                "Phoenix.Endpoint.Cowboy2Handler",
+                                %{
+                                  "tuple" => ["Pleroma.Web.Endpoint", []]
+                                }
+                              ]
+                            }
+                          ]
+                        ]
+                      }
+                    ]
+                  }
+                }
+              ]
+            }
+          ]
+        })
+
+      assert json_response(conn, 200) == %{
+               "configs" => [
+                 %{
+                   "key" => "Pleroma.Web.Endpoint.NotReal",
+                   "value" => [
+                     %{
+                       "http" => %{
+                         "dispatch" => %{
+                           "_" => [
+                             %{
+                               "tuple" => [
+                                 "/api/v1/streaming",
+                                 "Pleroma.Web.MastodonAPI.WebsocketHandler",
+                                 []
+                               ]
+                             },
+                             %{
+                               "tuple" => [
+                                 "/websocket",
+                                 "Phoenix.Endpoint.CowboyWebSocket",
+                                 %{
+                                   "Elixir.Phoenix.Transports.WebSocket" => %{
+                                     "tuple" => [
+                                       "Pleroma.Web.Endpoint",
+                                       "Pleroma.Web.UserSocket",
+                                       []
+                                     ]
+                                   }
+                                 }
+                               ]
+                             },
+                             %{
+                               "tuple" => [
+                                 "_",
+                                 "Phoenix.Endpoint.Cowboy2Handler",
+                                 %{"Elixir.Pleroma.Web.Endpoint" => []}
+                               ]
+                             }
+                           ]
+                         }
+                       }
+                     }
+                   ]
+                 }
+               ]
+             }
+    end
   end
 end
+
+# Needed for testing
+defmodule Pleroma.Web.Endpoint.NotReal do
+end
+
+defmodule Pleroma.Captcha.NotReal do
+end
index a2fedca4061b6a591ac0d24f5c5a68300d947b4c..39050c27682b85ff6516da3fb86687c4f51e89b3 100644 (file)
@@ -179,5 +179,80 @@ defmodule Pleroma.Web.AdminAPI.ConfigTest do
       assert Config.from_binary(binary) ==
                [federated_timeline_removal: [], reject: [~r/comp[lL][aA][iI][nN]er/], replace: []]
     end
+
+    test "complex map with tuples with more than 2 values" do
+      binary =
+        Config.transform(%{
+          "http" => %{
+            "dispatch" => [
+              %{
+                "tuple" => [
+                  ":_",
+                  [
+                    %{
+                      "tuple" => [
+                        "/api/v1/streaming",
+                        "Pleroma.Web.MastodonAPI.WebsocketHandler",
+                        []
+                      ]
+                    },
+                    %{
+                      "tuple" => [
+                        "/websocket",
+                        "Phoenix.Endpoint.CowboyWebSocket",
+                        %{
+                          "tuple" => [
+                            "Phoenix.Transports.WebSocket",
+                            %{"tuple" => ["Pleroma.Web.Endpoint", "Pleroma.Web.UserSocket", []]}
+                          ]
+                        }
+                      ]
+                    },
+                    %{
+                      "tuple" => [
+                        ":_",
+                        "Phoenix.Endpoint.Cowboy2Handler",
+                        %{
+                          "tuple" => ["Pleroma.Web.Endpoint", []]
+                        }
+                      ]
+                    }
+                  ]
+                ]
+              }
+            ]
+          }
+        })
+
+      assert binary ==
+               :erlang.term_to_binary(
+                 http: [
+                   dispatch: [
+                     _: [
+                       {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
+                       {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
+                        {Phoenix.Transports.WebSocket,
+                         {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}},
+                       {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
+                     ]
+                   ]
+                 ]
+               )
+
+      assert Config.from_binary(binary) == [
+               http: [
+                 dispatch: [
+                   {:_,
+                    [
+                      {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
+                      {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
+                       {Phoenix.Transports.WebSocket,
+                        {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}},
+                      {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
+                    ]}
+                 ]
+               ]
+             ]
+    end
   end
 end