add version field

This commit is contained in:
FloatingGhost 2022-09-13 13:37:57 +01:00
parent fb7cc0d7cc
commit affd255daf
7 changed files with 185 additions and 13 deletions

View File

@ -13,6 +13,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfile do
field(:frontend_name, :string, primary_key: true)
field(:profile_name, :string, primary_key: true)
field(:settings, :map)
field(:version, :integer, default: 1)
timestamps()
end
@ -22,6 +23,7 @@ defmodule Pleroma.Akkoma.FrontendSettingProfile do
|> validate_required([:user_id, :frontend_name, :profile_name, :settings])
|> validate_length(:frontend_name, min: 1, max: 255)
|> validate_length(:profile_name, min: 1, max: 255)
|> validate_version()
|> validate_settings_length(Config.get([:instance, :max_frontend_settings_json_chars]))
end
@ -77,4 +79,13 @@ defmodule Pleroma.Akkoma.FrontendSettingProfile do
changeset
end
end
defp validate_version(%Ecto.Changeset{changes: %{version: version}} = changeset) do
IO.inspect(changeset)
if version < 1 do
add_error(changeset, :version, "must be greater than 0")
else
changeset
end
end
end

View File

@ -7,19 +7,26 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
@unauthenticated_access %{fallback: :proceed_unauthenticated, scopes: []}
plug(
OAuthScopesPlug,
%{@unauthenticated_access | scopes: ["read:account"]}
%{@unauthenticated_access | scopes: ["read:accounts"]}
when action in [
:list, :get, :update
:list_profiles, :get_profile
]
)
plug(
OAuthScopesPlug,
%{@unauthenticated_access | scopes: ["write:accounts"]}
when action in [
:update_profile
]
)
#plug(Pleroma.Web.ApiSpec.CastAndValidate)
#defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TranslationOperation
plug(Pleroma.Web.ApiSpec.CastAndValidate)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.FrontendSettingsOperation
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
@doc "GET /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name"
def get(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
conn
|> json(profile.settings)
@ -29,17 +36,16 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
end
@doc "GET /api/v1/akkoma/frontend_settings/:frontend_name"
def list(conn, %{"frontend_name" => frontend_name}) do
with profiles <- FrontendSettingProfile.get_by_user_and_frontend_name(conn.assigns.user, frontend_name) do
conn
|> json(profiles)
def list_profiles(conn, %{frontend_name: frontend_name}) do
with profiles <- FrontendSettingProfile.get_all_by_user_and_frontend_name(conn.assigns.user, frontend_name),
data <- Enum.map(profiles, fn profile -> profile.profile_name end) do
json(conn, data)
end
end
@doc "PUT /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name"
def update(conn, %{"frontend_name" => frontend_name, "profile_name" => profile_name, "settings" => settings}) do
with %FrontendSettingProfile{} = profile <- FrontendSettingProfile.get_by_user_and_frontend_name_and_profile_name(conn.assigns.user, frontend_name, profile_name),
{:ok, profile} <- FrontendSettingProfile.create_or_update(conn.assigns.user, frontend_name, profile_name, settings) do
def update_profile(conn, %{frontend_name: frontend_name, profile_name: profile_name, settings: settings}) do
with {:ok, profile} <- FrontendSettingProfile.create_or_update(conn.assigns.user, frontend_name, profile_name, settings) do
conn
|> json(profile.settings)
end

View File

@ -0,0 +1,79 @@
defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
@spec open_api_operation(atom) :: Operation.t()
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
@spec list_profiles_operation() :: Operation.t()
def list_profiles_operation() do
%Operation{
tags: ["Retrieve frontend setting profiles"],
summary: "Frontend Settings Profiles",
description: "List frontend setting profiles",
operationId: "AkkomaAPI.FrontendSettingsController.list_profiles",
parameters: [frontend_name_param()],
security: [%{"oAuth" => ["read:accounts"]}],
responses: %{
200 =>
Operation.response("Profiles", "application/json", %Schema{type: :array, items: %Schema{type: :string}})
}
}
end
@spec get_profile_operation() :: Operation.t()
def get_profile_operation() do
%Operation{
tags: ["Retrieve frontend setting profile"],
summary: "Frontend Settings Profile",
description: "Get frontend setting profile",
operationId: "AkkomaAPI.FrontendSettingsController.get_profile",
security: [%{"oAuth" => ["read:accounts"]}],
parameters: [frontend_name_param(), profile_name_param()],
responses: %{
200 =>
Operation.response("Translation", "application/json", %Schema{type: :object}),
404 =>
Operation.response("Not Found", "application/json", %Schema{type: :object})
}
}
end
@spec update_profile_operation() :: Operation.t()
def update_profile_operation() do
%Operation{
tags: ["Update frontend setting profile"],
summary: "Frontend Settings Profile",
description: "Update frontend setting profile",
operationId: "AkkomaAPI.FrontendSettingsController.update_profile_operation",
security: [%{"oAuth" => ["write:accounts"]}],
parameters: [frontend_name_param(), profile_name_param()],
requestBody: request_body_param,
responses: %{
200 =>
Operation.response("Translation", "application/json", %Schema{type: :object})
}
}
end
def frontend_name_param do
Operation.parameter(:frontend_name, :path, :string, "Frontend name",
example: "pleroma-fe",
required: true
)
end
def profile_name_param do
Operation.parameter(:profile_name, :path, :string, "Profile name",
example: "mobile",
required: true
)
end
def profile_body_param do
request_body("Settings", %Schema{type: :object}, required: true),
end
end

View File

@ -466,6 +466,10 @@ defmodule Pleroma.Web.Router do
scope "/api/v1/akkoma", Pleroma.Web.AkkomaAPI do
pipe_through(:authenticated_api)
get("/translation/languages", TranslationController, :languages)
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)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do

