pluralise settings

This commit is contained in:
FloatingGhost 2022-09-19 21:09:13 +01:00
parent 56e3d11807
commit 8a3b7a3757
8 changed files with 125 additions and 58 deletions

View File

@ -1,4 +1,4 @@
defmodule Pleroma.Akkoma.FrontendSettingProfile do defmodule Pleroma.Akkoma.FrontendSettingsProfile do
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
@ -84,12 +84,13 @@ defmodule Pleroma.Akkoma.FrontendSettingProfile do
defp validate_version(changeset, %{version: nil}), do: changeset defp validate_version(changeset, %{version: nil}), do: changeset
defp validate_version(%Ecto.Changeset{changes: %{version: version}} = changeset, %{version: prev_version}) do defp validate_version(%Ecto.Changeset{changes: %{version: version}} = changeset, %{
version: prev_version
}) do
if version != prev_version + 1 do if version != prev_version + 1 do
add_error(changeset, :version, "must be incremented by 1") add_error(changeset, :version, "must be incremented by 1")
else else
changeset changeset
end end
end end
end end

View File

@ -165,7 +165,7 @@ defmodule Pleroma.User do
has_many(:outgoing_relationships, UserRelationship, foreign_key: :source_id) has_many(:outgoing_relationships, UserRelationship, foreign_key: :source_id)
has_many(:incoming_relationships, UserRelationship, foreign_key: :target_id) has_many(:incoming_relationships, UserRelationship, foreign_key: :target_id)
has_many(:frontend_profiles, Pleroma.Akkoma.FrontendSettingProfile) has_many(:frontend_profiles, Pleroma.Akkoma.FrontendSettingsProfile)
for {relationship_type, for {relationship_type,
[ [

View File

@ -2,22 +2,24 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Akkoma.FrontendSettingProfile alias Pleroma.Akkoma.FrontendSettingsProfile
@unauthenticated_access %{fallback: :proceed_unauthenticated, scopes: []} @unauthenticated_access %{fallback: :proceed_unauthenticated, scopes: []}
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{@unauthenticated_access | scopes: ["read:accounts"]} %{@unauthenticated_access | scopes: ["read:accounts"]}
when action in [ when action in [
:list_profiles, :get_profile :list_profiles,
] :get_profile
]
) )
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{@unauthenticated_access | scopes: ["write:accounts"]} %{@unauthenticated_access | scopes: ["write:accounts"]}
when action in [ when action in [
:update_profile :update_profile
] ]
) )
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
@ -27,9 +29,17 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
@doc "GET /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name" @doc "GET /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name"
def get_profile(conn, %{frontend_name: frontend_name, profile_name: profile_name}) do def get_profile(conn, %{frontend_name: frontend_name, profile_name: profile_name}) do
with %FrontendSettingProfile{} = profile <- FrontendSettingProfile.get_by_user_and_frontend_name_and_profile_name(conn.assigns.user, frontend_name, profile_name) do with %FrontendSettingsProfile{} = profile <-
FrontendSettingsProfile.get_by_user_and_frontend_name_and_profile_name(
conn.assigns.user,
frontend_name,
profile_name
) do
conn conn
|> json(profile.settings) |> json(%{
settings: profile.settings,
version: profile.version
})
else else
nil -> {:error, :not_found} nil -> {:error, :not_found}
end end
@ -37,17 +47,34 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
@doc "GET /api/v1/akkoma/frontend_settings/:frontend_name" @doc "GET /api/v1/akkoma/frontend_settings/:frontend_name"
def list_profiles(conn, %{frontend_name: frontend_name}) do def list_profiles(conn, %{frontend_name: frontend_name}) do
with profiles <- FrontendSettingProfile.get_all_by_user_and_frontend_name(conn.assigns.user, frontend_name), with profiles <-
data <- Enum.map(profiles, fn profile -> profile.profile_name end) do FrontendSettingsProfile.get_all_by_user_and_frontend_name(
conn.assigns.user,
frontend_name
),
data <-
Enum.map(profiles, fn profile ->
%{name: profile.profile_name, version: profile.version}
end) do
json(conn, data) json(conn, data)
end end
end end
@doc "PUT /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name" @doc "PUT /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name"
def update_profile(%{body_params: %{settings: settings, version: version}} = conn, %{frontend_name: frontend_name, profile_name: profile_name}) do def update_profile(%{body_params: %{settings: settings, version: version}} = conn, %{
with {:ok, profile} <- FrontendSettingProfile.create_or_update(conn.assigns.user, frontend_name, profile_name, settings, version) do frontend_name: frontend_name,
profile_name: profile_name
}) do
with {:ok, profile} <-
FrontendSettingsProfile.create_or_update(
conn.assigns.user,
frontend_name,
profile_name,
settings,
version
) do
conn conn
|> json(profile.settings) |> json(profile.settings)
end end
end end
end end

