forked from AkkomaGang/akkoma
Merge branch 'refactor/keys' into 'develop'
move key generation functions into Pleroma.Keys module See merge request pleroma/pleroma!1186
This commit is contained in:
commit
ff363f70b5
14 changed files with 133 additions and 124 deletions
44
lib/pleroma/keys.ex
Normal file
44
lib/pleroma/keys.ex
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Keys do
|
||||||
|
# Native generation of RSA keys is only available since OTP 20+ and in default build conditions
|
||||||
|
# We try at compile time to generate natively an RSA key otherwise we fallback on the old way.
|
||||||
|
try do
|
||||||
|
_ = :public_key.generate_key({:rsa, 2048, 65_537})
|
||||||
|
|
||||||
|
def generate_rsa_pem do
|
||||||
|
key = :public_key.generate_key({:rsa, 2048, 65_537})
|
||||||
|
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
|
||||||
|
pem = :public_key.pem_encode([entry]) |> String.trim_trailing()
|
||||||
|
{:ok, pem}
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
_ ->
|
||||||
|
def generate_rsa_pem do
|
||||||
|
port = Port.open({:spawn, "openssl genrsa"}, [:binary])
|
||||||
|
|
||||||
|
{:ok, pem} =
|
||||||
|
receive do
|
||||||
|
{^port, {:data, pem}} -> {:ok, pem}
|
||||||
|
end
|
||||||
|
|
||||||
|
Port.close(port)
|
||||||
|
|
||||||
|
if Regex.match?(~r/RSA PRIVATE KEY/, pem) do
|
||||||
|
{:ok, pem}
|
||||||
|
else
|
||||||
|
:error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def keys_from_pem(pem) do
|
||||||
|
[private_key_code] = :public_key.pem_decode(pem)
|
||||||
|
private_key = :public_key.pem_entry_decode(private_key_code)
|
||||||
|
{:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} = private_key
|
||||||
|
public_key = {:RSAPublicKey, modulus, exponent}
|
||||||
|
{:ok, private_key, public_key}
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,11 +5,10 @@
|
||||||
defmodule Pleroma.Signature do
|
defmodule Pleroma.Signature do
|
||||||
@behaviour HTTPSignatures.Adapter
|
@behaviour HTTPSignatures.Adapter
|
||||||
|
|
||||||
|
alias Pleroma.Keys
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.Salmon
|
|
||||||
alias Pleroma.Web.WebFinger
|
|
||||||
|
|
||||||
def fetch_public_key(conn) do
|
def fetch_public_key(conn) do
|
||||||
with actor_id <- Utils.get_ap_id(conn.params["actor"]),
|
with actor_id <- Utils.get_ap_id(conn.params["actor"]),
|
||||||
|
@ -33,8 +32,8 @@ def refetch_public_key(conn) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign(%User{} = user, headers) do
|
def sign(%User{} = user, headers) do
|
||||||
with {:ok, %{info: %{keys: keys}}} <- WebFinger.ensure_keys_present(user),
|
with {:ok, %{info: %{keys: keys}}} <- User.ensure_keys_present(user),
|
||||||
{:ok, private_key, _} <- Salmon.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
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule Pleroma.User do
|
||||||
|
|
||||||
alias Comeonin.Pbkdf2
|
alias Comeonin.Pbkdf2
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Keys
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Registration
|
alias Pleroma.Registration
|
||||||
|
@ -1422,4 +1423,24 @@ def get_mascot(%{info: %{mascot: mascot}}) when is_nil(mascot) do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_keys_present(user) do
|
||||||
|
info = user.info
|
||||||
|
|
||||||
|
if info.keys do
|
||||||
|
{:ok, user}
|
||||||
|
else
|
||||||
|
{:ok, pem} = Keys.generate_rsa_pem()
|
||||||
|
|
||||||
|
info_cng =
|
||||||
|
info
|
||||||
|
|> User.Info.set_keys(pem)
|
||||||
|
|
||||||
|
cng =
|
||||||
|
Ecto.Changeset.change(user)
|
||||||
|
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
update_and_set_cache(cng)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,7 +39,7 @@ def relay_active?(conn, _) do
|
||||||
|
|
||||||
def user(conn, %{"nickname" => nickname}) do
|
def user(conn, %{"nickname" => nickname}) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(UserView.render("user.json", %{user: user}))
|
|> json(UserView.render("user.json", %{user: user}))
|
||||||
|
@ -106,7 +106,7 @@ def activity(conn, %{"uuid" => uuid}) do
|
||||||
|
|
||||||
def following(conn, %{"nickname" => nickname, "page" => page}) do
|
def following(conn, %{"nickname" => nickname, "page" => page}) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
{page, _} = Integer.parse(page)
|
{page, _} = Integer.parse(page)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -117,7 +117,7 @@ def following(conn, %{"nickname" => nickname, "page" => page}) do
|
||||||
|
|
||||||
def following(conn, %{"nickname" => nickname}) do
|
def following(conn, %{"nickname" => nickname}) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(UserView.render("following.json", %{user: user}))
|
|> json(UserView.render("following.json", %{user: user}))
|
||||||
|
@ -126,7 +126,7 @@ def following(conn, %{"nickname" => nickname}) do
|
||||||
|
|
||||||
def followers(conn, %{"nickname" => nickname, "page" => page}) do
|
def followers(conn, %{"nickname" => nickname, "page" => page}) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
{page, _} = Integer.parse(page)
|
{page, _} = Integer.parse(page)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -137,7 +137,7 @@ def followers(conn, %{"nickname" => nickname, "page" => page}) do
|
||||||
|
|
||||||
def followers(conn, %{"nickname" => nickname}) do
|
def followers(conn, %{"nickname" => nickname}) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(UserView.render("followers.json", %{user: user}))
|
|> json(UserView.render("followers.json", %{user: user}))
|
||||||
|
@ -146,7 +146,7 @@ def followers(conn, %{"nickname" => nickname}) do
|
||||||
|
|
||||||
def outbox(conn, %{"nickname" => nickname} = params) do
|
def outbox(conn, %{"nickname" => nickname} = params) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(UserView.render("outbox.json", %{user: user, max_id: params["max_id"]}))
|
|> json(UserView.render("outbox.json", %{user: user, max_id: params["max_id"]}))
|
||||||
|
@ -195,7 +195,7 @@ def inbox(conn, params) do
|
||||||
|
|
||||||
def relay(conn, _params) do
|
def relay(conn, _params) do
|
||||||
with %User{} = user <- Relay.get_actor(),
|
with %User{} = user <- Relay.get_actor(),
|
||||||
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
|
{:ok, user} <- User.ensure_keys_present(user) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(UserView.render("user.json", %{user: user}))
|
|> json(UserView.render("user.json", %{user: user}))
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.ActivityPub.UserView do
|
defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
|
|
||||||
|
alias Pleroma.Keys
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
@ -12,8 +13,6 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.Endpoint
|
alias Pleroma.Web.Endpoint
|
||||||
alias Pleroma.Web.Router.Helpers
|
alias Pleroma.Web.Router.Helpers
|
||||||
alias Pleroma.Web.Salmon
|
|
||||||
alias Pleroma.Web.WebFinger
|
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
@ -34,8 +33,8 @@ def render("endpoints.json", _), do: %{}
|
||||||
|
|
||||||
# the instance itself is not a Person, but instead an Application
|
# the instance itself is not a Person, but instead an Application
|
||||||
def render("user.json", %{user: %{nickname: nil} = user}) do
|
def render("user.json", %{user: %{nickname: nil} = user}) do
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
{:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys)
|
{:ok, _, public_key} = Keys.keys_from_pem(user.info.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])
|
||||||
|
|
||||||
|
@ -62,8 +61,8 @@ def render("user.json", %{user: %{nickname: nil} = user}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("user.json", %{user: user}) do
|
def render("user.json", %{user: user}) do
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
{:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys)
|
{:ok, _, public_key} = Keys.keys_from_pem(user.info.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])
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ defmodule Pleroma.Web.Federator do
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.Federator.Publisher
|
alias Pleroma.Web.Federator.Publisher
|
||||||
alias Pleroma.Web.Federator.RetryQueue
|
alias Pleroma.Web.Federator.RetryQueue
|
||||||
alias Pleroma.Web.WebFinger
|
|
||||||
alias Pleroma.Web.Websub
|
alias Pleroma.Web.Websub
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
@ -77,9 +76,8 @@ def perform(:request_subscription, websub) do
|
||||||
def perform(:publish, activity) do
|
def perform(:publish, activity) do
|
||||||
Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end)
|
Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end)
|
||||||
|
|
||||||
with actor when not is_nil(actor) <- User.get_cached_by_ap_id(activity.data["actor"]) do
|
with %User{} = actor <- User.get_cached_by_ap_id(activity.data["actor"]),
|
||||||
{:ok, actor} = WebFinger.ensure_keys_present(actor)
|
{:ok, actor} <- User.ensure_keys_present(actor) do
|
||||||
|
|
||||||
Publisher.publish(actor, activity)
|
Publisher.publish(actor, activity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.Salmon do
|
||||||
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Instances
|
alias Pleroma.Instances
|
||||||
|
alias Pleroma.Keys
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
alias Pleroma.Web.Federator.Publisher
|
alias Pleroma.Web.Federator.Publisher
|
||||||
|
@ -89,45 +90,6 @@ def encode_key({:RSAPublicKey, modulus, exponent}) do
|
||||||
"RSA.#{modulus_enc}.#{exponent_enc}"
|
"RSA.#{modulus_enc}.#{exponent_enc}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Native generation of RSA keys is only available since OTP 20+ and in default build conditions
|
|
||||||
# We try at compile time to generate natively an RSA key otherwise we fallback on the old way.
|
|
||||||
try do
|
|
||||||
_ = :public_key.generate_key({:rsa, 2048, 65_537})
|
|
||||||
|
|
||||||
def generate_rsa_pem do
|
|
||||||
key = :public_key.generate_key({:rsa, 2048, 65_537})
|
|
||||||
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
|
|
||||||
pem = :public_key.pem_encode([entry]) |> String.trim_trailing()
|
|
||||||
{:ok, pem}
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
_ ->
|
|
||||||
def generate_rsa_pem do
|
|
||||||
port = Port.open({:spawn, "openssl genrsa"}, [:binary])
|
|
||||||
|
|
||||||
{:ok, pem} =
|
|
||||||
receive do
|
|
||||||
{^port, {:data, pem}} -> {:ok, pem}
|
|
||||||
end
|
|
||||||
|
|
||||||
Port.close(port)
|
|
||||||
|
|
||||||
if Regex.match?(~r/RSA PRIVATE KEY/, pem) do
|
|
||||||
{:ok, pem}
|
|
||||||
else
|
|
||||||
:error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def keys_from_pem(pem) do
|
|
||||||
[private_key_code] = :public_key.pem_decode(pem)
|
|
||||||
private_key = :public_key.pem_entry_decode(private_key_code)
|
|
||||||
{:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} = private_key
|
|
||||||
public_key = {:RSAPublicKey, modulus, exponent}
|
|
||||||
{:ok, private_key, public_key}
|
|
||||||
end
|
|
||||||
|
|
||||||
def encode(private_key, doc) do
|
def encode(private_key, doc) do
|
||||||
type = "application/atom+xml"
|
type = "application/atom+xml"
|
||||||
encoding = "base64url"
|
encoding = "base64url"
|
||||||
|
@ -227,7 +189,7 @@ def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity
|
||||||
|> :xmerl.export_simple(:xmerl_xml)
|
|> :xmerl.export_simple(:xmerl_xml)
|
||||||
|> to_string
|
|> to_string
|
||||||
|
|
||||||
{:ok, private, _} = keys_from_pem(keys)
|
{:ok, private, _} = Keys.keys_from_pem(keys)
|
||||||
{:ok, feed} = encode(private, feed)
|
{:ok, feed} = encode(private, feed)
|
||||||
|
|
||||||
remote_users = remote_users(activity)
|
remote_users = remote_users(activity)
|
||||||
|
@ -253,7 +215,7 @@ def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity
|
||||||
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_from_pem(user.info.keys)
|
{:ok, _private, public} = Keys.keys_from_pem(user.info.keys)
|
||||||
magic_key = encode_key(public)
|
magic_key = encode_key(public)
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.Web.WebFinger do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.Federator.Publisher
|
alias Pleroma.Web.Federator.Publisher
|
||||||
alias Pleroma.Web.Salmon
|
|
||||||
alias Pleroma.Web.XML
|
alias Pleroma.Web.XML
|
||||||
alias Pleroma.XmlBuilder
|
alias Pleroma.XmlBuilder
|
||||||
require Jason
|
require Jason
|
||||||
|
@ -61,7 +60,7 @@ defp gather_links(%User{} = user) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def represent_user(user, "JSON") do
|
def represent_user(user, "JSON") do
|
||||||
{:ok, user} = ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
"subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}",
|
"subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}",
|
||||||
|
@ -71,7 +70,7 @@ def represent_user(user, "JSON") do
|
||||||
end
|
end
|
||||||
|
|
||||||
def represent_user(user, "XML") do
|
def represent_user(user, "XML") do
|
||||||
{:ok, user} = ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
links =
|
links =
|
||||||
gather_links(user)
|
gather_links(user)
|
||||||
|
@ -88,27 +87,6 @@ def represent_user(user, "XML") do
|
||||||
|> XmlBuilder.to_doc()
|
|> XmlBuilder.to_doc()
|
||||||
end
|
end
|
||||||
|
|
||||||
# This seems a better fit in Salmon
|
|
||||||
def ensure_keys_present(user) do
|
|
||||||
info = user.info
|
|
||||||
|
|
||||||
if info.keys do
|
|
||||||
{:ok, user}
|
|
||||||
else
|
|
||||||
{:ok, pem} = Salmon.generate_rsa_pem()
|
|
||||||
|
|
||||||
info_cng =
|
|
||||||
info
|
|
||||||
|> User.Info.set_keys(pem)
|
|
||||||
|
|
||||||
cng =
|
|
||||||
Ecto.Changeset.change(user)
|
|
||||||
|> Ecto.Changeset.put_embed(:info, info_cng)
|
|
||||||
|
|
||||||
User.update_and_set_cache(cng)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp get_magic_key(magic_key) do
|
defp get_magic_key(magic_key) do
|
||||||
"data:application/magic-public-key," <> magic_key = magic_key
|
"data:application/magic-public-key," <> magic_key = magic_key
|
||||||
{:ok, magic_key}
|
{:ok, magic_key}
|
||||||
|
|
20
test/keys_test.exs
Normal file
20
test/keys_test.exs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
defmodule Pleroma.KeysTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
|
||||||
|
alias Pleroma.Keys
|
||||||
|
|
||||||
|
test "generates an RSA private key pem" do
|
||||||
|
{:ok, key} = Keys.generate_rsa_pem()
|
||||||
|
|
||||||
|
assert is_binary(key)
|
||||||
|
assert Regex.match?(~r/RSA/, key)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns a public and private key from a pem" do
|
||||||
|
pem = File.read!("test/fixtures/private_key.pem")
|
||||||
|
{:ok, private, public} = Keys.keys_from_pem(pem)
|
||||||
|
|
||||||
|
assert elem(private, 0) == :RSAPrivateKey
|
||||||
|
assert elem(public, 0) == :RSAPublicKey
|
||||||
|
end
|
||||||
|
end
|
|
@ -1251,4 +1251,19 @@ test "if user is unconfirmed" do
|
||||||
refute user.info.confirmation_token
|
refute user.info.confirmation_token
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "ensure_keys_present" do
|
||||||
|
test "it creates keys for a user and stores them in info" do
|
||||||
|
user = insert(:user)
|
||||||
|
refute is_binary(user.info.keys)
|
||||||
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
assert is_binary(user.info.keys)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it doesn't create keys if there already are some" do
|
||||||
|
user = insert(:user, %{info: %{keys: "xxx"}})
|
||||||
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
assert user.info.keys == "xxx"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1005,7 +1005,7 @@ test "it filters broken threads" do
|
||||||
describe "update" do
|
describe "update" do
|
||||||
test "it creates an update activity with the new user data" do
|
test "it creates an update activity with the new user data" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
user_data = Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})
|
user_data = Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})
|
||||||
|
|
||||||
{:ok, update} =
|
{:ok, update} =
|
||||||
|
|
|
@ -2,11 +2,12 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.UserView
|
alias Pleroma.Web.ActivityPub.UserView
|
||||||
|
|
||||||
test "Renders a user, including the public key" do
|
test "Renders a user, including the public key" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
result = UserView.render("user.json", %{user: user})
|
result = UserView.render("user.json", %{user: user})
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ test "Renders a user, including the public key" do
|
||||||
|
|
||||||
test "Does not add an avatar image if the user hasn't set one" do
|
test "Does not add an avatar image if the user hasn't set one" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
result = UserView.render("user.json", %{user: user})
|
result = UserView.render("user.json", %{user: user})
|
||||||
refute result["icon"]
|
refute result["icon"]
|
||||||
|
@ -32,7 +33,7 @@ test "Does not add an avatar image if the user hasn't set one" do
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
result = UserView.render("user.json", %{user: user})
|
result = UserView.render("user.json", %{user: user})
|
||||||
assert result["icon"]["url"] == "https://someurl"
|
assert result["icon"]["url"] == "https://someurl"
|
||||||
|
@ -42,7 +43,7 @@ test "Does not add an avatar image if the user hasn't set one" do
|
||||||
describe "endpoints" do
|
describe "endpoints" do
|
||||||
test "local users have a usable endpoints structure" do
|
test "local users have a usable endpoints structure" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
result = UserView.render("user.json", %{user: user})
|
result = UserView.render("user.json", %{user: user})
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ test "local users have a usable endpoints structure" do
|
||||||
|
|
||||||
test "remote users have an empty endpoints structure" do
|
test "remote users have an empty endpoints structure" do
|
||||||
user = insert(:user, local: false)
|
user = insert(:user, local: false)
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
result = UserView.render("user.json", %{user: user})
|
result = UserView.render("user.json", %{user: user})
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ test "remote users have an empty endpoints structure" do
|
||||||
|
|
||||||
test "instance users do not expose oAuth endpoints" do
|
test "instance users do not expose oAuth endpoints" do
|
||||||
user = insert(:user, nickname: nil, local: true)
|
user = insert(:user, nickname: nil, local: true)
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
result = UserView.render("user.json", %{user: user})
|
result = UserView.render("user.json", %{user: user})
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.Salmon.SalmonTest do
|
defmodule Pleroma.Web.Salmon.SalmonTest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Keys
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.Federator.Publisher
|
alias Pleroma.Web.Federator.Publisher
|
||||||
|
@ -34,12 +35,6 @@ test "errors on wrong magic key" do
|
||||||
assert Salmon.decode_and_validate(@wrong_magickey, salmon) == :error
|
assert Salmon.decode_and_validate(@wrong_magickey, salmon) == :error
|
||||||
end
|
end
|
||||||
|
|
||||||
test "generates an RSA private key pem" do
|
|
||||||
{:ok, key} = Salmon.generate_rsa_pem()
|
|
||||||
assert is_binary(key)
|
|
||||||
assert Regex.match?(~r/RSA/, key)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it encodes a magic key from a public key" do
|
test "it encodes a magic key from a public key" do
|
||||||
key = Salmon.decode_key(@magickey)
|
key = Salmon.decode_key(@magickey)
|
||||||
magic_key = Salmon.encode_key(key)
|
magic_key = Salmon.encode_key(key)
|
||||||
|
@ -51,18 +46,10 @@ test "it decodes a friendica public key" do
|
||||||
_key = Salmon.decode_key(@magickey_friendica)
|
_key = Salmon.decode_key(@magickey_friendica)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns a public and private key from a pem" do
|
|
||||||
pem = File.read!("test/fixtures/private_key.pem")
|
|
||||||
{:ok, private, public} = Salmon.keys_from_pem(pem)
|
|
||||||
|
|
||||||
assert elem(private, 0) == :RSAPrivateKey
|
|
||||||
assert elem(public, 0) == :RSAPublicKey
|
|
||||||
end
|
|
||||||
|
|
||||||
test "encodes an xml payload with a private key" do
|
test "encodes an xml payload with a private key" do
|
||||||
doc = File.read!("test/fixtures/incoming_note_activity.xml")
|
doc = File.read!("test/fixtures/incoming_note_activity.xml")
|
||||||
pem = File.read!("test/fixtures/private_key.pem")
|
pem = File.read!("test/fixtures/private_key.pem")
|
||||||
{:ok, private, public} = Salmon.keys_from_pem(pem)
|
{:ok, private, public} = Keys.keys_from_pem(pem)
|
||||||
|
|
||||||
# Let's try a roundtrip.
|
# Let's try a roundtrip.
|
||||||
{:ok, salmon} = Salmon.encode(private, doc)
|
{:ok, salmon} = Salmon.encode(private, doc)
|
||||||
|
@ -105,7 +92,7 @@ test "it gets a magic key" do
|
||||||
|
|
||||||
{:ok, activity} = Repo.insert(%Activity{data: activity_data, recipients: activity_data["to"]})
|
{:ok, activity} = Repo.insert(%Activity{data: activity_data, recipients: activity_data["to"]})
|
||||||
user = User.get_cached_by_ap_id(activity.data["actor"])
|
user = User.get_cached_by_ap_id(activity.data["actor"])
|
||||||
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
|
|
||||||
Salmon.publish(user, activity)
|
Salmon.publish(user, activity)
|
||||||
|
|
||||||
|
|
|
@ -105,19 +105,4 @@ test "it gets the xrd endpoint for statusnet" do
|
||||||
assert template == "http://status.alpicola.com/main/xrd?uri={uri}"
|
assert template == "http://status.alpicola.com/main/xrd?uri={uri}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "ensure_keys_present" do
|
|
||||||
test "it creates keys for a user and stores them in info" do
|
|
||||||
user = insert(:user)
|
|
||||||
refute is_binary(user.info.keys)
|
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
|
||||||
assert is_binary(user.info.keys)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it doesn't create keys if there already are some" do
|
|
||||||
user = insert(:user, %{info: %{keys: "xxx"}})
|
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
|
||||||
assert user.info.keys == "xxx"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue