Allow user to register with custom language
authorTusooa Zhu <tusooa@kazv.moe>
Wed, 2 Mar 2022 06:41:13 +0000 (01:41 -0500)
committerFloatingGhost <hannah@coffee-and-dreams.uk>
Wed, 29 Jun 2022 19:46:51 +0000 (20:46 +0100)
lib/pleroma/user.ex
lib/pleroma/web/api_spec/operations/account_operation.ex
lib/pleroma/web/gettext.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
lib/pleroma/web/plugs/set_locale_plug.ex
lib/pleroma/web/twitter_api/twitter_api.ex
test/pleroma/web/mastodon_api/controllers/account_controller_test.exs

index 70afba3aede41ea0eeff508ce7277be9480e7c24..9a50ee3ec8b8589c3d1b927087170c24ef0d25d5 100644 (file)
@@ -735,7 +735,8 @@ defmodule Pleroma.User do
       :password_confirmation,
       :emoji,
       :accepts_chat_messages,
-      :registration_reason
+      :registration_reason,
+      :language
     ])
     |> validate_required([:name, :nickname, :password, :password_confirmation])
     |> validate_confirmation(:password)
index f5304d7d6fd4d79cdcadbc51b0df680618daad46..bdbae9b747cedc5a2e94a6a07fd4fe4292da4b1c 100644 (file)
@@ -507,6 +507,11 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           type: :string,
           nullable: true,
           description: "Invite token required when the registrations aren't public"
+        },
+        language: %Schema{
+          type: :string,
+          nullable: true,
+          description: "User's preferred language for emails"
         }
       },
       example: %{
index e85290496ef59f215b099212c065020885e28b87..828b98b153d68ad555bc2f0c1a78ce7765b51741 100644 (file)
@@ -35,6 +35,14 @@ defmodule Pleroma.Web.Gettext do
     |> String.replace("_", "-", global: true)
   end
 
+  def normalize_locale(locale) do
+    if is_binary(locale) do
+      String.replace(locale, "-", "_")
+    else
+      nil
+    end
+  end
+
   def supports_locale?(locale) do
     Pleroma.Web.Gettext
     |> Gettext.known_locales()
index 5303bdfd9f438dd1311a476ad3a56b54d4774354..83cebbb963eda2f44e5f5da0cbccbc65059cce9b 100644 (file)
@@ -217,7 +217,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       |> Maps.put_if_present(:is_locked, params[:locked])
       # Note: param name is indeed :discoverable (not an error)
       |> Maps.put_if_present(:is_discoverable, params[:discoverable])
-      |> Maps.put_if_present(:language, params[:language])
+      |> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language]))
 
     # What happens here:
     #
index 3c3fffa81a9ff33ff4da5c046ea64951e3d6f921..4c6e44fb59353e86db2d7ad0a7dab26e2261ae1b 100644 (file)
@@ -25,7 +25,7 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do
 
   defp normalize_language_codes(codes) do
     codes
-    |> Enum.map(fn code -> String.replace(code, "-", "_") end)
+    |> Enum.map(fn code -> Pleroma.Web.Gettext.normalize_locale(code) end)
   end
 
   defp extract_preferred_language(conn) do
index 76ca82d20b6568e60ecd1a020c01e3a09b0c637e..7921653a86f68e7c6f9a1fa57fe86e671e83d047 100644 (file)
@@ -12,6 +12,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
   alias Pleroma.UserInviteToken
 
   def register_user(params, opts \\ []) do
+    fallback_language = Gettext.get_locale()
+
     params =
       params
       |> Map.take([:email, :token, :password])
@@ -20,6 +22,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
       |> Map.put(:name, Map.get(params, :fullname, params[:username]))
       |> Map.put(:password_confirmation, params[:password])
       |> Map.put(:registration_reason, params[:reason])
+      |> Map.put(
+        :language,
+        Pleroma.Web.Gettext.normalize_locale(params[:language]) || fallback_language
+      )
 
     if Pleroma.Config.get([:instance, :registrations_open]) do
       create_user(params, opts)
index 374e2048a732114a60c521bcd1a2073d24201a83..de38a9798d18d47c8360f3407576cdb8d9857ca6 100644 (file)
@@ -11,6 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
   alias Pleroma.Web.ActivityPub.InternalFetchActor
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.OAuth.Token
+  alias Pleroma.Web.Plugs.SetLocalePlug
 
   import Pleroma.Factory
 
@@ -1586,6 +1587,75 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
     end
   end
 
+  describe "create account with language" do
+    setup %{conn: conn} do
+      app_token = insert(:oauth_token, user: nil)
+
+      conn =
+        conn
+        |> put_req_header("authorization", "Bearer " <> app_token.token)
+        |> put_req_header("content-type", "multipart/form-data")
+        |> put_req_cookie(SetLocalePlug.frontend_language_cookie_name(), "zh-Hans")
+        |> SetLocalePlug.call([])
+
+      [conn: conn]
+    end
+
+    test "creates an account with language parameter", %{conn: conn} do
+      params = %{
+        username: "foo",
+        email: "foo@example.org",
+        password: "dupa.8",
+        agreement: true,
+        language: "ru"
+      }
+
+      res =
+        conn
+        |> post("/api/v1/accounts", params)
+
+      assert json_response_and_validate_schema(res, 200)
+
+      assert %{language: "ru"} = Pleroma.User.get_by_nickname("foo")
+    end
+
+    test "language parameter should be normalized", %{conn: conn} do
+      params = %{
+        username: "foo",
+        email: "foo@example.org",
+        password: "dupa.8",
+        agreement: true,
+        language: "ru-RU"
+      }
+
+      res =
+        conn
+        |> post("/api/v1/accounts", params)
+
+      assert json_response_and_validate_schema(res, 200)
+
+      assert %{language: "ru_RU"} = Pleroma.User.get_by_nickname("foo")
+    end
+
+    test "createing an account without language parameter should fallback to cookie/header language",
+         %{conn: conn} do
+      params = %{
+        username: "foo2",
+        email: "foo2@example.org",
+        password: "dupa.8",
+        agreement: true
+      }
+
+      res =
+        conn
+        |> post("/api/v1/accounts", params)
+
+      assert json_response_and_validate_schema(res, 200)
+
+      assert %{language: "zh_Hans"} = Pleroma.User.get_by_nickname("foo2")
+    end
+  end
+
   describe "GET /api/v1/accounts/:id/lists - account_lists" do
     test "returns lists to which the account belongs" do
       %{user: user, conn: conn} = oauth_access(["read:lists"])