Merge branch 'refactoring/move-out-keys-from-user-info' into 'develop'

Move local keys out of `user.info`

See merge request pleroma/pleroma!1799
This commit is contained in:
kaniini 2019-10-06 14:32:56 +00:00
commit 2411d09215
9 changed files with 35 additions and 21 deletions

View file

@ -48,7 +48,7 @@ defmodule Pleroma.Signature do
end end
def sign(%User{} = user, headers) do def sign(%User{} = user, headers) do
with {:ok, %{info: %{keys: keys}}} <- User.ensure_keys_present(user), with {:ok, %{keys: keys}} <- User.ensure_keys_present(user),
{:ok, private_key, _} <- Keys.keys_from_pem(keys) do {:ok, private_key, _} <- Keys.keys_from_pem(keys) do
HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers) HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers)
end end

View file

@ -51,6 +51,7 @@ defmodule Pleroma.User do
field(:password_hash, :string) field(:password_hash, :string)
field(:password, :string, virtual: true) field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true) field(:password_confirmation, :string, virtual: true)
field(:keys, :string)
field(:following, {:array, :string}, default: []) field(:following, {:array, :string}, default: [])
field(:ap_id, :string) field(:ap_id, :string)
field(:avatar, :map) field(:avatar, :map)
@ -1554,11 +1555,14 @@ defmodule Pleroma.User do
} }
end end
def ensure_keys_present(%{info: %{keys: keys}} = user) when not is_nil(keys), do: {:ok, user} def ensure_keys_present(%{keys: keys} = user) when not is_nil(keys), do: {:ok, user}
def ensure_keys_present(%User{} = user) do def ensure_keys_present(%User{} = user) do
with {:ok, pem} <- Keys.generate_rsa_pem() do with {:ok, pem} <- Keys.generate_rsa_pem() do
update_info(user, &User.Info.set_keys(&1, pem)) user
|> cast(%{keys: pem}, [:keys])
|> validate_required([:keys])
|> update_and_set_cache()
end end
end end

View file

@ -33,7 +33,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
def render("service.json", %{user: user}) do def render("service.json", %{user: user}) do
{:ok, user} = User.ensure_keys_present(user) {:ok, user} = User.ensure_keys_present(user)
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys) {:ok, _, public_key} = Keys.keys_from_pem(user.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key]) public_key = :public_key.pem_encode([public_key])
@ -69,7 +69,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
def render("user.json", %{user: user}) do def render("user.json", %{user: user}) do
{:ok, user} = User.ensure_keys_present(user) {:ok, user} = User.ensure_keys_present(user)
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys) {:ok, _, public_key} = Keys.keys_from_pem(user.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key]) public_key = :public_key.pem_encode([public_key])

View file

@ -202,7 +202,7 @@ defmodule Pleroma.Web.Salmon do
@spec publish(User.t(), Pleroma.Activity.t()) :: none @spec publish(User.t(), Pleroma.Activity.t()) :: none
def publish(user, activity) def publish(user, activity)
def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity) def publish(%{keys: keys} = user, %{data: %{"type" => type}} = activity)
when type in @supported_activities do when type in @supported_activities do
feed = ActivityRepresenter.to_simple_form(activity, user, true) feed = ActivityRepresenter.to_simple_form(activity, user, true)
@ -238,7 +238,7 @@ defmodule Pleroma.Web.Salmon do
def publish(%{id: id}, _), do: Logger.debug(fn -> "Keys missing for user #{id}" end) def publish(%{id: id}, _), do: Logger.debug(fn -> "Keys missing for user #{id}" end)
def gather_webfinger_links(%User{} = user) do def gather_webfinger_links(%User{} = user) do
{:ok, _private, public} = Keys.keys_from_pem(user.info.keys) {:ok, _private, public} = Keys.keys_from_pem(user.keys)
magic_key = encode_key(public) magic_key = encode_key(public)
[ [

View file

@ -1,15 +1,10 @@
defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do
use Ecto.Migration use Ecto.Migration
import Ecto.Query
alias Pleroma.User alias Pleroma.User
def change do def change do
query = query = from(u in "users", where: fragment("not (?->'deactivated' @> 'true')", u.info), select: %{info: u.info}, where: u.local == true, order_by: u.id)
User.Query.build(%{
local: true,
active: true,
order_by: :id
})
Pleroma.Repo.stream(query) Pleroma.Repo.stream(query)
|> Enum.each(fn |> Enum.each(fn
%{info: %{mutes: mutes} = info} = user -> %{info: %{mutes: mutes} = info} = user ->

View file

@ -0,0 +1,9 @@
defmodule Pleroma.Repo.Migrations.AddKeysColumn do
use Ecto.Migration
def change do
alter table("users") do
add_if_not_exists :keys, :text
end
end
end

View file

@ -0,0 +1,7 @@
defmodule Pleroma.Repo.Migrations.MoveKeysToSeparateColumn do
use Ecto.Migration
def change do
execute("update users set keys = info->>'keys' where local", "update users set info = jsonb_set(info, '{keys}'::text[], to_jsonb(keys)) where local")
end
end

View file

@ -80,7 +80,7 @@ defmodule Pleroma.SignatureTest do
user = user =
insert(:user, %{ insert(:user, %{
ap_id: "https://mastodon.social/users/lambadalambda", ap_id: "https://mastodon.social/users/lambadalambda",
info: %{keys: @private_key} keys: @private_key
}) })
assert Signature.sign( assert Signature.sign(
@ -94,8 +94,7 @@ defmodule Pleroma.SignatureTest do
end end
test "it returns error" do test "it returns error" do
user = user = insert(:user, %{ap_id: "https://mastodon.social/users/lambadalambda", keys: ""})
insert(:user, %{ap_id: "https://mastodon.social/users/lambadalambda", info: %{keys: ""}})
assert Signature.sign( assert Signature.sign(
user, user,

View file

@ -1457,15 +1457,15 @@ defmodule Pleroma.UserTest do
describe "ensure_keys_present" do describe "ensure_keys_present" do
test "it creates keys for a user and stores them in info" do test "it creates keys for a user and stores them in info" do
user = insert(:user) user = insert(:user)
refute is_binary(user.info.keys) refute is_binary(user.keys)
{:ok, user} = User.ensure_keys_present(user) {:ok, user} = User.ensure_keys_present(user)
assert is_binary(user.info.keys) assert is_binary(user.keys)
end end
test "it doesn't create keys if there already are some" do test "it doesn't create keys if there already are some" do
user = insert(:user, %{info: %{keys: "xxx"}}) user = insert(:user, keys: "xxx")
{:ok, user} = User.ensure_keys_present(user) {:ok, user} = User.ensure_keys_present(user)
assert user.info.keys == "xxx" assert user.keys == "xxx"
end end
end end