aboutsummaryrefslogtreecommitdiff
path: root/roomserver
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2024-03-22 22:54:29 +0100
committerGitHub <noreply@github.com>2024-03-22 21:54:29 +0000
commitad0a7d09e89fe18c9e2b08f23f5817a5231c6074 (patch)
tree01ae155c112ac01dce299724790a9db8d999994d /roomserver
parent81f73c9f8df6dd3078a93b6ca978ecbb9c95df16 (diff)
Add getting/deleting single event report (#3344)
Based on https://github.com/matrix-org/dendrite/pull/3342 Adds `GET /_synapse/admin/v1/event_reports/{reportID}` and `DELETE /_synapse/admin/v1/event_reports/{reportID}`
Diffstat (limited to 'roomserver')
-rw-r--r--roomserver/api/api.go2
-rw-r--r--roomserver/api/query.go5
-rw-r--r--roomserver/internal/perform/perform_admin.go4
-rw-r--r--roomserver/internal/query/query.go5
-rw-r--r--roomserver/storage/interface.go2
-rw-r--r--roomserver/storage/postgres/reported_events_table.go41
-rw-r--r--roomserver/storage/shared/storage.go68
-rw-r--r--roomserver/storage/sqlite3/reported_events_table.go41
-rw-r--r--roomserver/storage/tables/interface.go6
9 files changed, 174 insertions, 0 deletions
diff --git a/roomserver/api/api.go b/roomserver/api/api.go
index ac4ea5ba..dffb6d47 100644
--- a/roomserver/api/api.go
+++ b/roomserver/api/api.go
@@ -272,6 +272,8 @@ type ClientRoomserverAPI interface {
score int64,
) (int64, error)
QueryAdminEventReports(ctx context.Context, from, limit uint64, backwards bool, userID, roomID string) ([]QueryAdminEventReportsResponse, int64, error)
+ QueryAdminEventReport(ctx context.Context, reportID uint64) (QueryAdminEventReportResponse, error)
+ PerformAdminDeleteEventReport(ctx context.Context, reportID uint64) error
}
type UserRoomserverAPI interface {
diff --git a/roomserver/api/query.go b/roomserver/api/query.go
index 9a7acab9..c4c019f9 100644
--- a/roomserver/api/query.go
+++ b/roomserver/api/query.go
@@ -363,6 +363,11 @@ type QueryAdminEventReportsResponse struct {
ReceivedTS spec.Timestamp `json:"received_ts"`
}
+type QueryAdminEventReportResponse struct {
+ QueryAdminEventReportsResponse
+ EventJSON json.RawMessage `json:"event_json"`
+}
+
// MarshalJSON stringifies the room ID and StateKeyTuple keys so they can be sent over the wire in HTTP API mode.
func (r *QueryBulkStateContentResponse) MarshalJSON() ([]byte, error) {
se := make(map[string]string)
diff --git a/roomserver/internal/perform/perform_admin.go b/roomserver/internal/perform/perform_admin.go
index ae203854..1b881723 100644
--- a/roomserver/internal/perform/perform_admin.go
+++ b/roomserver/internal/perform/perform_admin.go
@@ -354,3 +354,7 @@ func (r *Admin) PerformAdminDownloadState(
return nil
}
+
+func (r *Admin) PerformAdminDeleteEventReport(ctx context.Context, reportID uint64) error {
+ return r.DB.AdminDeleteEventReport(ctx, reportID)
+}
diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go
index b1b11df3..886d0049 100644
--- a/roomserver/internal/query/query.go
+++ b/roomserver/internal/query/query.go
@@ -1109,3 +1109,8 @@ func (r *Queryer) RoomsWithACLs(ctx context.Context) ([]string, error) {
func (r *Queryer) QueryAdminEventReports(ctx context.Context, from uint64, limit uint64, backwards bool, userID, roomID string) ([]api.QueryAdminEventReportsResponse, int64, error) {
return r.DB.QueryAdminEventReports(ctx, from, limit, backwards, userID, roomID)
}
+
+// QueryAdminEventReport returns a single event report.
+func (r *Queryer) QueryAdminEventReport(ctx context.Context, reportID uint64) (api.QueryAdminEventReportResponse, error) {
+ return r.DB.QueryAdminEventReport(ctx, reportID)
+}
diff --git a/roomserver/storage/interface.go b/roomserver/storage/interface.go
index eb169cbb..ab105e6f 100644
--- a/roomserver/storage/interface.go
+++ b/roomserver/storage/interface.go
@@ -196,6 +196,8 @@ type Database interface {
// RoomsWithACLs returns all room IDs for rooms with ACLs
RoomsWithACLs(ctx context.Context) ([]string, error)
QueryAdminEventReports(ctx context.Context, from uint64, limit uint64, backwards bool, userID string, roomID string) ([]api.QueryAdminEventReportsResponse, int64, error)
+ QueryAdminEventReport(ctx context.Context, reportID uint64) (api.QueryAdminEventReportResponse, error)
+ AdminDeleteEventReport(ctx context.Context, reportID uint64) error
}
type UserRoomKeys interface {
diff --git a/roomserver/storage/postgres/reported_events_table.go b/roomserver/storage/postgres/reported_events_table.go
index 70393833..c46f47b3 100644
--- a/roomserver/storage/postgres/reported_events_table.go
+++ b/roomserver/storage/postgres/reported_events_table.go
@@ -75,10 +75,20 @@ OFFSET $3
LIMIT $4
`
+const selectReportedEventSQL = `
+SELECT id, room_nid, event_nid, reporting_user_nid, event_sender_nid, reason, score, received_ts
+FROM roomserver_reported_events
+WHERE id = $1
+`
+
+const deleteReportedEventSQL = `DELETE FROM roomserver_reported_events WHERE id = $1`
+
type reportedEventsStatements struct {
insertReportedEventsStmt *sql.Stmt
selectReportedEventsDescStmt *sql.Stmt
selectReportedEventsAscStmt *sql.Stmt
+ selectReportedEventStmt *sql.Stmt
+ deleteReportedEventStmt *sql.Stmt
}
func CreateReportedEventsTable(db *sql.DB) error {
@@ -93,6 +103,8 @@ func PrepareReportedEventsTable(db *sql.DB) (tables.ReportedEvents, error) {
{&s.insertReportedEventsStmt, insertReportedEventSQL},
{&s.selectReportedEventsDescStmt, selectReportedEventsDescSQL},
{&s.selectReportedEventsAscStmt, selectReportedEventsAscSQL},
+ {&s.selectReportedEventStmt, selectReportedEventSQL},
+ {&s.deleteReportedEventStmt, deleteReportedEventSQL},
}.Prepare(db)
}
@@ -178,3 +190,32 @@ func (r *reportedEventsStatements) SelectReportedEvents(
return result, count, rows.Err()
}
+
+func (r *reportedEventsStatements) SelectReportedEvent(
+ ctx context.Context,
+ txn *sql.Tx,
+ reportID uint64,
+) (api.QueryAdminEventReportResponse, error) {
+ stmt := sqlutil.TxStmt(txn, r.selectReportedEventStmt)
+
+ var row api.QueryAdminEventReportResponse
+ if err := stmt.QueryRowContext(ctx, reportID).Scan(
+ &row.ID,
+ &row.RoomNID,
+ &row.EventNID,
+ &row.ReportingUserNID,
+ &row.SenderNID,
+ &row.Reason,
+ &row.Score,
+ &row.ReceivedTS,
+ ); err != nil {
+ return api.QueryAdminEventReportResponse{}, err
+ }
+ return row, nil
+}
+
+func (r *reportedEventsStatements) DeleteReportedEvent(ctx context.Context, txn *sql.Tx, reportID uint64) error {
+ stmt := sqlutil.TxStmt(txn, r.deleteReportedEventStmt)
+ _, err := stmt.ExecContext(ctx, reportID)
+ return err
+}
diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go
index c8c34907..7b04641b 100644
--- a/roomserver/storage/shared/storage.go
+++ b/roomserver/storage/shared/storage.go
@@ -2040,6 +2040,74 @@ func (d *Database) QueryAdminEventReports(ctx context.Context, from uint64, limi
return reports, count, nil
}
+func (d *Database) QueryAdminEventReport(ctx context.Context, reportID uint64) (api.QueryAdminEventReportResponse, error) {
+
+ report, err := d.ReportedEventsTable.SelectReportedEvent(ctx, nil, reportID)
+ if err != nil {
+ return api.QueryAdminEventReportResponse{}, err
+ }
+
+ // Get a map from EventStateKeyNID to userID
+ userNIDMap, err := d.EventStateKeys(ctx, []types.EventStateKeyNID{report.ReportingUserNID, report.SenderNID})
+ if err != nil {
+ logrus.WithError(err).Error("unable to map userNIDs to userIDs")
+ return report, err
+ }
+
+ roomIDs, err := d.RoomsTable.BulkSelectRoomIDs(ctx, nil, []types.RoomNID{report.RoomNID})
+ if err != nil {
+ return report, err
+ }
+
+ if len(roomIDs) != 1 {
+ return report, fmt.Errorf("expected one roomID, got %d", len(roomIDs))
+ }
+
+ // TODO: replace this with something more efficient, as it loads the entire state snapshot.
+ stateContent, err := d.GetBulkStateContent(ctx, roomIDs, []gomatrixserverlib.StateKeyTuple{
+ {EventType: spec.MRoomName, StateKey: ""},
+ {EventType: spec.MRoomCanonicalAlias, StateKey: ""},
+ }, false)
+ if err != nil {
+ return report, err
+ }
+
+ eventIDMap, err := d.EventIDs(ctx, []types.EventNID{report.EventNID})
+ if err != nil {
+ logrus.WithError(err).Error("unable to map eventNIDs to eventIDs")
+ return report, err
+ }
+ if len(eventIDMap) != 1 {
+ return report, fmt.Errorf("expected %d eventIDs, got %d", 1, len(eventIDMap))
+ }
+
+ eventJSONs, err := d.EventJSONTable.BulkSelectEventJSON(ctx, nil, []types.EventNID{report.EventNID})
+ if err != nil {
+ return report, err
+ }
+ if len(eventJSONs) != 1 {
+ return report, fmt.Errorf("expected %d eventJSONs, got %d", 1, len(eventJSONs))
+ }
+
+ roomName, canonicalAlias := findRoomNameAndCanonicalAlias(stateContent, roomIDs[0])
+
+ report.Sender = userNIDMap[report.SenderNID]
+ report.UserID = userNIDMap[report.ReportingUserNID]
+ report.RoomID = roomIDs[0]
+ report.RoomName = roomName
+ report.CanonicalAlias = canonicalAlias
+ report.EventID = eventIDMap[report.EventNID]
+ report.EventJSON = eventJSONs[0].EventJSON
+
+ return report, nil
+}
+
+func (d *Database) AdminDeleteEventReport(ctx context.Context, reportID uint64) error {
+ return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
+ return d.ReportedEventsTable.DeleteReportedEvent(ctx, txn, reportID)
+ })
+}
+
// findRoomNameAndCanonicalAlias loops over events to find the corresponding room name and canonicalAlias
// for a given roomID.
func findRoomNameAndCanonicalAlias(events []tables.StrippedEvent, roomID string) (name, canonicalAlias string) {
diff --git a/roomserver/storage/sqlite3/reported_events_table.go b/roomserver/storage/sqlite3/reported_events_table.go
index 65584f4c..b72cb068 100644
--- a/roomserver/storage/sqlite3/reported_events_table.go
+++ b/roomserver/storage/sqlite3/reported_events_table.go
@@ -74,10 +74,20 @@ LIMIT $3
OFFSET $4
`
+const selectReportedEventSQL = `
+SELECT id, room_nid, event_nid, reporting_user_nid, event_sender_nid, reason, score, received_ts
+FROM roomserver_reported_events
+WHERE id = $1
+`
+
+const deleteReportedEventSQL = `DELETE FROM roomserver_reported_events WHERE id = $1`
+
type reportedEventsStatements struct {
insertReportedEventsStmt *sql.Stmt
selectReportedEventsDescStmt *sql.Stmt
selectReportedEventsAscStmt *sql.Stmt
+ selectReportedEventStmt *sql.Stmt
+ deleteReportedEventStmt *sql.Stmt
}
func CreateReportedEventsTable(db *sql.DB) error {
@@ -92,6 +102,8 @@ func PrepareReportedEventsTable(db *sql.DB) (tables.ReportedEvents, error) {
{&s.insertReportedEventsStmt, insertReportedEventSQL},
{&s.selectReportedEventsDescStmt, selectReportedEventsDescSQL},
{&s.selectReportedEventsAscStmt, selectReportedEventsAscSQL},
+ {&s.selectReportedEventStmt, selectReportedEventSQL},
+ {&s.deleteReportedEventStmt, deleteReportedEventSQL},
}.Prepare(db)
}
@@ -178,3 +190,32 @@ func (r *reportedEventsStatements) SelectReportedEvents(
return result, count, rows.Err()
}
+
+func (r *reportedEventsStatements) SelectReportedEvent(
+ ctx context.Context,
+ txn *sql.Tx,
+ reportID uint64,
+) (api.QueryAdminEventReportResponse, error) {
+ stmt := sqlutil.TxStmt(txn, r.selectReportedEventStmt)
+
+ var row api.QueryAdminEventReportResponse
+ if err := stmt.QueryRowContext(ctx, reportID).Scan(
+ &row.ID,
+ &row.RoomNID,
+ &row.EventNID,
+ &row.ReportingUserNID,
+ &row.SenderNID,
+ &row.Reason,
+ &row.Score,
+ &row.ReceivedTS,
+ ); err != nil {
+ return api.QueryAdminEventReportResponse{}, err
+ }
+ return row, nil
+}
+
+func (r *reportedEventsStatements) DeleteReportedEvent(ctx context.Context, txn *sql.Tx, reportID uint64) error {
+ stmt := sqlutil.TxStmt(txn, r.deleteReportedEventStmt)
+ _, err := stmt.ExecContext(ctx, reportID)
+ return err
+}
diff --git a/roomserver/storage/tables/interface.go b/roomserver/storage/tables/interface.go
index d41b5032..02f6992c 100644
--- a/roomserver/storage/tables/interface.go
+++ b/roomserver/storage/tables/interface.go
@@ -147,6 +147,12 @@ type ReportedEvents interface {
reportingUserID types.EventStateKeyNID,
roomNID types.RoomNID,
) ([]api.QueryAdminEventReportsResponse, int64, error)
+ SelectReportedEvent(
+ ctx context.Context,
+ txn *sql.Tx,
+ reportID uint64,
+ ) (api.QueryAdminEventReportResponse, error)
+ DeleteReportedEvent(ctx context.Context, txn *sql.Tx, reportID uint64) error
}
type MembershipState int64