View File

@ -20,7 +20,10 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
responses: %{ responses: %{
200 => 200 =>
Operation.response("Profiles", "application/json", %Schema{type: :array, items: %Schema{type: :string}}) Operation.response("Profiles", "application/json", %Schema{
type: :array,
items: %Schema{type: :string}
})
} }
} }
end end
@ -35,10 +38,8 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
parameters: [frontend_name_param(), profile_name_param()], parameters: [frontend_name_param(), profile_name_param()],
responses: %{ responses: %{
200 => 200 => Operation.response("Translation", "application/json", %Schema{type: :object}),
Operation.response("Translation", "application/json", %Schema{type: :object}), 404 => Operation.response("Not Found", "application/json", %Schema{type: :object})
404 =>
Operation.response("Not Found", "application/json", %Schema{type: :object})
} }
} }
end end
@ -54,10 +55,8 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
parameters: [frontend_name_param(), profile_name_param()], parameters: [frontend_name_param(), profile_name_param()],
requestBody: profile_body_param(), requestBody: profile_body_param(),
responses: %{ responses: %{
200 => 200 => Operation.response("Settings", "application/json", %Schema{type: :object}),
Operation.response("Settings", "application/json", %Schema{type: :object}), 422 => Operation.response("Invalid", "application/json", %Schema{type: :object})
422 =>
Operation.response("Invalid", "application/json", %Schema{type: :object})
} }
} }
end end
@ -77,7 +76,8 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
end end
def profile_body_param do def profile_body_param do
request_body("Settings", request_body(
"Settings",
%Schema{ %Schema{
title: "Frontend Setting Profile", title: "Frontend Setting Profile",
type: :object, type: :object,
@ -98,6 +98,7 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
} }
} }
}, },
required: true) required: true
)
end end
end end

View File

@ -468,8 +468,18 @@ defmodule Pleroma.Web.Router do
get("/translation/languages", TranslationController, :languages) get("/translation/languages", TranslationController, :languages)
get("/frontend_settings/:frontend_name", FrontendSettingsController, :list_profiles) get("/frontend_settings/:frontend_name", FrontendSettingsController, :list_profiles)
get("/frontend_settings/:frontend_name/:profile_name", FrontendSettingsController, :get_profile)
put("/frontend_settings/:frontend_name/:profile_name", FrontendSettingsController, :update_profile) get(
"/frontend_settings/:frontend_name/:profile_name",
FrontendSettingsController,
:get_profile
)
put(
"/frontend_settings/:frontend_name/:profile_name",
FrontendSettingsController,
:update_profile
)
end end
scope "/api/v1", Pleroma.Web.MastodonAPI do scope "/api/v1", Pleroma.Web.MastodonAPI do

View File

