Merge branch 'fork' into backend-new
This commit is contained in:
commit
9d6d528bcb
16 changed files with 149 additions and 16 deletions
|
@ -1,4 +1,4 @@
|
||||||
`pl` is my personal fork of Pleroma that I use on my single-user instance.
|
Pleroma by mkljczk is a fork of Pleroma I'm developing for personal use.
|
||||||
|
|
||||||
Added features:
|
Added features:
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ Features not authored by me:
|
||||||
There might be more, it's hard to keep track of it. I'm trying to keep the fork as close to upstream and I hope the list will eventually get much shorter.
|
There might be more, it's hard to keep track of it. I'm trying to keep the fork as close to upstream and I hope the list will eventually get much shorter.
|
||||||
|
|
||||||
**DISCLAIMER:**
|
**DISCLAIMER:**
|
||||||
Although `pl` *just works* for me, I cannot guarantee that it'll work well for you. There might be bugs I simply don't care about or I might decide to abandon the project one day.
|
Although Pleroma by mkljczk *just works* for me, I cannot guarantee that it'll work well for you. There might be bugs I simply don't care about or I might decide to abandon the project one day.
|
||||||
|
|
||||||
It should be possible to migrate from Pleroma or Rebased to `pl` without issues. It is recommended to use `pl` with [`pl-fe`](https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-fe) for full feature compatibility, but pleroma-fe and other frontends work fine too.
|
It should be possible to migrate from Pleroma or Rebased to Pleroma by mkljczk without issues. It is recommended to use Pleroma by mkljczk with [`pl-fe`](https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-fe) for full feature compatibility, but pleroma-fe and other frontends work fine too.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
1
changelog.d/debian-install-improve.skip
Normal file
1
changelog.d/debian-install-improve.skip
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fixed a formatting issue that had a required commend embedded in a textblock, and change the language to make it a bit more idiomatic.
|
|
@ -747,7 +747,8 @@
|
||||||
events_actions: {10_000, 15},
|
events_actions: {10_000, 15},
|
||||||
password_reset: {1_800_000, 5},
|
password_reset: {1_800_000, 5},
|
||||||
account_confirmation_resend: {8_640_000, 5},
|
account_confirmation_resend: {8_640_000, 5},
|
||||||
ap_routes: {60_000, 15}
|
ap_routes: {60_000, 15},
|
||||||
|
bites: {10_000, 10}
|
||||||
|
|
||||||
config :pleroma, Pleroma.Workers.PurgeExpiredActivity, enabled: true, min_lifetime: 600
|
config :pleroma, Pleroma.Workers.PurgeExpiredActivity, enabled: true, min_lifetime: 600
|
||||||
|
|
||||||
|
|
|
@ -69,12 +69,18 @@ cd /opt/pleroma
|
||||||
sudo -Hu pleroma mix deps.get
|
sudo -Hu pleroma mix deps.get
|
||||||
```
|
```
|
||||||
|
|
||||||
* Generate the configuration: `sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
|
* Generate the configuration:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
|
||||||
|
```
|
||||||
|
|
||||||
|
* During this process:
|
||||||
* Answer with `yes` if it asks you to install `rebar3`.
|
* Answer with `yes` if it asks you to install `rebar3`.
|
||||||
* This may take some time, because parts of pleroma get compiled first.
|
* This may take some time, because parts of pleroma get compiled first.
|
||||||
* After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
|
* After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
|
||||||
|
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for production instances, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
|
|
|
@ -116,7 +116,10 @@ defmodule Pleroma.Constants do
|
||||||
"Announce",
|
"Announce",
|
||||||
"Undo",
|
"Undo",
|
||||||
"Flag",
|
"Flag",
|
||||||
"EmojiReact"
|
"EmojiReact",
|
||||||
|
"Bite",
|
||||||
|
"Join",
|
||||||
|
"Leave"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Object.Updater do
|
defmodule Pleroma.Object.Updater do
|
||||||
require Pleroma.Constants
|
require Pleroma.Constants
|
||||||
|
|
||||||
|
alias Pleroma.Maps
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Workers.EventReminderWorker
|
alias Pleroma.Workers.EventReminderWorker
|
||||||
|
@ -116,6 +117,7 @@ defp maybe_update_poll(to_be_updated, updated_object) do
|
||||||
# Choices are the same, but counts are different
|
# Choices are the same, but counts are different
|
||||||
to_be_updated
|
to_be_updated
|
||||||
|> Map.put(key, updated_object[key])
|
|> Map.put(key, updated_object[key])
|
||||||
|
|> Maps.put_if_present("votersCount", updated_object["votersCount"])
|
||||||
else
|
else
|
||||||
# Choices (or vote type) have changed, do not allow this
|
# Choices (or vote type) have changed, do not allow this
|
||||||
_ -> to_be_updated
|
_ -> to_be_updated
|
||||||
|
|
|
@ -38,7 +38,7 @@ defp validate_data(cng) do
|
||||||
|> validate_required([:id, :type, :actor, :to, :target])
|
|> validate_required([:id, :type, :actor, :to, :target])
|
||||||
|> validate_inclusion(:type, ["Bite"])
|
|> validate_inclusion(:type, ["Bite"])
|
||||||
|> validate_actor_presence()
|
|> validate_actor_presence()
|
||||||
|> validate_actor_presence(field_name: :target)
|
|> validate_object_or_user_presence(field_name: :target)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cast_and_validate(data) do
|
def cast_and_validate(data) do
|
||||||
|
|
|
@ -78,7 +78,7 @@ def changeset(struct, data, meta) do
|
||||||
defp validate_data(data_cng, _meta) do
|
defp validate_data(data_cng, _meta) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Event"])
|
|> validate_inclusion(:type, ["Event"])
|
||||||
|> validate_inclusion(:joinMode, ~w[free restricted invite])
|
|> validate_inclusion(:joinMode, ~w[free restricted invite external])
|
||||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||||
|
|
|
@ -498,6 +498,32 @@ def handle_incoming(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_incoming(
|
||||||
|
%{"type" => "Bite", "target" => target_id} = data,
|
||||||
|
_options
|
||||||
|
) do
|
||||||
|
target_id =
|
||||||
|
cond do
|
||||||
|
%User{ap_id: actor_id} = User.get_by_ap_id(target_id) ->
|
||||||
|
actor_id
|
||||||
|
|
||||||
|
%Object{data: data} = Object.get_by_ap_id(target_id) ->
|
||||||
|
data["actor"] || data["attributedTo"]
|
||||||
|
|
||||||
|
true ->
|
||||||
|
target_id
|
||||||
|
end
|
||||||
|
|
||||||
|
with data = Map.put(data, "target", target_id),
|
||||||
|
:ok <- ObjectValidator.fetch_actor_and_object(data),
|
||||||
|
{:ok, activity, _meta} <-
|
||||||
|
Pipeline.common_pipeline(data, local: false) do
|
||||||
|
{:ok, activity}
|
||||||
|
else
|
||||||
|
e -> {:error, e}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def handle_incoming(%{"type" => type} = data, _options)
|
def handle_incoming(%{"type" => type} = data, _options)
|
||||||
when type in ~w{Like EmojiReact Announce Add Remove} do
|
when type in ~w{Like EmojiReact Announce Add Remove} do
|
||||||
with :ok <- ObjectValidator.fetch_actor_and_object(data),
|
with :ok <- ObjectValidator.fetch_actor_and_object(data),
|
||||||
|
|
|
@ -1070,6 +1070,7 @@ def fetch_latest_bite(
|
||||||
|> maybe_exclude_activity_id(exclude_activity)
|
|> maybe_exclude_activity_id(exclude_activity)
|
||||||
|> Activity.Queries.by_object_id(bitten_ap_id)
|
|> Activity.Queries.by_object_id(bitten_ap_id)
|
||||||
|> order_by([activity], fragment("? desc nulls last", activity.id))
|
|> order_by([activity], fragment("? desc nulls last", activity.id))
|
||||||
|
|> exclude_rejected()
|
||||||
|> limit(1)
|
|> limit(1)
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
@ -1080,4 +1081,14 @@ defp maybe_exclude_activity_id(query, %Activity{id: activity_id}) do
|
||||||
query
|
query
|
||||||
|> where([a], a.id != ^activity_id)
|
|> where([a], a.id != ^activity_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp exclude_rejected(query) do
|
||||||
|
rejected_activities =
|
||||||
|
"Reject"
|
||||||
|
|> Activity.Queries.by_type()
|
||||||
|
|> select([a], fragment("?->>'object'", a.data))
|
||||||
|
|
||||||
|
query
|
||||||
|
|> where([a], fragment("?->>'id'", a.data) not in subquery(rejected_activities))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,14 +9,13 @@ defmodule Pleroma.Web.MastodonAPI.BiteController do
|
||||||
|
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||||
# alias Pleroma.Web.Plugs.RateLimiter
|
alias Pleroma.Web.Plugs.RateLimiter
|
||||||
|
|
||||||
plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
|
plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
|
||||||
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write:bite"]} when action == :bite)
|
plug(OAuthScopesPlug, %{scopes: ["write:bites"]} when action == :bite)
|
||||||
|
|
||||||
# plug(RateLimiter, [name: :relations_actions] when action in @relationship_actions)
|
plug(RateLimiter, name: :bites)
|
||||||
# plug(RateLimiter, [name: :app_account_creation] when action == :create)
|
|
||||||
|
|
||||||
plug(:assign_account_by_id)
|
plug(:assign_account_by_id)
|
||||||
|
|
||||||
|
|
6
mix.exs
6
mix.exs
|
@ -20,10 +20,10 @@ def project do
|
||||||
deps: deps(),
|
deps: deps(),
|
||||||
test_coverage: [tool: :covertool, summary: true],
|
test_coverage: [tool: :covertool, summary: true],
|
||||||
# Docs
|
# Docs
|
||||||
homepage_url: "https://github.com/mkljczk/pleroma",
|
homepage_url: "https://github.com/mkljczk/pl",
|
||||||
source_url: "https://github.com/mkljczk/pleroma",
|
source_url: "https://github.com/mkljczk/pl",
|
||||||
docs: [
|
docs: [
|
||||||
source_url_pattern: "https://github.com/mkljczk/pleroma/blob/develop/%{path}#L%{line}",
|
source_url_pattern: "https://github.com/mkljczk/pl/blob/develop/%{path}#L%{line}",
|
||||||
logo: "priv/static/images/logo.png",
|
logo: "priv/static/images/logo.png",
|
||||||
extras: ["README.md", "CHANGELOG.md"] ++ Path.wildcard("docs/**/*.md"),
|
extras: ["README.md", "CHANGELOG.md"] ++ Path.wildcard("docs/**/*.md"),
|
||||||
groups_for_extras: [
|
groups_for_extras: [
|
||||||
|
|
Binary file not shown.
|
@ -44,6 +44,7 @@
|
||||||
"formerRepresentations": "litepub:formerRepresentations",
|
"formerRepresentations": "litepub:formerRepresentations",
|
||||||
"sm": "http://smithereen.software/ns#",
|
"sm": "http://smithereen.software/ns#",
|
||||||
"nonAnonymous": "sm:nonAnonymous",
|
"nonAnonymous": "sm:nonAnonymous",
|
||||||
|
<<<<<<< HEAD
|
||||||
"votersCount": "toot:votersCount",
|
"votersCount": "toot:votersCount",
|
||||||
"mz": "https://joinmobilizon.org/ns#",
|
"mz": "https://joinmobilizon.org/ns#",
|
||||||
"joinMode": {
|
"joinMode": {
|
||||||
|
@ -67,6 +68,8 @@
|
||||||
"@id": "schema:location",
|
"@id": "schema:location",
|
||||||
"@type": "schema:Place"
|
"@type": "schema:Place"
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> bites-pleroma
|
||||||
"Bite": "https://ns.mia.jetzt/as#Bite"
|
"Bite": "https://ns.mia.jetzt/as#Bite"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ActivityPub.ObjectValidators.BiteValidationTest do
|
||||||
|
use Pleroma.DataCase, async: true
|
||||||
|
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidators.BiteValidator
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
describe "bites" do
|
||||||
|
setup do
|
||||||
|
biting = insert(:user)
|
||||||
|
bitten = insert(:user)
|
||||||
|
|
||||||
|
valid_bite = %{
|
||||||
|
"id" => Utils.generate_activity_id(),
|
||||||
|
"type" => "Bite",
|
||||||
|
"actor" => biting.ap_id,
|
||||||
|
"target" => bitten.ap_id,
|
||||||
|
"to" => [bitten.ap_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
%{valid_bite: valid_bite, biting: biting, bitten: bitten}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns ok when called in the ObjectValidator", %{valid_bite: valid_bite} do
|
||||||
|
{:ok, object, _meta} = ObjectValidator.validate(valid_bite, [])
|
||||||
|
|
||||||
|
assert "id" in Map.keys(object)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "is valid for a valid object", %{valid_bite: valid_bite} do
|
||||||
|
assert BiteValidator.cast_and_validate(valid_bite).valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "is valid when biting an object", %{valid_bite: valid_bite, bitten: bitten} do
|
||||||
|
{:ok, activity} = CommonAPI.post(bitten, %{status: "uguu"})
|
||||||
|
|
||||||
|
valid_bite =
|
||||||
|
valid_bite
|
||||||
|
|> Map.put("target", activity.data["object"])
|
||||||
|
|
||||||
|
assert BiteValidator.cast_and_validate(valid_bite).valid?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.MastodonAPI.BiteControllerTest do
|
||||||
|
use Pleroma.Web.ConnCase
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
setup do: oauth_access(["write:bites"])
|
||||||
|
|
||||||
|
test "bites a user", %{conn: conn} do
|
||||||
|
%{id: bitten_id} = insert(:user)
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> post("/api/v1/bite?id=#{bitten_id}")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
assert response == %{}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "self harm is not supported", %{conn: conn, user: %{id: self_id}} do
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> post("/api/v1/bite?id=#{self_id}")
|
||||||
|
|> json_response_and_validate_schema(400)
|
||||||
|
|
||||||
|
assert %{"error" => "Can not bite yourself"} = response
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue