PieFed and Mbin take reports from the reporter too
Both speak Lemmy's shapes and joined the servers that get reports in that shape only once the pasture showed each keeps one with its reason. By their source, PieFed dropped the instance actor's report (it makes a user only of a Person or a Service) and Mbin kept it without the persona's words (it reads the reason from `summary` alone). With them in `ServiceReportTakers`, each keeps the reports of a thread and of a comment from "Reports from privapub.test" with alice's words, and none names her (piefed.sh and mbin.sh, 65 checks with the full sweep's 876). A report of a PieFed account alone, which PieFed would take from the reporter, is not sent yet; INTEROP says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
f66c280b0b
commit
f105d1f7ea
9 files changed
+72
-24
No files matched your search
@@ -22,8 +22,8 @@ Its defining idea: **one private login owns several public personas.**
|
|||||||
- **`DmGroup` is a direct-message conversation.**
|
- **`DmGroup` is a direct-message conversation.**
|
||||||
- **`privapub` is the instance actor** (type Application). It signs fetches no persona should be tied to.
|
- **`privapub` is the instance actor** (type Application). It signs fetches no persona should be tied to.
|
||||||
- **`privapub_reports` is the reporter** (type Service, `LocalActorKind.Reporter`). It carries reports to Lemmy, which
|
- **`privapub_reports` is the reporter** (type Service, `LocalActorKind.Reporter`). It carries reports to Lemmy, which
|
||||||
takes none from an Application, and names nobody. Both are server actors (`LocalActor.IsServerActor`): never followed,
|
takes none from an Application, and to PieFed and Mbin, and names nobody. Both are server actors
|
||||||
mentioned or shown as accounts.
|
(`LocalActor.IsServerActor`): never followed, mentioned or shown as accounts.
|
||||||
|
|
||||||
Privacy features in the model:
|
Privacy features in the model:
|
||||||
- location-ranged posts (`Post.Location`, `RangeKm`), to become local-only and never federated;
|
- location-ranged posts (`Post.Location`, `RangeKm`), to become local-only and never federated;
|
||||||
@@ -333,7 +333,7 @@ group www-data and reaches the private mongod; `sudo -u www-data` works too.
|
|||||||
- **Per-avatar state stays per avatar:** blocks, mutes, notifications, follows. Nothing may relate sibling avatars.
|
- **Per-avatar state stays per avatar:** blocks, mutes, notifications, follows. Nothing may relate sibling avatars.
|
||||||
- **Blocks federate** (owner decision, 2026-10-01): a block is sent as `Block` from the blocking avatar, an unblock as
|
- **Blocks federate** (owner decision, 2026-10-01): a block is sent as `Block` from the blocking avatar, an unblock as
|
||||||
`Undo{Block}`. Reports still leave as `Flag` from the server's own actors (the instance actor, or the reporter for
|
`Undo{Block}`. Reports still leave as `Flag` from the server's own actors (the instance actor, or the reporter for
|
||||||
Lemmy's communities), never from the reporting avatar.
|
communities on Lemmy, PieFed and Mbin), never from the reporting avatar.
|
||||||
- **What PrivaPub reveals is the owner's call.** Previews, blocks, website authorship, views, bridging and reactions were
|
- **What PrivaPub reveals is the owner's call.** Previews, blocks, website authorship, views, bridging and reactions were
|
||||||
decided in `docs/ROADMAP.md` ("Owner decisions on what PrivaPub reveals"). Anything new that tells another server
|
decided in `docs/ROADMAP.md` ("Owner decisions on what PrivaPub reveals"). Anything new that tells another server
|
||||||
something about an avatar gets the same treatment: ask, then record it there.
|
something about an avatar gets the same treatment: ask, then record it there.
|
||||||
|
|||||||
+10
-7
@@ -133,9 +133,9 @@ The names are the project's own and are stable; resolve actors through WebFinger
|
|||||||
is used to read another server's content. It also answers at the server's root (`/`) for a request that asks for
|
is used to read another server's content. It also answers at the server's root (`/`) for a request that asks for
|
||||||
ActivityPub, as Lemmy's site actor does: PieFed sends a community's announces to the inbox of the Application at a
|
ActivityPub, as Lemmy's site actor does: PieFed sends a community's announces to the inbox of the Application at a
|
||||||
peer's root, and to `/inbox` when there is none.
|
peer's root, and to `/inbox` when there is none.
|
||||||
- The reporter is `/peasants/privapub_reports` (type `Service`, "Reports from <host>"), one for the whole server with its
|
- The reporter is `/peasants/privapub_reports` (type `Service`, "Reports from <host>"), one for the whole server with
|
||||||
own key. It sends the reports Lemmy takes only from a person or a service (see **Reports** below) and does nothing
|
its own key. It sends the reports Lemmy, PieFed and Mbin take in Lemmy's shape (see **Reports** below) and does
|
||||||
else: nobody follows or mentions it, the Mastodon API has no account for it, and it has no page.
|
nothing else: nobody follows or mentions it, the Mastodon API has no account for it, and it has no page.
|
||||||
|
|
||||||
## Groups
|
## Groups
|
||||||
|
|
||||||
@@ -231,12 +231,15 @@ persona's posts passed on to its followers. A deleted post answers 410 with a `T
|
|||||||
- **Reports** are sent as `Flag`, never by the reporting account and never naming it.
|
- **Reports** are sent as `Flag`, never by the reporting account and never naming it.
|
||||||
- To the reported account's server: from the instance actor, with the account and the posts as `object` and the
|
- To the reported account's server: from the instance actor, with the account and the posts as `object` and the
|
||||||
persona's words in `content`.
|
persona's words in `content`.
|
||||||
- To a community on a server whose NodeInfo names Lemmy (owner decision 2026-10-06, the second place PrivaPub decides
|
- To a community on a server whose NodeInfo names Lemmy, PieFed or Mbin (owner decision 2026-10-06, the second place
|
||||||
by a server's software): one `Flag` per reported post or comment that was made in that community (its own
|
PrivaPub decides by a server's software; PieFed and Mbin once the pasture showed each keeps such a report with its
|
||||||
|
reason): one `Flag` per reported post or comment that was made in that community (its own
|
||||||
`audience`, else its thread's), from the reporter, `to` the community, the post alone as `object`, the words (or,
|
`audience`, else its thread's), from the reporter, `to` the community, the post alone as `object`, the words (or,
|
||||||
with none, the category) in `summary` and `content`, sent to the community's inbox. Lemmy refuses a Flag from an
|
with none, the category) in `summary` and `content`, sent to the community's inbox. Lemmy refuses a Flag from an
|
||||||
`Application`, with no `to` or with no reason. Such a server gets no instance actor's Flag: an account alone, or a
|
`Application`, with no `to` or with no reason; PieFed drops one from an `Application`; Mbin reads the reason from
|
||||||
post outside its communities, is not reported there, since Lemmy takes neither.
|
`summary` alone. Such a server gets no instance actor's Flag: an account alone, or a post outside its communities,
|
||||||
|
is not reported there, since Lemmy takes neither (PieFed would take an account alone from the reporter; that is not
|
||||||
|
sent yet).
|
||||||
- **Direct messages** go out as a `Note` addressed to their recipients, except a message to one account elsewhere that
|
- **Direct messages** go out as a `Note` addressed to their recipients, except a message to one account elsewhere that
|
||||||
writes to us as `ChatMessage`s (Pleroma's type), or whose server takes nothing else: Lemmy before 1.0 and Mbin, as
|
writes to us as `ChatMessage`s (Pleroma's type), or whose server takes nothing else: Lemmy before 1.0 and Mbin, as
|
||||||
their NodeInfo names them (owner decision 2026-10-05, the first place PrivaPub decides by a server's software). That
|
their NodeInfo names them (owner decision 2026-10-05, the first place PrivaPub decides by a server's software). That
|
||||||
|
|||||||
@@ -80,22 +80,27 @@ namespace PrivaPub.Tests.Federation
|
|||||||
.Select(p => (p, JsonNode.Parse(p.Body)!.AsObject()))
|
.Select(p => (p, JsonNode.Parse(p.Body)!.AsObject()))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// a community on a Lemmy (the peer as localhost), and one of its posters there
|
// a community on a Lemmy, or on a server that takes reports as Lemmy does (the peer as localhost), and one of its posters there
|
||||||
async Task<(RemoteActor Community, RemoteActor Poster)> OnLemmy()
|
async Task<(RemoteActor Community, RemoteActor Poster)> OnLemmy(string software = "lemmy")
|
||||||
{
|
{
|
||||||
var community = new RemoteActor(_harness.Peer, "cats", _harness.Peer.B, type: "Group", sharedInbox: true);
|
var community = new RemoteActor(_harness.Peer, "cats", _harness.Peer.B, type: "Group", sharedInbox: true);
|
||||||
var poster = new RemoteActor(_harness.Peer, "poster", _harness.Peer.B);
|
var poster = new RemoteActor(_harness.Peer, "poster", _harness.Peer.B);
|
||||||
await Known(community);
|
await Known(community);
|
||||||
await Known(poster);
|
await Known(poster);
|
||||||
await Runs("localhost", "lemmy");
|
await Runs("localhost", software);
|
||||||
return (community, poster);
|
return (community, poster);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
// PieFed and Mbin take it too, proven live (2026-10-06); NodeInfo names Lemmy as "lemmy" and kbin's heir as "mbin"
|
||||||
public async Task A_post_in_a_lemmy_community_is_reported_to_its_community_by_the_reporter_and_nowhere_else()
|
[Theory]
|
||||||
|
[InlineData("lemmy")]
|
||||||
|
[InlineData("Lemmy")]
|
||||||
|
[InlineData("piefed")]
|
||||||
|
[InlineData("mbin")]
|
||||||
|
public async Task A_post_in_a_lemmy_community_is_reported_to_its_community_by_the_reporter_and_nowhere_else(string software)
|
||||||
{
|
{
|
||||||
var (_, alice) = await _harness.Persona("alice");
|
var (_, alice) = await _harness.Persona("alice");
|
||||||
var (community, poster) = await OnLemmy();
|
var (community, poster) = await OnLemmy(software);
|
||||||
var post = await Held(poster, community.Id);
|
var post = await Held(poster, community.Id);
|
||||||
var reporter = await _harness.Local.GetReporterActor(Token);
|
var reporter = await _harness.Local.GetReporterActor(Token);
|
||||||
|
|
||||||
|
|||||||
@@ -111,8 +111,9 @@ namespace PrivaPub.Domain.Relationships
|
|||||||
// The second place PrivaPub decides by a server's software (owner decision 2026-10-06): Lemmy takes a report only from a
|
// The second place PrivaPub decides by a server's software (owner decision 2026-10-06): Lemmy takes a report only from a
|
||||||
// person or a service, about one post or comment, addressed to its community, so a report for it leaves in that shape
|
// person or a service, about one post or comment, addressed to its community, so a report for it leaves in that shape
|
||||||
// from the server's anonymous reporter; a server joins only once the pasture shows it stores such a report with its
|
// from the server's anonymous reporter; a server joins only once the pasture shows it stores such a report with its
|
||||||
// reason. NodeInfo names it: PieFed and Mbin speak Lemmy's shapes, and nothing else tells them apart.
|
// reason. PieFed (which drops a report from an Application) and Mbin (which reads the reason from summary alone) did on
|
||||||
static readonly HashSet<string> ServiceReportTakers = new(StringComparer.Ordinal) { "lemmy" };
|
// 2026-10-06. NodeInfo names them: they speak Lemmy's shapes, and nothing else tells them apart.
|
||||||
|
static readonly HashSet<string> ServiceReportTakers = new(StringComparer.Ordinal) { "lemmy", "piefed", "mbin" };
|
||||||
|
|
||||||
static async Task<bool> TakesServiceReports(string actorUri, CancellationToken token)
|
static async Task<bool> TakesServiceReports(string actorUri, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ namespace PrivaPub.Models.Jobs
|
|||||||
|
|
||||||
public string Software { get; set; }//NodeInfo software.name: for display, never for deciding behaviour, but for two
|
public string Software { get; set; }//NodeInfo software.name: for display, never for deciding behaviour, but for two
|
||||||
//owner decisions: a first private message to Lemmy before 1.0 or Mbin is a ChatMessage (2026-10-05), and a report
|
//owner decisions: a first private message to Lemmy before 1.0 or Mbin is a ChatMessage (2026-10-05), and a report
|
||||||
//to a Lemmy community leaves from the reporter in Lemmy's shape (2026-10-06, ReportService.ServiceReportTakers)
|
//to a community on Lemmy, PieFed or Mbin leaves from the reporter in Lemmy's shape (2026-10-06,
|
||||||
|
//ReportService.ServiceReportTakers)
|
||||||
public string SoftwareVersion { get; set; }
|
public string SoftwareVersion { get; set; }
|
||||||
public string NodeName { get; set; }
|
public string NodeName { get; set; }
|
||||||
public List<string> Protocols { get; set; } = new();
|
public List<string> Protocols { get; set; } = new();
|
||||||
|
|||||||
@@ -630,6 +630,14 @@ What it showed:
|
|||||||
alice's home and her Note becomes a microblog post in it; comments both ways; Mbin's favourite counts as a like and
|
alice's home and her Note becomes a microblog post in it; comments both ways; Mbin's favourite counts as a like and
|
||||||
its upvote as a boost, alice's like and boost count there; alice's first message and mbuser's answer; a moderator's
|
its upvote as a boost, alice's like and boost count there; alice's first message and mbuser's answer; a moderator's
|
||||||
lock, unlock and removal; the unfollow; statistics.
|
lock, unlock and removal; the unfollow; statistics.
|
||||||
|
- **Reports** (owner decision 2026-10-06): both take a report about a post or comment as Lemmy does, so it leaves from
|
||||||
|
the reporter `privapub_reports` (a `Service`), one `Flag` per post, `to` its community
|
||||||
|
(`ReportService.ServiceReportTakers`). The instance actor's report did not serve either, by their source: **PieFed
|
||||||
|
drops a Flag whose actor is an `Application`** (`actor_json_to_model` makes a user only of a Person or a Service), and
|
||||||
|
**Mbin reads the reason from `summary` alone** (`FlagHandler`), so it kept the report without the persona's words.
|
||||||
|
PieFed keeps the first 255 characters of a reason. **Pasture evidence (2026-10-06, `piefed.sh` and `mbin.sh`):** alice's report of a thread
|
||||||
|
and of a comment in it is kept on each, from the reporter, with her words, and no report names her. Not sent yet: a
|
||||||
|
report of a PieFed account alone, which PieFed would take from the reporter (`process_report` on a user).
|
||||||
- **Gaps:**
|
- **Gaps:**
|
||||||
- **P1:** Lemmy's P1 set, W2, and tolerating `source` as a string.
|
- **P1:** Lemmy's P1 set, W2, and tolerating `source` as a string.
|
||||||
- **P2:** galleries; post `Move`; `repliesEnabled`; `nsfl`; flairs; publish `likes`/`shares` totals.
|
- **P2:** galleries; post `Move`; `repliesEnabled`; `nsfl`; flairs; publish `likes`/`shares` totals.
|
||||||
|
|||||||
+5
-5
@@ -275,7 +275,7 @@ and circles (see Owner decisions).
|
|||||||
|---|---|
|
|---|---|
|
||||||
| May a persona join a remote event? | **Yes.** A persona joins and leaves another server's event (`Join`/`Leave`, sent to the event's organiser only). Its participation is public on that server, as on every platform with events. Events that take participants only by invitation or on another site are refused before anything is sent. |
|
| May a persona join a remote event? | **Yes.** A persona joins and leaves another server's event (`Join`/`Leave`, sent to the event's organiser only). Its participation is public on that server, as on every platform with events. Events that take participants only by invitation or on another site are refused before anything is sent. |
|
||||||
| A first private message to Lemmy 0.19 or Mbin (G-0008) | **Decide by the server's software.** Lemmy before 1.0 and Mbin take a private message only as a `ChatMessage` and their actors do not say so, so a direct message to one account on a server whose NodeInfo names one of them goes as a `ChatMessage`: the one exception to "a server's software is for display only". |
|
| A first private message to Lemmy 0.19 or Mbin (G-0008) | **Decide by the server's software.** Lemmy before 1.0 and Mbin take a private message only as a `ChatMessage` and their actors do not say so, so a direct message to one account on a server whose NodeInfo names one of them goes as a `ChatMessage`: the one exception to "a server's software is for display only". |
|
||||||
| Reports to Lemmy (2026-10-06) | **In Lemmy's shape, for Lemmy only.** Lemmy takes a report only from a person or a service, about one post or comment, addressed to its community, so a report of a post in a community on a server whose NodeInfo names Lemmy leaves from an anonymous `Service`, `privapub_reports`, one `Flag` per post: the second exception to "a server's software is for display only". PieFed and Mbin, which speak Lemmy's shapes, join only once the pasture shows each keeps such a report with its reason; every other server keeps the instance actor's report. |
|
| Reports to Lemmy (2026-10-06) | **In Lemmy's shape, for Lemmy only.** Lemmy takes a report only from a person or a service, about one post or comment, addressed to its community, so a report of a post in a community on a server whose NodeInfo names Lemmy leaves from an anonymous `Service`, `privapub_reports`, one `Flag` per post: the second exception to "a server's software is for display only". PieFed and Mbin, which speak Lemmy's shapes, join only once the pasture shows each keeps such a report with its reason (both did the same day; by their source, PieFed drops the instance actor's report and Mbin keeps it without its words); every other server keeps the instance actor's report. |
|
||||||
| An account a persona follows moves | **Move the follow, as Mastodon does.** After a verified `Move` the persona follows the new account (a Follow to its server) and unfollows the old, in the same lists; a mute or a block of the old account carries over. |
|
| An account a persona follows moves | **Move the follow, as Mastodon does.** After a verified `Move` the persona follows the new account (a Follow to its server) and unfollows the old, in the same lists; a mute or a block of the old account carries over. |
|
||||||
| Should PrivaPub pass on replies to a persona's posts? | **Yes, "the fediverse is broken without".** A public or unlisted reply that someone on another server writes to a persona's post goes on to the persona's followers, as Mastodon forwards it: the activity as its author signed it, never to the replier's own server, never for a post that is local-only, in a group or not shown to followers. Its edits and deletion follow the same way. |
|
| Should PrivaPub pass on replies to a persona's posts? | **Yes, "the fediverse is broken without".** A public or unlisted reply that someone on another server writes to a persona's post goes on to the persona's followers, as Mastodon forwards it: the activity as its author signed it, never to the replier's own server, never for a post that is local-only, in a group or not shown to followers. Its edits and deletion follow the same way. |
|
||||||
|
|
||||||
@@ -542,8 +542,8 @@ The first refactor commit is a pure move with namespaces only. Logic changes fol
|
|||||||
- **Blocks and mutes:** per avatar. **Block is not federated**: it sends Reject or Undo Follow instead and drops the
|
- **Blocks and mutes:** per avatar. **Block is not federated**: it sends Reject or Undo Follow instead and drops the
|
||||||
blocked actor's traffic. Domain blocks per account as well.
|
blocked actor's traffic. Domain blocks per account as well.
|
||||||
- **Reports:** inbound Flag becomes a `Report`. Outbound Flag is **sent by the instance actor**, or for a post in a
|
- **Reports:** inbound Flag becomes a `Report`. Outbound Flag is **sent by the instance actor**, or for a post in a
|
||||||
Lemmy community by the reporter `privapub_reports` (2026-10-06), so the reporting persona isn't revealed. Moderator
|
community on Lemmy, PieFed or Mbin by the reporter `privapub_reports` (2026-10-06), so the reporting persona isn't
|
||||||
endpoints on `/clientapi`.
|
revealed. Moderator endpoints on `/clientapi`.
|
||||||
- **Locked accounts:** the follow-request flow.
|
- **Locked accounts:** the follow-request flow.
|
||||||
|
|
||||||
### P4 Groups and privacy features
|
### P4 Groups and privacy features
|
||||||
@@ -665,8 +665,8 @@ it, raw where it doesn't.
|
|||||||
- the outbound shape Lemmy requires;
|
- the outbound shape Lemmy requires;
|
||||||
- communities we host announce to the author's own instance too: **done 2026-10-06** (its server's shared inbox,
|
- communities we host announce to the author's own instance too: **done 2026-10-06** (its server's shared inbox,
|
||||||
whether anyone there follows the community or not: Lemmy keeps its user's post pending until it is announced back);
|
whether anyone there follows the community or not: Lemmy keeps its user's post pending until it is announced back);
|
||||||
- Flags from a `Service`-typed reporter actor: **done 2026-10-06** for Lemmy (owner decision below; `privapub_reports`,
|
- Flags from a `Service`-typed reporter actor: **done 2026-10-06** for Lemmy, PieFed and Mbin (owner decision below;
|
||||||
one Flag per post `to` its community, checked live on 1.0 and 0.19).
|
`privapub_reports`, one Flag per post `to` its community, checked live on Lemmy 1.0 and 0.19, PieFed and Mbin).
|
||||||
- **GoToSocial interaction policies** (**done 2026-10-05**, `InteractionApprovals`): stored and shown as
|
- **GoToSocial interaction policies** (**done 2026-10-05**, `InteractionApprovals`): stored and shown as
|
||||||
`interaction_policy`; `ReplyRequest`/`LikeRequest`/`AnnounceRequest` where approval is needed; `Accept{result}`
|
`interaction_policy`; `ReplyRequest`/`LikeRequest`/`AnnounceRequest` where approval is needed; `Accept{result}`
|
||||||
verified and carried; replies a policy does not let in kept only with an authorization.
|
verified and carried; replies a policy does not let in kept only with an authorization.
|
||||||
|
|||||||
@@ -108,6 +108,21 @@ mb PUT "moderate/entry/$books_thread/lock" >/dev/null
|
|||||||
until_true 45 '[ "$(p_locked)" = "True" ]' && ok "a moderator's lock reaches PrivaPub" || ko "a moderator's lock did not reach PrivaPub"
|
until_true 45 '[ "$(p_locked)" = "True" ]' && ok "a moderator's lock reaches PrivaPub" || ko "a moderator's lock did not reach PrivaPub"
|
||||||
mb PUT "moderate/entry/$books_thread/lock" >/dev/null
|
mb PUT "moderate/entry/$books_thread/lock" >/dev/null
|
||||||
until_true 45 '[ "$(p_locked)" = "False" ]' && ok "a moderator's unlock reaches PrivaPub" || ko "a moderator's unlock did not reach PrivaPub"
|
until_true 45 '[ "$(p_locked)" = "False" ]' && ok "a moderator's unlock reaches PrivaPub" || ko "a moderator's unlock did not reach PrivaPub"
|
||||||
|
echo " reports"
|
||||||
|
# Mbin reads a report's reason from its summary alone (owner decision 2026-10-06): alice's report of mbuser's thread and
|
||||||
|
# comment leaves from PrivaPub's reporter, one Flag each with alice's words, and never names her
|
||||||
|
mb POST "entry/$books_thread/comments" "{\"body\":\"an Mbin comment to report $run\",\"lang\":\"en\"}" >/dev/null
|
||||||
|
mb_comment_on_p() { curl -s -H "$PH" "$P/api/v1/statuses/$books_thread_on_p/context" | j "print(next((s['id'] for s in d['descendants'] if 'an Mbin comment to report $run' in s['content']), ''))"; }
|
||||||
|
until_true 45 '[ -n "$(mb_comment_on_p)" ]' && ok "mbuser's comment to report reaches PrivaPub" || ko "mbuser's comment never reached PrivaPub"
|
||||||
|
mb_author_on_p=$(curl -s -H "$PH" "$P/api/v1/statuses/$books_thread_on_p" | j "print(d['account']['id'])")
|
||||||
|
reason="a pasture report $run"
|
||||||
|
[ "$(p_report "$PH" "$mb_author_on_p" "$reason" "$books_thread_on_p" "$(mb_comment_on_p)")" = "True" ] \
|
||||||
|
&& ok "PrivaPub says alice's report was forwarded" || ko "PrivaPub did not forward alice's report"
|
||||||
|
mb_reports() { mb_sql "select count(*) from report r join \"user\" u on u.id = r.reporting_id where r.reason = '$reason' and u.ap_profile_id = '$P_REPORTER' and r.$1"; }
|
||||||
|
until_true 45 '[ "$(mb_reports "entry_id is not null and r.entry_comment_id is null")" = "1" ]' && ok "Mbin keeps the thread's report from PrivaPub's reporter, with alice's words" || ko "Mbin kept no report of the thread with alice's words"
|
||||||
|
until_true 45 '[ "$(mb_reports "entry_comment_id is not null")" = "1" ]' && ok "Mbin keeps the comment's report from PrivaPub's reporter, with alice's words" || ko "Mbin kept no report of the comment with alice's words"
|
||||||
|
[ "$(mb_sql "select count(*) from report r join \"user\" u on u.id = r.reporting_id where u.ap_profile_id like '%alice_mbin%'")" = "0" ] \
|
||||||
|
&& ok "no report on Mbin names alice" || ko "a report on Mbin names alice"
|
||||||
mb PUT "moderate/entry/$books_thread/trash" >/dev/null
|
mb PUT "moderate/entry/$books_thread/trash" >/dev/null
|
||||||
until_true 45 '[ "$(curl -s -o /dev/null -w "%{http_code}" -H "$PH" "$P/api/v1/statuses/$books_thread_on_p")" = "404" ]' \
|
until_true 45 '[ "$(curl -s -o /dev/null -w "%{http_code}" -H "$PH" "$P/api/v1/statuses/$books_thread_on_p")" = "404" ]' \
|
||||||
&& ok "a moderator's removal reaches PrivaPub" || ko "a moderator's removal did not reach PrivaPub"
|
&& ok "a moderator's removal reaches PrivaPub" || ko "a moderator's removal did not reach PrivaPub"
|
||||||
|
|||||||
@@ -112,6 +112,21 @@ until_true 45 '[ "$(p_locked)" = "True" ]' && ok "a moderator's lock reaches Pri
|
|||||||
&& ok "a reply to the locked thread is refused" || ko "a reply to the locked thread was taken"
|
&& ok "a reply to the locked thread is refused" || ko "a reply to the locked thread was taken"
|
||||||
pf POST post/lock "{\"post_id\":$pies_thread_id,\"locked\":false}" >/dev/null
|
pf POST post/lock "{\"post_id\":$pies_thread_id,\"locked\":false}" >/dev/null
|
||||||
until_true 45 '[ "$(p_locked)" = "False" ]' && ok "a moderator's unlock reaches PrivaPub" || ko "a moderator's unlock did not reach PrivaPub"
|
until_true 45 '[ "$(p_locked)" = "False" ]' && ok "a moderator's unlock reaches PrivaPub" || ko "a moderator's unlock did not reach PrivaPub"
|
||||||
|
echo " reports"
|
||||||
|
# PieFed takes a report only from a person or a service, as Lemmy does (owner decision 2026-10-06): alice's report of
|
||||||
|
# pfuser's thread and comment leaves from PrivaPub's reporter, one Flag each, and never names her
|
||||||
|
pf POST comment "{\"post_id\":$pies_thread_id,\"body\":\"a PieFed comment to report $run\"}" >/dev/null
|
||||||
|
pf_comment_on_p() { curl -s -H "$PH" "$P/api/v1/statuses/$pies_thread_on_p/context" | j "print(next((s['id'] for s in d['descendants'] if 'a PieFed comment to report $run' in s['content']), ''))"; }
|
||||||
|
until_true 45 '[ -n "$(pf_comment_on_p)" ]' && ok "pfuser's comment to report reaches PrivaPub" || ko "pfuser's comment never reached PrivaPub"
|
||||||
|
pf_author_on_p=$(curl -s -H "$PH" "$P/api/v1/statuses/$pies_thread_on_p" | j "print(d['account']['id'])")
|
||||||
|
reason="a pasture report $run"
|
||||||
|
[ "$(p_report "$PH" "$pf_author_on_p" "$reason" "$pies_thread_on_p" "$(pf_comment_on_p)")" = "True" ] \
|
||||||
|
&& ok "PrivaPub says alice's report was forwarded" || ko "PrivaPub did not forward alice's report"
|
||||||
|
pf_reports() { podman exec pasture-postgres psql -U pasture -d piefed -tAc "select count(*) from report r join \"user\" u on u.id = r.reporter_id where r.reasons = '$reason' and u.ap_profile_id = '$P_REPORTER' and r.$1"; }
|
||||||
|
until_true 45 '[ "$(pf_reports "suspect_post_id is not null and r.suspect_post_reply_id is null")" = "1" ]' && ok "PieFed keeps the thread's report from PrivaPub's reporter, with alice's words" || ko "PieFed kept no report of the thread"
|
||||||
|
until_true 45 '[ "$(pf_reports "suspect_post_reply_id is not null")" = "1" ]' && ok "PieFed keeps the comment's report from PrivaPub's reporter, with alice's words" || ko "PieFed kept no report of the comment"
|
||||||
|
[ "$(podman exec pasture-postgres psql -U pasture -d piefed -tAc "select count(*) from report r join \"user\" u on u.id = r.reporter_id where u.ap_profile_id like '%alice_piefed%'")" = "0" ] \
|
||||||
|
&& ok "no report on PieFed names alice" || ko "a report on PieFed names alice"
|
||||||
pf POST post/remove "{\"post_id\":$pies_thread_id,\"removed\":true,\"reason\":\"pasture\"}" >/dev/null
|
pf POST post/remove "{\"post_id\":$pies_thread_id,\"removed\":true,\"reason\":\"pasture\"}" >/dev/null
|
||||||
until_true 45 '[ -z "$(p_home_has "$pf_pies_thread")" ]' && ok "a moderator's removal reaches PrivaPub" || ko "a moderator's removal did not reach PrivaPub"
|
until_true 45 '[ -z "$(p_home_has "$pf_pies_thread")" ]' && ok "a moderator's removal reaches PrivaPub" || ko "a moderator's removal did not reach PrivaPub"
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user