dendrite/vendor/src/github.com/matrix-org/gomatrixserverlib/redactevent.go
Andrew Morgan 241b1b5ace
Update gomatrixserverlib version (#476)
Signed-off-by: Andrew Morgan <andrewm@matrix.org>
2018-06-01 17:42:55 +01:00

162 lines
6 KiB
Go

/* Copyright 2016-2017 Vector Creations Ltd
*
* 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 gomatrixserverlib
import (
"encoding/json"
)
// RawJSON is a reimplementation of json.RawMessage that supports being used as a value type
//
// For example:
//
// jsonBytes, _ := json.Marshal(struct{
// RawMessage json.RawMessage
// RawJSON RawJSON
// }{
// json.RawMessage(`"Hello"`),
// RawJSON(`"World"`),
// })
//
// Results in:
//
// {"RawMessage":"IkhlbGxvIg==","RawJSON":"World"}
//
// See https://play.golang.org/p/FzhKIJP8-I for a full example.
type RawJSON []byte
// MarshalJSON implements the json.Marshaller interface using a value receiver.
// This means that RawJSON used as an embedded value will still encode correctly.
func (r RawJSON) MarshalJSON() ([]byte, error) {
return []byte(r), nil
}
// UnmarshalJSON implements the json.Unmarshaller interface using a pointer receiver.
func (r *RawJSON) UnmarshalJSON(data []byte) error {
*r = RawJSON(data)
return nil
}
// redactEvent strips the user controlled fields from an event, but leaves the
// fields necessary for authenticating the event.
func redactEvent(eventJSON []byte) ([]byte, error) {
// createContent keeps the fields needed in a m.room.create event.
// Create events need to keep the creator.
// (In an ideal world they would keep the m.federate flag see matrix-org/synapse#1831)
type createContent struct {
Creator RawJSON `json:"creator,omitempty"`
}
// joinRulesContent keeps the fields needed in a m.room.join_rules event.
// Join rules events need to keep the join_rule key.
type joinRulesContent struct {
JoinRule RawJSON `json:"join_rule,omitempty"`
}
// powerLevelContent keeps the fields needed in a m.room.power_levels event.
// Power level events need to keep all the levels.
type powerLevelContent struct {
Users RawJSON `json:"users,omitempty"`
UsersDefault RawJSON `json:"users_default,omitempty"`
Events RawJSON `json:"events,omitempty"`
EventsDefault RawJSON `json:"events_default,omitempty"`
StateDefault RawJSON `json:"state_default,omitempty"`
Ban RawJSON `json:"ban,omitempty"`
Kick RawJSON `json:"kick,omitempty"`
Redact RawJSON `json:"redact,omitempty"`
}
// memberContent keeps the fields needed in a m.room.member event.
// Member events keep the membership.
// (In an ideal world they would keep the third_party_invite see matrix-org/synapse#1831)
type memberContent struct {
Membership RawJSON `json:"membership,omitempty"`
}
// aliasesContent keeps the fields needed in a m.room.aliases event.
// TODO: Alias events probably don't need to keep the aliases key, but we need to match synapse here.
type aliasesContent struct {
Aliases RawJSON `json:"aliases,omitempty"`
}
// historyVisibilityContent keeps the fields needed in a m.room.history_visibility event
// History visibility events need to keep the history_visibility key.
type historyVisibilityContent struct {
HistoryVisibility RawJSON `json:"history_visibility,omitempty"`
}
// allContent keeps the union of all the content fields needed across all the event types.
// All the content JSON keys we are keeping are distinct across the different event types.
type allContent struct {
createContent
joinRulesContent
powerLevelContent
memberContent
aliasesContent
historyVisibilityContent
}
// eventFields keeps the top level keys needed by all event types.
// (In an ideal world they would include the "redacts" key for m.room.redaction events, see matrix-org/synapse#1831)
// See https://github.com/matrix-org/synapse/blob/v0.18.7/synapse/events/utils.py#L42-L56 for the list of fields
type eventFields struct {
EventID RawJSON `json:"event_id,omitempty"`
Sender RawJSON `json:"sender,omitempty"`
RoomID RawJSON `json:"room_id,omitempty"`
Hashes RawJSON `json:"hashes,omitempty"`
Signatures RawJSON `json:"signatures,omitempty"`
Content allContent `json:"content"`
Type string `json:"type"`
StateKey RawJSON `json:"state_key,omitempty"`
Depth RawJSON `json:"depth,omitempty"`
PrevEvents RawJSON `json:"prev_events,omitempty"`
PrevState RawJSON `json:"prev_state,omitempty"`
AuthEvents RawJSON `json:"auth_events,omitempty"`
Origin RawJSON `json:"origin,omitempty"`
OriginServerTS RawJSON `json:"origin_server_ts,omitempty"`
Membership RawJSON `json:"membership,omitempty"`
}
var event eventFields
// Unmarshalling into a struct will discard any extra fields from the event.
if err := json.Unmarshal(eventJSON, &event); err != nil {
return nil, err
}
var newContent allContent
// Copy the content fields that we should keep for the event type.
// By default we copy nothing leaving the content object empty.
switch event.Type {
case MRoomCreate:
newContent.createContent = event.Content.createContent
case MRoomMember:
newContent.memberContent = event.Content.memberContent
case MRoomJoinRules:
newContent.joinRulesContent = event.Content.joinRulesContent
case MRoomPowerLevels:
newContent.powerLevelContent = event.Content.powerLevelContent
case MRoomHistoryVisibility:
newContent.historyVisibilityContent = event.Content.historyVisibilityContent
case MRoomAliases:
newContent.aliasesContent = event.Content.aliasesContent
}
// Replace the content with our new filtered content.
// This will zero out any keys that weren't copied in the switch statement above.
event.Content = newContent
// Return the redacted event encoded as JSON.
return json.Marshal(&event)
}