@ -1,7 +1,7 @@
defmodule Pleroma.Akkoma.FrontendSettingProfileTest do defmodule Pleroma.Akkoma.FrontendSettingsProfileTest do
use Pleroma.DataCase, async: true use Pleroma.DataCase, async: true
use Oban.Testing, repo: Pleroma.Repo use Oban.Testing, repo: Pleroma.Repo
alias Pleroma.Akkoma.FrontendSettingProfile alias Pleroma.Akkoma.FrontendSettingsProfile
import Pleroma.Factory import Pleroma.Factory
@ -11,7 +11,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
frontend_name = "test" frontend_name = "test"
profile_name = "test" profile_name = "test"
settings = %{"test" => "test"} settings = %{"test" => "test"}
struct = %FrontendSettingProfile{} struct = %FrontendSettingsProfile{}
attrs = %{ attrs = %{
user_id: user.id, user_id: user.id,
@ -21,7 +21,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
version: 1 version: 1
} }
assert %{valid?: true} = FrontendSettingProfile.changeset(struct, attrs) assert %{valid?: true} = FrontendSettingsProfile.changeset(struct, attrs)
end end
test "when settings is too long" do test "when settings is too long" do
@ -30,7 +30,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
frontend_name = "test" frontend_name = "test"
profile_name = "test" profile_name = "test"
settings = %{"verylong" => "verylongoops"} settings = %{"verylong" => "verylongoops"}
struct = %FrontendSettingProfile{} struct = %FrontendSettingsProfile{}
attrs = %{ attrs = %{
user_id: user.id, user_id: user.id,
@ -41,7 +41,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
} }
assert %{valid?: false, errors: [settings: {"is too long", _}]} = assert %{valid?: false, errors: [settings: {"is too long", _}]} =
FrontendSettingProfile.changeset(struct, attrs) FrontendSettingsProfile.changeset(struct, attrs)
end end
test "when frontend name is too short" do test "when frontend name is too short" do
@ -49,7 +49,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
frontend_name = "" frontend_name = ""
profile_name = "test" profile_name = "test"
settings = %{"test" => "test"} settings = %{"test" => "test"}
struct = %FrontendSettingProfile{} struct = %FrontendSettingsProfile{}
attrs = %{ attrs = %{
user_id: user.id, user_id: user.id,
@ -60,7 +60,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
} }
assert %{valid?: false, errors: [frontend_name: {"can't be blank", _}]} = assert %{valid?: false, errors: [frontend_name: {"can't be blank", _}]} =
FrontendSettingProfile.changeset(struct, attrs) FrontendSettingsProfile.changeset(struct, attrs)
end end
test "when profile name is too short" do test "when profile name is too short" do
@ -68,7 +68,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
frontend_name = "test" frontend_name = "test"
profile_name = "" profile_name = ""
settings = %{"test" => "test"} settings = %{"test" => "test"}
struct = %FrontendSettingProfile{} struct = %FrontendSettingsProfile{}
attrs = %{ attrs = %{
user_id: user.id, user_id: user.id,
@ -79,7 +79,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
} }
assert %{valid?: false, errors: [profile_name: {"can't be blank", _}]} = assert %{valid?: false, errors: [profile_name: {"can't be blank", _}]} =
FrontendSettingProfile.changeset(struct, attrs) FrontendSettingsProfile.changeset(struct, attrs)
end end
test "when version is negative" do test "when version is negative" do
@ -87,7 +87,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
frontend_name = "test" frontend_name = "test"
profile_name = "test" profile_name = "test"
settings = %{"test" => "test"} settings = %{"test" => "test"}
struct = %FrontendSettingProfile{} struct = %FrontendSettingsProfile{}
attrs = %{ attrs = %{
user_id: user.id, user_id: user.id,
@ -98,7 +98,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
} }
assert %{valid?: false, errors: [version: {"must be greater than %{number}", _}]} = assert %{valid?: false, errors: [version: {"must be greater than %{number}", _}]} =
FrontendSettingProfile.changeset(struct, attrs) FrontendSettingsProfile.changeset(struct, attrs)
end end
end end
@ -109,8 +109,8 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
profile_name = "test" profile_name = "test"
settings = %{"test" => "test"} settings = %{"test" => "test"}
assert {:ok, %FrontendSettingProfile{}} = assert {:ok, %FrontendSettingsProfile{}} =
FrontendSettingProfile.create_or_update( FrontendSettingsProfile.create_or_update(
user, user,
frontend_name, frontend_name,
profile_name, profile_name,
@ -134,8 +134,8 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
settings = %{"test" => "test2"} settings = %{"test" => "test2"}
assert {:ok, %FrontendSettingProfile{settings: ^settings}} = assert {:ok, %FrontendSettingsProfile{settings: ^settings}} =
FrontendSettingProfile.create_or_update( FrontendSettingsProfile.create_or_update(
user, user,
frontend_name, frontend_name,
profile_name, profile_name,
@ -166,8 +166,8 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
version: 1 version: 1
) )
assert [%FrontendSettingProfile{profile_name: "profileA"}, %{profile_name: "profileB"}] = assert [%FrontendSettingsProfile{profile_name: "profileA"}, %{profile_name: "profileB"}] =
FrontendSettingProfile.get_all_by_user_and_frontend_name(user, frontend_name) FrontendSettingsProfile.get_all_by_user_and_frontend_name(user, frontend_name)
end end
end end
@ -185,8 +185,8 @@ defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
version: 1 version: 1
) )
assert %FrontendSettingProfile{profile_name: "profileA"} = assert %FrontendSettingsProfile{profile_name: "profileA"} =
FrontendSettingProfile.get_by_user_and_frontend_name_and_profile_name( FrontendSettingsProfile.get_by_user_and_frontend_name_and_profile_name(
user, user,
frontend_name, frontend_name,
profile_name profile_name

View File

@ -2,7 +2,7 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsControllerTest do
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: true
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Akkoma.FrontendSettingProfile alias Pleroma.Akkoma.FrontendSettingsProfile
describe "GET /api/v1/akkoma/frontend_settings/:frontend_name" do describe "GET /api/v1/akkoma/frontend_settings/:frontend_name" do
test "it returns a list of profiles" do test "it returns a list of profiles" do
@ -17,7 +17,8 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsControllerTest do
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
assert response == [ assert response == [
"test1", "test2" "test1",
"test2"
] ]
end end
end end
@ -33,12 +34,19 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsControllerTest do
test "it returns 200 if found" do test "it returns 200 if found" do
%{conn: conn, user: user} = oauth_access(["read"]) %{conn: conn, user: user} = oauth_access(["read"])
insert(:frontend_setting_profile, user: user, frontend_name: "test", profile_name: "test1", settings: %{"test" => "test"})
insert(:frontend_setting_profile,
user: user,
frontend_name: "test",
profile_name: "test1",
settings: %{"test" => "test"}
)
response = response =
conn conn
|> get("/api/v1/akkoma/frontend_settings/test/test1") |> get("/api/v1/akkoma/frontend_settings/test/test1")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
assert response == %{"test" => "test"} assert response == %{"test" => "test"}
end end
end end
@ -47,24 +55,44 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsControllerTest do
test "puts a config" do test "puts a config" do
%{conn: conn, user: user} = oauth_access(["write"]) %{conn: conn, user: user} = oauth_access(["write"])
settings = %{"test" => "test2"} settings = %{"test" => "test2"}
response = response =
conn conn
|> put_req_header("content-type", "application/json") |> put_req_header("content-type", "application/json")
|> put("/api/v1/akkoma/frontend_settings/test/test1", %{"settings" => settings, "version" => 1}) |> put("/api/v1/akkoma/frontend_settings/test/test1", %{
"settings" => settings,
"version" => 1
})
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
assert response == settings assert response == settings
assert %FrontendSettingProfile{settings: ^settings} = FrontendSettingProfile.get_by_user_and_frontend_name_and_profile_name(user, "test", "test1")
assert %FrontendSettingsProfile{settings: ^settings} =
FrontendSettingsProfile.get_by_user_and_frontend_name_and_profile_name(
user,
"test",
"test1"
)
end end
test "refuses to overwrite a newer config" do test "refuses to overwrite a newer config" do
%{conn: conn, user: user} = oauth_access(["write"]) %{conn: conn, user: user} = oauth_access(["write"])
insert(:frontend_setting_profile, user: user, frontend_name: "test", profile_name: "test1", settings: %{"test" => "test"}, version: 2)
insert(:frontend_setting_profile,
user: user,
frontend_name: "test",
profile_name: "test1",
settings: %{"test" => "test"},
version: 2
)
conn conn
|> put_req_header("content-type", "application/json") |> put_req_header("content-type", "application/json")
|> put("/api/v1/akkoma/frontend_settings/test/test1", %{"settings" => %{"test" => "test2"}, "version" => 1}) |> put("/api/v1/akkoma/frontend_settings/test/test1", %{
"settings" => %{"test" => "test2"},
"version" => 1
})
|> json_response_and_validate_schema(422) |> json_response_and_validate_schema(422)
end end
end end
end end

View File

@ -665,7 +665,7 @@ defmodule Pleroma.Factory do
end end
def frontend_setting_profile_factory(params \\ %{}) do def frontend_setting_profile_factory(params \\ %{}) do
%Pleroma.Akkoma.FrontendSettingProfile{ %Pleroma.Akkoma.FrontendSettingsProfile{
user: build(:user), user: build(:user),
frontend_name: "akkoma-fe", frontend_name: "akkoma-fe",
profile_name: "default", profile_name: "default",