diff options
author | Kegsay <kegan@matrix.org> | 2020-07-06 17:49:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-06 17:49:15 +0100 |
commit | 52c77cb4b4f4ac5ae3b643d203964d1754db4249 (patch) | |
tree | 15f785ab3df94d0c873ab868096d4d0583b2e8fc /roomserver/storage/sqlite3 | |
parent | 65084c50520310306ee44d25160762f27512a664 (diff) |
Implement core redaction logic (#1185)
* Implement core redaction logic
- Add a new `redactions_table.go` which tracks the mapping of
the redaction event ID and the redacted event ID
- Mark redactions as 'validated' when we have both events.
- When redactions are validated, add `unsigned.redacted_because`
and modify the `eventJSON` accordingly.
Note: We currently do NOT redact the event content - it's gated
behind a feature flag - until we have tested redactions a bit more.
* Linting
Diffstat (limited to 'roomserver/storage/sqlite3')
-rw-r--r-- | roomserver/storage/sqlite3/event_json_table.go | 3 | ||||
-rw-r--r-- | roomserver/storage/sqlite3/redactions_table.go | 120 | ||||
-rw-r--r-- | roomserver/storage/sqlite3/storage.go | 5 |
3 files changed, 126 insertions, 2 deletions
diff --git a/roomserver/storage/sqlite3/event_json_table.go b/roomserver/storage/sqlite3/event_json_table.go index da0c448d..6368675b 100644 --- a/roomserver/storage/sqlite3/event_json_table.go +++ b/roomserver/storage/sqlite3/event_json_table.go @@ -35,8 +35,7 @@ const eventJSONSchema = ` ` const insertEventJSONSQL = ` - INSERT INTO roomserver_event_json (event_nid, event_json) VALUES ($1, $2) - ON CONFLICT DO NOTHING + INSERT OR REPLACE INTO roomserver_event_json (event_nid, event_json) VALUES ($1, $2) ` // Bulk event JSON lookup by numeric event ID. diff --git a/roomserver/storage/sqlite3/redactions_table.go b/roomserver/storage/sqlite3/redactions_table.go new file mode 100644 index 00000000..9910892c --- /dev/null +++ b/roomserver/storage/sqlite3/redactions_table.go @@ -0,0 +1,120 @@ +// Copyright 2020 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sqlite3 + +import ( + "context" + "database/sql" + + "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/roomserver/storage/shared" + "github.com/matrix-org/dendrite/roomserver/storage/tables" +) + +const redactionsSchema = ` +-- Stores information about the redacted state of events. +-- We need to track redactions rather than blindly updating the event JSON table on receipt of a redaction +-- because we might receive the redaction BEFORE we receive the event which it redacts (think backfill). +CREATE TABLE IF NOT EXISTS roomserver_redactions ( + redaction_event_id TEXT PRIMARY KEY, + redacts_event_id TEXT NOT NULL, + -- Initially FALSE, set to TRUE when the redaction has been validated according to rooms v3+ spec + -- https://matrix.org/docs/spec/rooms/v3#authorization-rules-for-events + validated BOOLEAN NOT NULL +); +` + +const insertRedactionSQL = "" + + "INSERT INTO roomserver_redactions (redaction_event_id, redacts_event_id, validated)" + + " VALUES ($1, $2, $3)" + +const selectRedactedEventSQL = "" + + "SELECT redaction_event_id, redacts_event_id, validated FROM roomserver_redactions" + + " WHERE redaction_event_id = $1" + +const selectRedactionEventSQL = "" + + "SELECT redaction_event_id, redacts_event_id, validated FROM roomserver_redactions" + + " WHERE redacts_event_id = $1" + +const markRedactionValidatedSQL = "" + + " UPDATE roomserver_redactions SET validated = $2 WHERE redaction_event_id = $1" + +type redactionStatements struct { + insertRedactionStmt *sql.Stmt + selectRedactedEventStmt *sql.Stmt + selectRedactionEventStmt *sql.Stmt + markRedactionValidatedStmt *sql.Stmt +} + +func NewSqliteRedactionsTable(db *sql.DB) (tables.Redactions, error) { + s := &redactionStatements{} + _, err := db.Exec(redactionsSchema) + if err != nil { + return nil, err + } + + return s, shared.StatementList{ + {&s.insertRedactionStmt, insertRedactionSQL}, + {&s.selectRedactedEventStmt, selectRedactedEventSQL}, + {&s.selectRedactionEventStmt, selectRedactionEventSQL}, + {&s.markRedactionValidatedStmt, markRedactionValidatedSQL}, + }.Prepare(db) +} + +func (s *redactionStatements) InsertRedaction( + ctx context.Context, txn *sql.Tx, info tables.RedactionInfo, +) error { + stmt := sqlutil.TxStmt(txn, s.insertRedactionStmt) + _, err := stmt.ExecContext(ctx, info.RedactionEventID, info.RedactsEventID, info.Validated) + return err +} + +func (s *redactionStatements) SelectRedactedEvent( + ctx context.Context, txn *sql.Tx, redactionEventID string, +) (info *tables.RedactionInfo, err error) { + info = &tables.RedactionInfo{} + stmt := sqlutil.TxStmt(txn, s.selectRedactedEventStmt) + err = stmt.QueryRowContext(ctx, redactionEventID).Scan( + &info.RedactionEventID, &info.RedactsEventID, &info.Validated, + ) + if err == sql.ErrNoRows { + info = nil + err = nil + } + return +} + +func (s *redactionStatements) SelectRedactionEvent( + ctx context.Context, txn *sql.Tx, redactedEventID string, +) (info *tables.RedactionInfo, err error) { + info = &tables.RedactionInfo{} + stmt := sqlutil.TxStmt(txn, s.selectRedactionEventStmt) + err = stmt.QueryRowContext(ctx, redactedEventID).Scan( + &info.RedactionEventID, &info.RedactsEventID, &info.Validated, + ) + if err == sql.ErrNoRows { + info = nil + err = nil + } + return +} + +func (s *redactionStatements) MarkRedactionValidated( + ctx context.Context, txn *sql.Tx, redactionEventID string, validated bool, +) error { + stmt := sqlutil.TxStmt(txn, s.markRedactionValidatedStmt) + _, err := stmt.ExecContext(ctx, redactionEventID, validated) + return err +} diff --git a/roomserver/storage/sqlite3/storage.go b/roomserver/storage/sqlite3/storage.go index 767b13ce..11781ce0 100644 --- a/roomserver/storage/sqlite3/storage.go +++ b/roomserver/storage/sqlite3/storage.go @@ -114,6 +114,10 @@ func Open(dataSourceName string) (*Database, error) { if err != nil { return nil, err } + redactions, err := NewSqliteRedactionsTable(d.db) + if err != nil { + return nil, err + } d.Database = shared.Database{ DB: d.db, EventsTable: d.events, @@ -129,6 +133,7 @@ func Open(dataSourceName string) (*Database, error) { InvitesTable: d.invites, MembershipTable: d.membership, PublishedTable: published, + RedactionsTable: redactions, } return &d, nil } |