View File

@ -6,6 +6,7 @@ defmodule Pleroma.Repo.Migrations.AddUserFrontendProfiles do
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all), primary_key: true)
add(:frontend_name, :string, primary_key: true)
add(:profile_name, :string, primary_key: true)
add(:version, :integer)
add(:settings, :map)
timestamps()
end

View File

@ -0,0 +1,70 @@
defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsControllerTest do
use Pleroma.Web.ConnCase, async: true
import Pleroma.Factory
alias Pleroma.Akkoma.FrontendSettingProfile
describe "GET /api/v1/akkoma/frontend_settings/:frontend_name" do
test "it returns a list of profiles" do
%{conn: conn, user: user} = oauth_access(["read"])
insert(:frontend_setting_profile, user: user, frontend_name: "test", profile_name: "test1")
insert(:frontend_setting_profile, user: user, frontend_name: "test", profile_name: "test2")
response =
conn
|> get("/api/v1/akkoma/frontend_settings/test")
|> json_response_and_validate_schema(200)
assert response == [
"test1", "test2"
]
end
end
describe "GET /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name" do
test "it returns 404 if not found" do
%{conn: conn} = oauth_access(["read"])
conn
|> get("/api/v1/akkoma/frontend_settings/unknown_frontend/unknown_profile")
|> json_response_and_validate_schema(404)
end
test "it returns 200 if found" do
%{conn: conn, user: user} = oauth_access(["read"])
insert(:frontend_setting_profile, user: user, frontend_name: "test", profile_name: "test1", settings: %{"test" => "test"})
response =
conn
|> get("/api/v1/akkoma/frontend_settings/test/test1")
|> json_response_and_validate_schema(200)
assert response == %{"test" => "test"}
end
end
describe "PUT /api/v1/akkoma/frontend_settings/:frontend_name/:profile_name" do
test "puts a config" do
%{conn: conn, user: user} = oauth_access(["write"])
response =
conn
|> put("/api/v1/akkoma/frontend_settings/test/test1", %{"settings" => %{"test" => "test2"}, "version" => 1})
|> json_response_and_validate_schema(200)
assert response == %{"test" => "test2"}
%FrontendSettingProfile{settings: settings} = FrontendSettingProfile.get_by_user_and_frontend_name_and_profile_name(user, "test", "test1")
end
test "refuses to overwrite a newer config" do
%{conn: conn, user: user} = oauth_access(["write"])
insert(:frontend_setting_profile, user: user, frontend_name: "test", profile_name: "test1", settings: %{"test" => "test"}, version: 2)
response =
conn
|> put("/api/v1/akkoma/frontend_settings/test/test1", %{"settings" => %{"test" => "test2"}, "version" => 1})
|> json_response_and_validate_schema(200)
assert response == %{"test" => "test2"}
%FrontendSettingProfile{settings: settings} = FrontendSettingProfile.get_by_user_and_frontend_name_and_profile_name(user, "test", "test1")
end
end
end

View File

@ -669,7 +669,8 @@ defmodule Pleroma.Factory do
user: build(:user),
frontend_name: "akkoma-fe",
profile_name: "default",
settings: %{"test" => "test"}
settings: %{"test" => "test"},
version: 1
}
|> Map.merge(params)
end