[FrontendProfiles] Add setting blob table
This commit is contained in:
parent
4c06c4ecb1
commit
d93e521f4a
6 changed files with 231 additions and 1 deletions
|
@ -260,7 +260,8 @@
|
||||||
password_reset_token_validity: 60 * 60 * 24,
|
password_reset_token_validity: 60 * 60 * 24,
|
||||||
profile_directory: true,
|
profile_directory: true,
|
||||||
privileged_staff: false,
|
privileged_staff: false,
|
||||||
local_bubble: []
|
local_bubble: [],
|
||||||
|
max_frontend_settings_json_chars: 100_000
|
||||||
|
|
||||||
config :pleroma, :welcome,
|
config :pleroma, :welcome,
|
||||||
direct_message: [
|
direct_message: [
|
||||||
|
|
76
lib/pleroma/akkoma/frontend_setting_profile.ex
Normal file
76
lib/pleroma/akkoma/frontend_setting_profile.ex
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
defmodule Pleroma.Akkoma.FrontendSettingProfile do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
import Ecto.Changeset
|
||||||
|
import Ecto.Query
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
|
@primary_key false
|
||||||
|
schema "user_frontend_setting_profiles" do
|
||||||
|
belongs_to(:user, Pleroma.User, primary_key: true, type: FlakeId.Ecto.CompatType)
|
||||||
|
field(:frontend_name, :string, primary_key: true)
|
||||||
|
field(:profile_name, :string, primary_key: true)
|
||||||
|
field(:settings, :map)
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(%__MODULE__{} = struct, attrs) do
|
||||||
|
struct
|
||||||
|
|> cast(attrs, [:user_id, :frontend_name, :profile_name, :settings])
|
||||||
|
|> 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_settings_length(Config.get([:instance, :max_frontend_settings_json_chars]))
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_or_update(%User{} = user, frontend_name, profile_name, settings) do
|
||||||
|
struct =
|
||||||
|
case get_by_user_and_frontend_name_and_profile_name(user.id, frontend_name, profile_name) do
|
||||||
|
nil ->
|
||||||
|
%__MODULE__{}
|
||||||
|
|
||||||
|
%__MODULE__{} = profile ->
|
||||||
|
profile
|
||||||
|
end
|
||||||
|
|
||||||
|
struct
|
||||||
|
|> changeset(%{
|
||||||
|
user_id: user.id,
|
||||||
|
frontend_name: frontend_name,
|
||||||
|
profile_name: profile_name,
|
||||||
|
settings: settings
|
||||||
|
})
|
||||||
|
|> Repo.insert_or_update()
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_all_by_user_and_frontend_name(user_id, frontend_name) do
|
||||||
|
Repo.all(
|
||||||
|
from(p in __MODULE__, where: p.user_id == ^user_id and p.frontend_name == ^frontend_name)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_by_user_and_frontend_name_and_profile_name(user_id, frontend_name, profile_name) do
|
||||||
|
Repo.one(
|
||||||
|
from(p in __MODULE__,
|
||||||
|
where:
|
||||||
|
p.user_id == ^user_id and p.frontend_name == ^frontend_name and
|
||||||
|
p.profile_name == ^profile_name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_settings_length(
|
||||||
|
%Ecto.Changeset{changes: %{settings: settings}} = changeset,
|
||||||
|
max_length
|
||||||
|
) do
|
||||||
|
settings_json = Jason.encode!(settings)
|
||||||
|
|
||||||
|
if String.length(settings_json) > max_length do
|
||||||
|
add_error(changeset, :settings, "is too long")
|
||||||
|
else
|
||||||
|
changeset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -165,6 +165,8 @@ 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)
|
||||||
|
|
||||||
for {relationship_type,
|
for {relationship_type,
|
||||||
[
|
[
|
||||||
{outgoing_relation, outgoing_relation_target},
|
{outgoing_relation, outgoing_relation_target},
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.AddUserFrontendProfiles do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
create_if_not_exists table("user_frontend_setting_profiles", primary_key: false) 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(:settings, :map)
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
create_if_not_exists(
|
||||||
|
unique_index(:user_frontend_setting_profiles, [:user_id, :frontend_name])
|
||||||
|
)
|
||||||
|
|
||||||
|
create_if_not_exists(
|
||||||
|
unique_index(:user_frontend_setting_profiles, [:user_id, :frontend_name, :profile_name])
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
drop_if_exists(table("user_frontend_setting_profiles"))
|
||||||
|
drop_if_exists(unique_index(:user_frontend_setting_profiles, [:user_id, :frontend_name]))
|
||||||
|
|
||||||
|
drop_if_exists(
|
||||||
|
unique_index(:user_frontend_setting_profiles, [:user_id, :frontend_name, :profile_name])
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
111
test/pleroma/akkoma/frontend_setting_profile_test.exs
Normal file
111
test/pleroma/akkoma/frontend_setting_profile_test.exs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
defmodule Pleroma.Akkoma.FrontendSettingProfileTest do
|
||||||
|
use Pleroma.DataCase, async: true
|
||||||
|
use Oban.Testing, repo: Pleroma.Repo
|
||||||
|
alias Pleroma.Akkoma.FrontendSettingProfile
|
||||||
|
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
describe "changeset/2" do
|
||||||
|
test "valid" do
|
||||||
|
user = insert(:user)
|
||||||
|
frontend_name = "test"
|
||||||
|
profile_name = "test"
|
||||||
|
settings = %{"test" => "test"}
|
||||||
|
struct = %FrontendSettingProfile{}
|
||||||
|
|
||||||
|
attrs = %{
|
||||||
|
user_id: user.id,
|
||||||
|
frontend_name: frontend_name,
|
||||||
|
profile_name: profile_name,
|
||||||
|
settings: settings
|
||||||
|
}
|
||||||
|
|
||||||
|
assert %{valid?: true} = FrontendSettingProfile.changeset(struct, attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "when settings is too long" do
|
||||||
|
clear_config([:instance, :max_frontend_settings_json_chars], 10)
|
||||||
|
user = insert(:user)
|
||||||
|
frontend_name = "test"
|
||||||
|
profile_name = "test"
|
||||||
|
settings = %{"verylong" => "verylongoops"}
|
||||||
|
struct = %FrontendSettingProfile{}
|
||||||
|
|
||||||
|
attrs = %{
|
||||||
|
user_id: user.id,
|
||||||
|
frontend_name: frontend_name,
|
||||||
|
profile_name: profile_name,
|
||||||
|
settings: settings
|
||||||
|
}
|
||||||
|
|
||||||
|
assert %{valid?: false, errors: [settings: {"is too long", _}]} =
|
||||||
|
FrontendSettingProfile.changeset(struct, attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "when frontend name is too short" do
|
||||||
|
user = insert(:user)
|
||||||
|
frontend_name = ""
|
||||||
|
profile_name = "test"
|
||||||
|
settings = %{"test" => "test"}
|
||||||
|
struct = %FrontendSettingProfile{}
|
||||||
|
|
||||||
|
attrs = %{
|
||||||
|
user_id: user.id,
|
||||||
|
frontend_name: frontend_name,
|
||||||
|
profile_name: profile_name,
|
||||||
|
settings: settings
|
||||||
|
}
|
||||||
|
|
||||||
|
assert %{valid?: false, errors: [frontend_name: {"can't be blank", _}]} =
|
||||||
|
FrontendSettingProfile.changeset(struct, attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "when profile name is too short" do
|
||||||
|
user = insert(:user)
|
||||||
|
frontend_name = "test"
|
||||||
|
profile_name = ""
|
||||||
|
settings = %{"test" => "test"}
|
||||||
|
struct = %FrontendSettingProfile{}
|
||||||
|
|
||||||
|
attrs = %{
|
||||||
|
user_id: user.id,
|
||||||
|
frontend_name: frontend_name,
|
||||||
|
profile_name: profile_name,
|
||||||
|
settings: settings
|
||||||
|
}
|
||||||
|
|
||||||
|
assert %{valid?: false, errors: [profile_name: {"can't be blank", _}]} =
|
||||||
|
FrontendSettingProfile.changeset(struct, attrs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "create_or_update/2" do
|
||||||
|
test "it should create a new record" do
|
||||||
|
user = insert(:user)
|
||||||
|
frontend_name = "test"
|
||||||
|
profile_name = "test"
|
||||||
|
settings = %{"test" => "test"}
|
||||||
|
|
||||||
|
assert {:ok, %FrontendSettingProfile{}} =
|
||||||
|
FrontendSettingProfile.create_or_update(user, frontend_name, profile_name, settings)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it should update a record" do
|
||||||
|
user = insert(:user)
|
||||||
|
frontend_name = "test"
|
||||||
|
profile_name = "test"
|
||||||
|
|
||||||
|
insert(:frontend_setting_profile,
|
||||||
|
user: user,
|
||||||
|
frontend_name: frontend_name,
|
||||||
|
profile_name: profile_name,
|
||||||
|
settings: %{"test" => "test"}
|
||||||
|
)
|
||||||
|
|
||||||
|
settings = %{"test" => "test2"}
|
||||||
|
|
||||||
|
assert {:ok, %FrontendSettingProfile{settings: ^settings}} =
|
||||||
|
FrontendSettingProfile.create_or_update(user, frontend_name, profile_name, settings)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -663,4 +663,14 @@ def announcement_factory(params \\ %{}) do
|
||||||
|> Map.merge(params)
|
|> Map.merge(params)
|
||||||
|> Pleroma.Announcement.add_rendered_properties()
|
|> Pleroma.Announcement.add_rendered_properties()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def frontend_setting_profile_factory(params \\ %{}) do
|
||||||
|
%Pleroma.Akkoma.FrontendSettingProfile{
|
||||||
|
user: build(:user),
|
||||||
|
frontend_name: "akkoma-fe",
|
||||||
|
profile_name: "default",
|
||||||
|
settings: %{"test" => "test"}
|
||||||
|
}
|
||||||
|
|> Map.merge(params)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue