gomatrixserverlib

package module
v0.0.0-...-c2391f7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2024 License: Apache-2.0 Imports: 27 Imported by: 561

README

gomatrixserverlib

GoDoc

Go library for common functions needed by matrix servers. This library assumes Go 1.18+.

Documentation

Index

Examples

Constants

View Source
const (
	EventValidationTooLarge int = 1
)

Event validation errors

View Source
const PublicKeyNotExpired = spec.Timestamp(0)

PublicKeyNotExpired is a magic value for PublicKeyLookupResult.ExpiredTS: it indicates that this is an active key which has not yet expired

View Source
const PublicKeyNotValid = spec.Timestamp(0)

PublicKeyNotValid is a magic value for PublicKeyLookupResult.ValidUntilTS: it is used when we don't have a validity period for this key. Most likely it is an old key with an expiry date.

Variables

View Source
var ErrCanonicalJSON = errors.New("value is outside of safe range")

Functions

func Allowed

func Allowed(event PDU, authEvents AuthEventProvider, userIDQuerier spec.UserIDForSender) error

Allowed checks whether an event is allowed by the auth events. It returns a NotAllowed error if the event is not allowed. If there was an error loading the auth events then it returns that error.

func CanonicalJSON

func CanonicalJSON(input []byte) ([]byte, error)

CanonicalJSON re-encodes the JSON in a canonical encoding. The encoding is the shortest possible encoding using integer values with sorted object keys. At present this function performs:

Returns a gomatrixserverlib.BadJSONError if JSON validation fails.

func CanonicalJSONAssumeValid

func CanonicalJSONAssumeValid(input []byte) []byte

CanonicalJSONAssumeValid is the same as CanonicalJSON, but assumes the input is valid JSON

func CheckFields

func CheckFields(input PDU) error

func CheckStateResponse

func CheckStateResponse(
	ctx context.Context, r StateResponse, roomVersion RoomVersion,
	keyRing JSONVerifier, missingAuth EventProvider, userIDForSender spec.UserIDForSender,
) ([]PDU, []PDU, error)

CheckStateResponse checks that a response to /state is valid. This function removes events that do not have valid signatures, and also returns the unmarshalled auth events (first return parameter) and state events (second return parameter). Does not alter any input args.

func CompactJSON

func CompactJSON(input, output []byte) []byte

CompactJSON makes the encoded JSON as small as possible by removing whitespace and unneeded unicode escapes

func EnforcedCanonicalJSON

func EnforcedCanonicalJSON(input []byte, roomVersion RoomVersion) ([]byte, error)

Returns a gomatrixserverlib.BadJSONError if the canonical JSON fails enforced checks or if JSON validation fails. At present this function performs:

Returns a gomatrixserverlib.BadJSONError if JSON validation fails.

func KnownRoomVersion

func KnownRoomVersion(verStr RoomVersion) bool

func NoStrictValidityCheck

func NoStrictValidityCheck(_, _ spec.Timestamp) bool

NoStrictValidityCheck doesn't perform any validation of potentially expired signing keys.

func PerformJoin

PerformJoin provides high level functionality that will attempt a federated room join. On success it will return the new join event and the state snapshot returned as part of the join.

func RawJSONFromResult

func RawJSONFromResult(result gjson.Result, _ []byte) []byte

RawJSONFromResult extracts the raw JSON bytes pointed to by result. input must be the json bytes that were used to generate result TODO: Why do we do this?

func RoomVersions

func RoomVersions() map[RoomVersion]IRoomVersion

RoomVersions returns information about room versions currently implemented by this commit of gomatrixserverlib.

func SignJSON

func SignJSON(signingName string, keyID KeyID, privateKey ed25519.PrivateKey, message []byte) (signed []byte, err error)

SignJSON signs a JSON object returning a copy signed with the given key. https://matrix.org/docs/spec/server_server/unstable.html#signing-json

func SortJSON

func SortJSON(input, output []byte) []byte

SortJSON reencodes the JSON with the object keys sorted by lexicographically by codepoint. The input must be valid JSON.

func SplitID

func SplitID(sigil byte, id string) (local string, domain spec.ServerName, err error)

SplitID splits a matrix ID into a local part and a server name.

Example
localpart, domain, err := SplitID('@', "@alice:localhost:8080")
if err != nil {
	panic(err)
}
fmt.Println(localpart, domain)
Output:

alice localhost:8080

func StableRoomVersion

func StableRoomVersion(verStr RoomVersion) bool

StableRoomVersion returns true if the provided room version is both known (i.e. KnownRoomVersion returns true) and marked as stable.

func StableRoomVersions

func StableRoomVersions() map[RoomVersion]IRoomVersion

StableRoomVersions returns a map of descriptions for room versions that are marked as stable.

func StrictValiditySignatureCheck

func StrictValiditySignatureCheck(atTs, validUntil spec.Timestamp) bool

StrictValiditySignatureCheck performs validation of potentially expired signing keys

func VerifyAllEventSignatures

func VerifyAllEventSignatures(ctx context.Context, events []PDU, verifier JSONVerifier, userIDForSender spec.UserIDForSender) []error

func VerifyAuthRulesAtState

func VerifyAuthRulesAtState(ctx context.Context, sp StateProvider, eventToVerify PDU, allowValidation bool, userIDForSender spec.UserIDForSender) error

VerifyAuthRulesAtState will check that the auth_events in the given event are valid at the state of the room before that event.

This implements Step 5 of https://matrix.org/docs/spec/server_server/latest#checks-performed-on-receipt-of-a-pdu "Passes authorization rules based on the state at the event, otherwise it is rejected."

If `allowValidation` is true: This check initially attempts to validate that the auth_events are in the target room state, and if they are it will short-circuit and succeed early. THIS IS ONLY VALID IF STEP 4 HAS BEEN PREVIOUSLY APPLIED. Otherwise, a malicious server could lie and say that no auth_events are required and this function will short-circuit and allow it.

func VerifyEventAuthChain

func VerifyEventAuthChain(ctx context.Context, eventToVerify PDU, provideEvents EventProvider, userIDForSender spec.UserIDForSender) error

VerifyEventAuthChain will verify that the event is allowed according to its auth_events, and then recursively verify each of those auth_events.

This function implements Step 4 of https://matrix.org/docs/spec/server_server/latest#checks-performed-on-receipt-of-a-pdu "Passes authorization rules based on the event's auth events, otherwise it is rejected." If an event passes this function without error, the caller should make sure that all the auth_events were actually for a valid room state, and not referencing random bits of room state from different positions in time (Step 5).

The `provideEvents` function will only be called for *new* events rather than for everything as it is assumed that this function is costly. Failing to provide all the requested events will fail this function. Returning an error from `provideEvents` will also fail this function.

func VerifyEventSignatures

func VerifyEventSignatures(ctx context.Context, e PDU, verifier JSONVerifier, userIDForSender spec.UserIDForSender) error

func VerifyJSON

func VerifyJSON(signingName string, keyID KeyID, publicKey ed25519.PublicKey, message []byte) error

VerifyJSON checks that the entity has signed the message using a particular key.

Types

type AuthChainErr

type AuthChainErr struct {
	// contains filtered or unexported fields
}

func (AuthChainErr) Error

func (se AuthChainErr) Error() string

func (AuthChainErr) Is

func (se AuthChainErr) Is(target error) bool

type AuthEventProvider

type AuthEventProvider interface {
	// Create returns the m.room.create event for the room or nil if there isn't a m.room.create event.
	Create() (PDU, error)
	// JoinRules returns the m.room.join_rules event for the room or nil if there isn't a m.room.join_rules event.
	JoinRules() (PDU, error)
	// PowerLevels returns the m.room.power_levels event for the room or nil if there isn't a m.room.power_levels event.
	PowerLevels() (PDU, error)
	// Member returns the m.room.member event for the given senderID state_key or nil if there isn't a m.room.member event.
	Member(stateKey spec.SenderID) (PDU, error)
	// ThirdPartyInvite returns the m.room.third_party_invite event for the
	// given state_key or nil if there isn't a m.room.third_party_invite event
	ThirdPartyInvite(stateKey string) (PDU, error)
	// Valid verifies that all auth events are from the same room.
	Valid() bool
}

AuthEventProvider provides auth_events for the authentication checks.

type AuthEvents

type AuthEvents struct {
	// contains filtered or unexported fields
}

AuthEvents is an implementation of AuthEventProvider backed by a map.

func NewAuthEvents

func NewAuthEvents(events []PDU) AuthEvents

NewAuthEvents returns an AuthEventProvider backed by the given events. New events can be added by calling AddEvent().

func (*AuthEvents) AddEvent

func (a *AuthEvents) AddEvent(event PDU) error

AddEvent adds an event to the provider. If an event already existed for the (type, state_key) then the event is replaced with the new event. Only returns an error if the event is not a state event.

func (*AuthEvents) Clear

func (a *AuthEvents) Clear()

Clear removes all entries from the AuthEventProvider.

func (*AuthEvents) Create

func (a *AuthEvents) Create() (PDU, error)

Create implements AuthEventProvider

func (*AuthEvents) JoinRules

func (a *AuthEvents) JoinRules() (PDU, error)

JoinRules implements AuthEventProvider

func (*AuthEvents) Member

func (a *AuthEvents) Member(stateKey spec.SenderID) (PDU, error)

Member implements AuthEventProvider

func (*AuthEvents) PowerLevels

func (a *AuthEvents) PowerLevels() (PDU, error)

PowerLevels implements AuthEventProvider

func (*AuthEvents) ThirdPartyInvite

func (a *AuthEvents) ThirdPartyInvite(stateKey string) (PDU, error)

ThirdPartyInvite implements AuthEventProvider

func (*AuthEvents) Valid

func (a *AuthEvents) Valid() bool

Valid verifies that all auth events are from the same room.

type AuthRulesErr

type AuthRulesErr struct {
	// contains filtered or unexported fields
}

func (AuthRulesErr) Error

func (se AuthRulesErr) Error() string

func (AuthRulesErr) Is

func (se AuthRulesErr) Is(target error) bool

type BackfillClient

type BackfillClient interface {
	// Backfill performs a backfill request to the given server.
	// https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-backfill-roomid
	Backfill(ctx context.Context, origin, server spec.ServerName, roomID string, limit int, fromEventIDs []string) (Transaction, error)
}

BackfillClient contains the necessary functions from the federation client to perform a backfill request from another homeserver.

type BackfillRequester

type BackfillRequester interface {
	StateProvider
	BackfillClient
	// ServersAtEvent is called when trying to determine which server to request from.
	// It returns a list of servers which can be queried for backfill requests. These servers
	// will be servers that are in the room already. The entries at the beginning are preferred servers
	// and will be tried first. An empty list will fail the request.
	ServersAtEvent(ctx context.Context, roomID, eventID string) []spec.ServerName
	ProvideEvents(roomVer RoomVersion, eventIDs []string) ([]PDU, error)
}

BackfillRequester contains the necessary functions to perform backfill requests from one server to another.

It requires a StateProvider in order to perform PDU checks on received events, notably the step "Passes authorization rules based on the state at the event, otherwise it is rejected.". The BackfillRequester will always call functions on the StateProvider in topological order, starting with the earliest event and rolling forwards. This allows implementations to make optimisations for subsequent events, rather than constantly deferring to federation requests.

type BadJSONError

type BadJSONError struct {
	// contains filtered or unexported fields
}

func (BadJSONError) Error

func (e BadJSONError) Error() string

func (BadJSONError) Unwrap

func (e BadJSONError) Unwrap() error

type CreateContent

type CreateContent struct {

	// The "m.federate" flag tells us whether the room can be federated to other servers.
	Federate *bool `json:"m.federate,omitempty"`
	// The creator of the room tells us what the default power levels are.
	Creator string `json:"creator"`
	// The version of the room. Should be treated as "1" when the key doesn't exist.
	RoomVersion *RoomVersion `json:"room_version,omitempty"`
	// The predecessor of the room.
	Predecessor *PreviousRoom `json:"predecessor,omitempty"`
	// The room type.
	RoomType string `json:"type,omitempty"`
	// contains filtered or unexported fields
}

CreateContent is the JSON content of a m.room.create event along with the top level keys needed for auth. See https://spec.matrix.org/v1.7/client-server-api/#mroomcreate for descriptions of the fields.

func NewCreateContentFromAuthEvents

func NewCreateContentFromAuthEvents(authEvents AuthEventProvider, userIDForSender spec.UserIDForSender) (c CreateContent, err error)

NewCreateContentFromAuthEvents loads the create event content from the create event in the auth events.

func (*CreateContent) DomainAllowed

func (c *CreateContent) DomainAllowed(domain string) error

DomainAllowed checks whether the domain is allowed in the room by the "m.federate" flag.

func (*CreateContent) UserIDAllowed

func (c *CreateContent) UserIDAllowed(id spec.UserID) error

UserIDAllowed checks whether the domain part of the user ID is allowed in the room by the "m.federate" flag.

type DeviceListUpdateEvent

type DeviceListUpdateEvent struct {
	UserID            string          `json:"user_id"`
	DeviceID          string          `json:"device_id"`
	DeviceDisplayName string          `json:"device_display_name,omitempty"`
	StreamID          int64           `json:"stream_id"`
	PrevID            []int64         `json:"prev_id,omitempty"`
	Deleted           bool            `json:"deleted,omitempty"`
	Keys              json.RawMessage `json:"keys,omitempty"`
}

DeviceListUpdateEvent is https://matrix.org/docs/spec/server_server/latest#m-device-list-update-schema

type DirectKeyFetcher

type DirectKeyFetcher struct {
	// The federation client to use to fetch keys with.
	Client            KeyClient
	IsLocalServerName func(server spec.ServerName) bool
	LocalPublicKey    spec.Base64Bytes
}

A DirectKeyFetcher fetches keys directly from a server. This may be suitable for local deployments that are firewalled from the public internet where DNS can be trusted.

func (*DirectKeyFetcher) FetchKeys

FetchKeys implements KeyFetcher

func (DirectKeyFetcher) FetcherName

func (d DirectKeyFetcher) FetcherName() string

FetcherName implements KeyFetcher

type EDU

type EDU struct {
	Type        string       `json:"edu_type"`
	Origin      string       `json:"origin"`
	Destination string       `json:"destination,omitempty"`
	Content     spec.RawJSON `json:"content,omitempty"`
}

EDU represents a EDU received via federation https://matrix.org/docs/spec/server_server/unstable.html#edus

func (*EDU) CacheCost

func (e *EDU) CacheCost() int

type Ed25519Checks

type Ed25519Checks struct {
	ValidEd25519      bool // The verify key is valid Ed25519 keys.
	MatchingSignature bool // The verify key has a valid signature.
}

Ed25519Checks are the checks that are applied to Ed25519 keys in ServerKey responses.

type EventBuilder

type EventBuilder struct {
	// The sender ID of the user sending the event.
	SenderID string `json:"sender"`
	// The room ID of the room this event is in.
	RoomID string `json:"room_id"`
	// The type of the event.
	Type string `json:"type"`
	// The state_key of the event if the event is a state event or nil if the event is not a state event.
	StateKey *string `json:"state_key,omitempty"`
	// The events that immediately preceded this event in the room history. This can be
	// either []eventReference for room v1/v2, and []string for room v3 onwards.
	PrevEvents interface{} `json:"prev_events"`
	// The events needed to authenticate this event. This can be
	// either []eventReference for room v1/v2, and []string for room v3 onwards.
	AuthEvents interface{} `json:"auth_events"`
	// The event ID of the event being redacted if this event is a "m.room.redaction".
	Redacts string `json:"redacts,omitempty"`
	// The depth of the event, This should be one greater than the maximum depth of the previous events.
	// The create event has a depth of 1.
	Depth int64 `json:"depth"`
	// The JSON object for "signatures" key of the event.
	Signature spec.RawJSON `json:"signatures,omitempty"`
	// The JSON object for "content" key of the event.
	Content spec.RawJSON `json:"content"`
	// The JSON object for the "unsigned" key
	Unsigned spec.RawJSON `json:"unsigned,omitempty"`
	// contains filtered or unexported fields
}

An EventBuilder is used to build a new event. These can be exchanged between matrix servers in the federation APIs when joining or leaving a room.

func (*EventBuilder) AddAuthEvents

func (eb *EventBuilder) AddAuthEvents(provider AuthEventProvider) error

func (*EventBuilder) Build

func (eb *EventBuilder) Build(
	now time.Time, origin spec.ServerName, keyID KeyID,
	privateKey ed25519.PrivateKey,
) (result PDU, err error)

Build a new Event. This is used when a local event is created on this server. Call this after filling out the necessary fields. This can be called multiple times on the same builder. A different event ID must be supplied each time this is called.

func (*EventBuilder) SetContent

func (eb *EventBuilder) SetContent(content interface{}) (err error)

SetContent sets the JSON content key of the event.

func (*EventBuilder) SetUnsigned

func (eb *EventBuilder) SetUnsigned(unsigned interface{}) (err error)

SetUnsigned sets the JSON unsigned key of the event.

type EventFormat

type EventFormat int

EventFormat refers to the formatting of the event fields struct.

const (
	EventFormatV1 EventFormat = iota + 1 // prev_events and auth_events as event references
	EventFormatV2                        // prev_events and auth_events as string array of event IDs
)

Event format constants.

type EventIDFormat

type EventIDFormat int

EventIDFormat refers to the formatting used to generate new event IDs.

const (
	EventIDFormatV1 EventIDFormat = iota + 1 // randomised
	EventIDFormatV2                          // base64-encoded hash of event
	EventIDFormatV3                          // URL-safe base64-encoded hash of event
)

Event ID format constants.

type EventJSONs

type EventJSONs []spec.RawJSON

func NewEventJSONsFromEvents

func NewEventJSONsFromEvents(he []PDU) EventJSONs

func (EventJSONs) TrustedEvents

func (e EventJSONs) TrustedEvents(roomVersion RoomVersion, redacted bool) []PDU

func (EventJSONs) UntrustedEvents

func (e EventJSONs) UntrustedEvents(roomVersion RoomVersion) []PDU

type EventLoadResult

type EventLoadResult struct {
	Event    PDU
	Error    error
	SoftFail bool
}

EventLoadResult is the result of loading and verifying an event in the EventsLoader.

type EventProvider

type EventProvider func(roomVer RoomVersion, eventIDs []string) ([]PDU, error)

EventProvider returns the requested list of events.

type EventValidationError

type EventValidationError struct {
	Message     string
	Code        int
	Persistable bool
}

EventValidationError is returned if there is a problem validating an event

func (EventValidationError) Error

func (e EventValidationError) Error() string

type EventsLoader

type EventsLoader struct {
	// contains filtered or unexported fields
}

EventsLoader loads untrusted events and verifies them.

func NewEventsLoader

func NewEventsLoader(roomVer RoomVersion, keyRing JSONVerifier, stateProvider StateProvider, provider EventProvider, performSoftFailCheck bool) *EventsLoader

NewEventsLoader returns a new events loader

func (*EventsLoader) LoadAndVerify

func (l *EventsLoader) LoadAndVerify(ctx context.Context, rawEvents []json.RawMessage, sortOrder TopologicalOrder, userIDForSender spec.UserIDForSender) ([]EventLoadResult, error)

LoadAndVerify loads untrusted events and verifies them. Checks performed are outlined at https://matrix.org/docs/spec/server_server/latest#checks-performed-on-receipt-of-a-pdu The length of the returned slice will always equal the length of rawEvents. The order of the returned events depends on `sortOrder`. The events are reverse topologically sorted by the ordering specified. However, in order to sort the events must be loaded which could fail. For those events which fail to be loaded, they will be put at the end of the returned slice.

type FederatedInviteClient

type FederatedInviteClient interface {
	SendInvite(ctx context.Context, event PDU, strippedState []InviteStrippedState) (PDU, error)
	SendInviteV3(ctx context.Context, event ProtoEvent, userID spec.UserID, roomVersion RoomVersion, strippedState []InviteStrippedState) (PDU, error)
}

type FederatedJoinClient

type FederatedJoinClient interface {
	MakeJoin(ctx context.Context, origin, s spec.ServerName, roomID, userID string) (res MakeJoinResponse, err error)
	SendJoin(ctx context.Context, origin, s spec.ServerName, event PDU) (res SendJoinResponse, err error)
}

type FederatedStateClient

type FederatedStateClient interface {
	LookupState(
		ctx context.Context, origin, s spec.ServerName, roomID, eventID string, roomVersion RoomVersion,
	) (res StateResponse, err error)
	LookupStateIDs(
		ctx context.Context, origin, s spec.ServerName, roomID, eventID string,
	) (res StateIDResponse, err error)
}

type FederatedStateProvider

type FederatedStateProvider struct {
	FedClient FederatedStateClient
	// The remote server to ask.
	Origin spec.ServerName
	Server spec.ServerName
	// Set to true to remember the auth event IDs for the room at various states
	RememberAuthEvents bool
	// Maps which are populated if AuthEvents is true, so you know which events are required to do PDU checks.
	EventToAuthEventIDs map[string][]string
	AuthEventMap        map[string]PDU
}

FederatedStateProvider is an implementation of StateProvider which solely uses federation requests to retrieve events.

func (*FederatedStateProvider) StateBeforeEvent

func (p *FederatedStateProvider) StateBeforeEvent(ctx context.Context, roomVer RoomVersion, event PDU, eventIDs []string) (map[string]PDU, error)

StateBeforeEvent implements StateProvider

func (*FederatedStateProvider) StateIDsBeforeEvent

func (p *FederatedStateProvider) StateIDsBeforeEvent(ctx context.Context, event PDU) ([]string, error)

StateIDsBeforeEvent implements StateProvider

type FederationError

type FederationError struct {
	ServerName spec.ServerName // The server being contacted.
	Transient  bool            // Whether the failure is permanent (will fail if performed again) or not.
	Reachable  bool            // Whether the server could be contacted.
	Err        error           // The underlying error message.
}

FederationError contains context surrounding why a federation request may have failed.

func (FederationError) Error

func (e FederationError) Error() string

type FledglingEvent

type FledglingEvent struct {
	// The type of the event.
	Type string `json:"type"`
	// The state_key of the event if the event is a state event or nil if the event is not a state event.
	StateKey string `json:"state_key"`
	// The JSON object for "content" key of the event.
	Content interface{} `json:"content"`
}

FledglingEvent is a helper representation of an event used when creating many events in succession.

type GetLatestEvents

type GetLatestEvents func(ctx context.Context, roomID spec.RoomID, eventsNeeded []StateKeyTuple) (LatestEvents, error)

type HandleInviteInput

type HandleInviteInput struct {
	RoomID          spec.RoomID           // The room that the user is being invited to join
	RoomVersion     RoomVersion           // The version of the invited to room
	InvitedUser     spec.UserID           // The user being invited to join the room
	InvitedSenderID spec.SenderID         // The senderID of the user being invited to join the room
	InviteEvent     PDU                   // The original invite event
	StrippedState   []InviteStrippedState // A small set of state events that can be used to identify the room

	KeyID      KeyID              // Used to sign the original invite event
	PrivateKey ed25519.PrivateKey // Used to sign the original invite event
	Verifier   JSONVerifier       // Used to verify the original invite event

	RoomQuerier       RoomQuerier          // Provides information about the room
	MembershipQuerier MembershipQuerier    // Provides information about the room's membership
	StateQuerier      StateQuerier         // Provides access to state events
	UserIDQuerier     spec.UserIDForSender // Provides userIDs given a senderID
}

type HandleInviteV3Input

type HandleInviteV3Input struct {
	HandleInviteInput

	InviteProtoEvent    ProtoEvent          // The original invite event
	GetOrCreateSenderID spec.CreateSenderID // Creates, if needed, a new senderID & private key
}

type HandleMakeJoinInput

type HandleMakeJoinInput struct {
	Context           context.Context
	UserID            spec.UserID               // The user wanting to join the room
	SenderID          spec.SenderID             // The senderID of the user wanting to join the room
	RoomID            spec.RoomID               // The room the user wants to join
	RoomVersion       RoomVersion               // The room version for the room being joined
	RemoteVersions    []RoomVersion             // Room versions supported by the remote server
	RequestOrigin     spec.ServerName           // The server that sent the /make_join federation request
	LocalServerName   spec.ServerName           // The name of this local server
	LocalServerInRoom bool                      // Whether this local server has a user currently joined to the room
	RoomQuerier       RestrictedRoomJoinQuerier // Provides access to potentially required information when processing restricted joins
	UserIDQuerier     spec.UserIDForSender      // Provides userIDs given a senderID

	// Returns a fully built version of the proto event and a list of state events required to auth this event
	BuildEventTemplate func(*ProtoEvent) (PDU, []PDU, error)
}

type HandleMakeJoinResponse

type HandleMakeJoinResponse struct {
	JoinTemplateEvent ProtoEvent
	RoomVersion       RoomVersion
}

func HandleMakeJoin

func HandleMakeJoin(input HandleMakeJoinInput) (*HandleMakeJoinResponse, error)

type HandleMakeLeaveInput

type HandleMakeLeaveInput struct {
	UserID            spec.UserID          // The user wanting to leave the room
	SenderID          spec.SenderID        // The senderID of the user wanting to leave the room
	RoomID            spec.RoomID          // The room the user wants to leave
	RoomVersion       RoomVersion          // The room version for the room being left
	RequestOrigin     spec.ServerName      // The server that sent the /make_leave federation request
	LocalServerName   spec.ServerName      // The name of this local server
	LocalServerInRoom bool                 // Whether this local server has a user currently joined to the room
	UserIDQuerier     spec.UserIDForSender // Provides userIDs given a senderID

	// Returns a fully built version of the proto event and a list of state events required to auth this event
	BuildEventTemplate func(*ProtoEvent) (PDU, []PDU, error)
}

type HandleMakeLeaveResponse

type HandleMakeLeaveResponse struct {
	LeaveTemplateEvent ProtoEvent
	RoomVersion        RoomVersion
}

type HandleSendJoinInput

type HandleSendJoinInput struct {
	Context                   context.Context
	RoomID                    spec.RoomID
	EventID                   string
	JoinEvent                 spec.RawJSON
	RoomVersion               RoomVersion     // The room version for the room being joined
	RequestOrigin             spec.ServerName // The server that sent the /make_join federation request
	LocalServerName           spec.ServerName // The name of this local server
	KeyID                     KeyID
	PrivateKey                ed25519.PrivateKey
	Verifier                  JSONVerifier
	MembershipQuerier         MembershipQuerier
	UserIDQuerier             spec.UserIDForSender // Provides userIDs given a senderID
	StoreSenderIDFromPublicID spec.StoreSenderIDFromPublicID
}

type HandleSendJoinResponse

type HandleSendJoinResponse struct {
	AlreadyJoined bool
	JoinEvent     PDU
}

func HandleSendJoin

func HandleSendJoin(input HandleSendJoinInput) (*HandleSendJoinResponse, error)

nolint: gocyclo

type HexString

type HexString []byte

A HexString is a string of bytes that are hex encoded when used in JSON. The bytes encoded using hex when marshalled as JSON. When the bytes are unmarshalled from JSON they are decoded from hex.

func (HexString) MarshalJSON

func (h HexString) MarshalJSON() ([]byte, error)

MarshalJSON encodes the bytes as hex and then encodes the hex as a JSON string. This takes a value receiver so that maps and slices of HexString encode correctly.

func (*HexString) UnmarshalJSON

func (h *HexString) UnmarshalJSON(raw []byte) (err error)

UnmarshalJSON decodes a JSON string and then decodes the resulting hex. This takes a pointer receiver because it needs to write the result of decoding.

type HistoryVisibility

type HistoryVisibility string
const (
	HistoryVisibilityWorldReadable HistoryVisibility = "world_readable"
	HistoryVisibilityShared        HistoryVisibility = "shared"
	HistoryVisibilityInvited       HistoryVisibility = "invited"
	HistoryVisibilityJoined        HistoryVisibility = "joined"
)

func (*HistoryVisibility) Scan

func (h *HistoryVisibility) Scan(src interface{}) error

Scan implements sql.Scanner

func (HistoryVisibility) Value

func (h HistoryVisibility) Value() (driver.Value, error)

Value implements sql.Valuer

type HistoryVisibilityContent

type HistoryVisibilityContent struct {
	HistoryVisibility HistoryVisibility `json:"history_visibility"`
}

HistoryVisibilityContent is the JSON content of a m.room.history_visibility event. See https://matrix.org/docs/spec/client_server/r0.6.0#room-history-visibility for descriptions of the fields.

type IRoomVersion

type IRoomVersion interface {
	Version() RoomVersion
	Stable() bool
	StateResAlgorithm() StateResAlgorithm
	EventFormat() EventFormat
	EventIDFormat() EventIDFormat
	RedactEventJSON(eventJSON []byte) ([]byte, error)
	SignatureValidityCheck(atTS, validUntil spec.Timestamp) bool
	NewEventFromTrustedJSON(eventJSON []byte, redacted bool) (result PDU, err error)
	NewEventFromTrustedJSONWithEventID(eventID string, eventJSON []byte, redacted bool) (result PDU, err error)
	NewEventFromUntrustedJSON(eventJSON []byte) (result PDU, err error)
	NewEventBuilder() *EventBuilder
	NewEventBuilderFromProtoEvent(pe *ProtoEvent) *EventBuilder
	CheckRestrictedJoin(ctx context.Context, localServerName spec.ServerName, roomQuerier RestrictedRoomJoinQuerier, roomID spec.RoomID, senderID spec.SenderID) (string, error)

	RestrictedJoinServername(content []byte) (spec.ServerName, error)
	CheckRestrictedJoinsAllowed() error
	CheckKnockingAllowed(m *membershipAllower) error
	CheckNotificationLevels(senderLevel int64, oldPowerLevels, newPowerLevels PowerLevelContent) error
	CheckCanonicalJSON(input []byte) error
	ParsePowerLevels(contentBytes []byte, c *PowerLevelContent) error
	CheckCreateEvent(event PDU, knownRoomVersion knownRoomVersionFunc) error
}

func GetRoomVersion

func GetRoomVersion(verStr RoomVersion) (impl IRoomVersion, err error)

func MustGetRoomVersion

func MustGetRoomVersion(verStr RoomVersion) IRoomVersion

MustGetRoomVersion is GetRoomVersion but panics if the version doesn't exist. Useful for tests.

type InviteStrippedState

type InviteStrippedState struct {
	// contains filtered or unexported fields
}

InviteStrippedState is a cut-down set of fields from room state events that allow the invited server to identify the room.

func GenerateStrippedState

func GenerateStrippedState(
	ctx context.Context, roomID spec.RoomID, stateQuerier StateQuerier,
) ([]InviteStrippedState, error)

func NewInviteStrippedState

func NewInviteStrippedState(event PDU) (ss InviteStrippedState)

NewInviteStrippedState creates a stripped state event from a regular state event.

func (*InviteStrippedState) Content

func (i *InviteStrippedState) Content() spec.RawJSON

Content returns the content of the stripped state.

func (InviteStrippedState) MarshalJSON

func (i InviteStrippedState) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaller

func (*InviteStrippedState) Sender

func (i *InviteStrippedState) Sender() string

Sender returns the sender of the stripped state.

func (*InviteStrippedState) StateKey

func (i *InviteStrippedState) StateKey() *string

StateKey returns the state key of the stripped state.

func (*InviteStrippedState) Type

func (i *InviteStrippedState) Type() string

Type returns the type of the stripped state.

func (*InviteStrippedState) UnmarshalJSON

func (i *InviteStrippedState) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaller

type IsRejected

type IsRejected func(eventID string) bool

IsRejected should return if the given eventID is rejected or not.

type JSONVerifier

type JSONVerifier interface {
	// VerifyJSONs performs bulk JSON signature verification for a list of VerifyJSONRequests.
	// Returns a list of VerifyJSONResults with the same length and order as the request list.
	// The caller should check the Result field for each entry to see if it was valid.
	// Returns an error if there was a problem talking to the database or one of the other methods
	// of fetching the public keys.
	VerifyJSONs(ctx context.Context, requests []VerifyJSONRequest) ([]VerifyJSONResult, error)
}

A JSONVerifier is an object which can verify the signatures of JSON messages.

type JSONVerifierSelf

type JSONVerifierSelf struct{}

JSONVerifierSelf provides methods to validate signatures signed by pseudo identities.

func (JSONVerifierSelf) VerifyJSONs

func (v JSONVerifierSelf) VerifyJSONs(ctx context.Context, requests []VerifyJSONRequest) ([]VerifyJSONResult, error)

VerifyJSONs implements JSONVerifier.

type JoinRuleContent

type JoinRuleContent struct {
	// We use the join_rule key to check whether join m.room.member events are allowed.
	JoinRule string                     `json:"join_rule"`
	Allow    []JoinRuleContentAllowRule `json:"allow,omitempty"`
}

JoinRuleContent is the JSON content of a m.room.join_rules event needed for auth checks. See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-join-rules for descriptions of the fields.

func NewJoinRuleContentFromAuthEvents

func NewJoinRuleContentFromAuthEvents(authEvents AuthEventProvider) (c JoinRuleContent, err error)

NewJoinRuleContentFromAuthEvents loads the join rule content from the join rules event in the auth event. Returns an error if there was an error loading the join rule event or parsing the content.

type JoinRuleContentAllowRule

type JoinRuleContentAllowRule struct {
	Type   string `json:"type"`
	RoomID string `json:"room_id"`
}

type KeyChecks

type KeyChecks struct {
	AllChecksOK        bool                    // Did all the checks pass?
	MatchingServerName bool                    // Does the server name match what was requested.
	FutureValidUntilTS bool                    // The valid until TS is in the future.
	HasEd25519Key      bool                    // The server has at least one ed25519 key.
	AllEd25519ChecksOK *bool                   // All the Ed25519 checks are ok. or null if there weren't any to check.
	Ed25519Checks      map[KeyID]Ed25519Checks // Checks for Ed25519 keys.
}

KeyChecks are the checks that should be applied to ServerKey responses.

func CheckKeys

func CheckKeys(
	serverName spec.ServerName,
	now time.Time,
	keys ServerKeys,
) (
	checks KeyChecks,
	ed25519Keys map[KeyID]spec.Base64Bytes,
)

CheckKeys checks the keys returned from a server to make sure they are valid. If the checks pass then also return a map of key_id to Ed25519 public key

type KeyClient

type KeyClient interface {
	GetServerKeys(ctx context.Context, matrixServer spec.ServerName) (ServerKeys, error)
	LookupServerKeys(ctx context.Context, matrixServer spec.ServerName, keyRequests map[PublicKeyLookupRequest]spec.Timestamp) ([]ServerKeys, error)
}

type KeyDatabase

type KeyDatabase interface {
	KeyFetcher
	// Add a block of public keys to the database.
	// Returns an error if there was a problem storing the keys.
	// A database is not required to rollback storing the all keys if some of
	// the keys aren't stored, and an in-progess store may be partially visible
	// to a concurrent FetchKeys(). This is acceptable since the database is
	// only used as a cache for the keys, so if a FetchKeys() races with a
	// StoreKeys() and some of the keys are missing they will be just be refetched.
	StoreKeys(ctx context.Context, results map[PublicKeyLookupRequest]PublicKeyLookupResult) error
}

A KeyDatabase is a store for caching public keys.

type KeyFetcher

type KeyFetcher interface {
	// Lookup a batch of public keys.
	// Takes a map from (server name, key ID) pairs to timestamp.
	// The timestamp is when the keys need to be vaild up to.
	// Returns a map from (server name, key ID) pairs to server key objects for
	// that server name containing that key ID
	// The result may have fewer (server name, key ID) pairs than were in the request.
	// The result may have more (server name, key ID) pairs than were in the request.
	// Returns an error if there was a problem fetching the keys.
	FetchKeys(ctx context.Context, requests map[PublicKeyLookupRequest]spec.Timestamp) (map[PublicKeyLookupRequest]PublicKeyLookupResult, error)

	// FetcherName returns the name of this fetcher, which can then be used for
	// logging errors etc.
	FetcherName() string
}

A KeyFetcher is a way of fetching public keys in bulk.

type KeyID

type KeyID string

A KeyID is the ID of a ed25519 key used to sign JSON. The key IDs have a format of "ed25519:[0-9A-Za-z]+" If we switch to using a different signing algorithm then we will change the prefix used.

func ListKeyIDs

func ListKeyIDs(signingName string, message []byte) ([]KeyID, error)

ListKeyIDs lists the key IDs a given entity has signed a message with.

type KeyRing

type KeyRing struct {
	KeyFetchers []KeyFetcher
	KeyDatabase KeyDatabase
}

A KeyRing stores keys for matrix servers and provides methods for verifying JSON messages.

func (KeyRing) VerifyJSONs

func (k KeyRing) VerifyJSONs(ctx context.Context, requests []VerifyJSONRequest) ([]VerifyJSONResult, error)

VerifyJSONs implements JSONVerifier.

type LatestEvents

type LatestEvents struct {
	RoomExists   bool
	StateEvents  []PDU
	PrevEventIDs []string
	Depth        int64
}

type MXIDMapping

type MXIDMapping struct {
	UserRoomKey spec.SenderID                                  `json:"user_room_key"`
	UserID      string                                         `json:"user_id"`
	Signatures  map[spec.ServerName]map[KeyID]spec.Base64Bytes `json:"signatures,omitempty"`
}

func (*MXIDMapping) Sign

func (m *MXIDMapping) Sign(serverName spec.ServerName, keyID KeyID, privateKey ed25519.PrivateKey) error

Sign signs the MXIDMapping with the signing key of the server. Sets the Signatures field on success.

type MakeJoinResponse

type MakeJoinResponse interface {
	GetJoinEvent() ProtoEvent
	GetRoomVersion() RoomVersion
}

type MemberContent

type MemberContent struct {
	// We use the membership key in order to check if the user is in the room.
	Membership  string `json:"membership"`
	DisplayName string `json:"displayname,omitempty"`
	AvatarURL   string `json:"avatar_url,omitempty"`
	Reason      string `json:"reason,omitempty"`
	IsDirect    bool   `json:"is_direct,omitempty"`
	// We use the third_party_invite key to special case thirdparty invites.
	ThirdPartyInvite *MemberThirdPartyInvite `json:"third_party_invite,omitempty"`
	// Restricted join rules require a user with invite permission to be nominated,
	// so that their membership can be included in the auth events.
	AuthorisedVia string `json:"join_authorised_via_users_server,omitempty"`

	// The MXIDMapping used in pseudo ID rooms
	MXIDMapping *MXIDMapping `json:"mxid_mapping,omitempty"`
}

MemberContent is the JSON content of a m.room.member event needed for auth checks. See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-member for descriptions of the fields.

func NewMemberContentFromAuthEvents

func NewMemberContentFromAuthEvents(authEvents AuthEventProvider, senderID spec.SenderID) (c MemberContent, err error)

NewMemberContentFromAuthEvents loads the member content from the member event for the senderID in the auth events. Returns an error if there was an error loading the member event or parsing the event content.

func NewMemberContentFromEvent

func NewMemberContentFromEvent(event PDU) (c MemberContent, err error)

NewMemberContentFromEvent parse the member content from an event. Returns an error if the content couldn't be parsed.

type MemberThirdPartyInvite

type MemberThirdPartyInvite struct {
	DisplayName string                       `json:"display_name"`
	Signed      MemberThirdPartyInviteSigned `json:"signed"`
}

MemberThirdPartyInvite is the "Invite" structure defined at http://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-member

type MemberThirdPartyInviteSigned

type MemberThirdPartyInviteSigned struct {
	MXID       string                       `json:"mxid"`
	Signatures map[string]map[string]string `json:"signatures"`
	Token      string                       `json:"token"`
}

MemberThirdPartyInviteSigned is the "signed" structure defined at http://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-member

type MembershipQuerier

type MembershipQuerier interface {
	CurrentMembership(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error)
}

type MissingAuthEventError

type MissingAuthEventError struct {
	AuthEventID string
	ForEventID  string
}

MissingAuthEventError refers to a situation where one of the auth event for a given event was not found.

func (MissingAuthEventError) Error

func (e MissingAuthEventError) Error() string

type NotAllowed

type NotAllowed struct {
	Message string
}

A NotAllowed error is returned if an event does not pass the auth checks.

func (*NotAllowed) Error

func (a *NotAllowed) Error() string

type OldVerifyKey

type OldVerifyKey struct {
	VerifyKey
	// When this key stopped being valid for event signing in milliseconds.
	ExpiredTS spec.Timestamp `json:"expired_ts"`
}

An OldVerifyKey is an old ed25519 public key that is no longer valid.

type PDU

type PDU interface {
	EventID() string
	StateKey() *string
	StateKeyEquals(s string) bool
	Type() string
	Content() []byte
	// JoinRule returns the value of the content.join_rule field if this event
	// is an "m.room.join_rules" event.
	// Returns an error if the event is not a m.room.join_rules event or if the content
	// is not valid m.room.join_rules content.
	JoinRule() (string, error)
	// HistoryVisibility returns the value of the content.history_visibility field if this event
	// is an "m.room.history_visibility" event.
	// Returns an error if the event is not a m.room.history_visibility event or if the content
	// is not valid m.room.history_visibility content.
	HistoryVisibility() (HistoryVisibility, error)
	Membership() (string, error)
	PowerLevels() (*PowerLevelContent, error)
	Version() RoomVersion
	RoomID() spec.RoomID
	Redacts() string
	// Redacted returns whether the event is redacted.
	Redacted() bool
	PrevEventIDs() []string
	OriginServerTS() spec.Timestamp
	// Redact redacts the event.
	Redact()
	SenderID() spec.SenderID
	Unsigned() []byte
	// SetUnsigned sets the unsigned key of the event.
	// Returns a copy of the event with the "unsigned" key set.
	SetUnsigned(unsigned interface{}) (PDU, error)
	// SetUnsignedField takes a path and value to insert into the unsigned dict of
	// the event.
	// path is a dot separated path into the unsigned dict (see gjson package
	// for details on format). In particular some characters like '.' and '*' must
	// be escaped.
	SetUnsignedField(path string, value interface{}) error
	// Sign returns a copy of the event with an additional signature.
	Sign(signingName string, keyID KeyID, privateKey ed25519.PrivateKey) PDU
	Depth() int64                    // TODO: remove
	JSON() []byte                    // TODO: remove
	AuthEventIDs() []string          // TODO: remove
	ToHeaderedJSON() ([]byte, error) // TODO: remove
}

func HandleInvite

func HandleInvite(ctx context.Context, input HandleInviteInput) (PDU, error)

HandleInvite - Ensures the incoming invite request is valid and signs the event to return back to the remote server. On success returns a fully formed & signed Invite Event

func HandleInviteV3

func HandleInviteV3(ctx context.Context, input HandleInviteV3Input) (PDU, error)

func HeaderedReverseTopologicalOrdering

func HeaderedReverseTopologicalOrdering(events []PDU, order TopologicalOrder) []PDU

HeaderedReverseTopologicalOrdering takes a set of input events and sorts them using Kahn's algorithm in order to topologically order them. The result array of events will be sorted so that "earlier" events appear first.

func LineariseStateResponse

func LineariseStateResponse(roomVersion RoomVersion, r StateResponse) []PDU

LineariseStateResponse combines the auth events and the state events and returns them in an order where every event comes after its auth events. Each event will only appear once in the output list.

func NewEventFromHeaderedJSON

func NewEventFromHeaderedJSON(headeredEventJSON []byte, redacted bool) (PDU, error)

NewEventFromHeaderedJSON creates a new event where the room version is embedded in the JSON bytes. The version is contained in the top level "_room_version" key.

func PerformInvite

func PerformInvite(ctx context.Context, input PerformInviteInput, fedClient FederatedInviteClient) (PDU, error)

PerformInvite - Performs all the checks required to validate the invite is allowed to happen. On success will return either nothing (in the case of inviting a local user) or a fully formed & signed Invite Event (in the case of inviting a remote user) nolint:gocyclo

func RequestBackfill

func RequestBackfill(ctx context.Context, origin spec.ServerName, b BackfillRequester, keyRing JSONVerifier,
	roomID string, ver RoomVersion, fromEventIDs []string, limit int, userIDForSender spec.UserIDForSender) ([]PDU, error)

RequestBackfill implements the server logic for making backfill requests to other servers. This handles server selection, fetching up to the request limit and verifying the received events. Event validation also includes authorisation checks, which may require additional state to be fetched.

The returned events are safe to be inserted into a database for later retrieval. It's possible for the number of returned events to be less than the limit, even if there exists more events. It's also possible for the number of returned events to be greater than the limit, if fromEventIDs > 1 and we need to ask multiple servers. We don't drop events greater than the limit because we've already done all the work to verify them, so it's up to the caller to decide what to do with them.

TODO: We should be able to make some guarantees for the caller about the returned events position in the DAG, but to verify it we need to know the prev_events of fromEventIDs.

TODO: When does it make sense to return errors?

func ResolveConflicts

func ResolveConflicts(
	version RoomVersion,
	events []PDU,
	authEvents []PDU,
	userIDForSender spec.UserIDForSender,
	isRejectedFn IsRejected,
) ([]PDU, error)

ResolveConflicts performs state resolution on the input events, returning the resolved state. It will automatically decide which state resolution algorithm to use, depending on the room version. `events` should be all the state events to resolve. `authEvents` should be the entire set of auth_events for these `events`. Returns an error if the state resolution algorithm cannot be determined.

func ResolveStateConflicts

func ResolveStateConflicts(conflicted []PDU, authEvents []PDU, userIDForSender spec.UserIDForSender) []PDU

ResolveStateConflicts takes a list of state events with conflicting state keys and works out which event should be used for each state event.

func ResolveStateConflictsV2

func ResolveStateConflictsV2(
	conflicted, unconflicted,
	authEvents []PDU,
	userIDForSender spec.UserIDForSender,
	isRejectedFn IsRejected,
) []PDU

ResolveStateConflicts takes a list of state events with conflicting state keys and works out which event should be used for each state event. This function returns the resolved state, including unconflicted state events.

func ReverseTopologicalOrdering

func ReverseTopologicalOrdering(input []PDU, order TopologicalOrder) []PDU

ReverseTopologicalOrdering takes a set of input events and sorts them using Kahn's algorithm in order to topologically order them. The result array of events will be sorted so that "earlier" events appear first.

func ToPDUs

func ToPDUs[T PDU](events []T) []PDU

Convert a slice of concrete PDU implementations to a slice of PDUs. This is useful when interfacing with GMSL functions which require []PDU.

type PerformInviteInput

type PerformInviteInput struct {
	RoomID        spec.RoomID // The room the user is being invited to join
	RoomVersion   RoomVersion
	Inviter       spec.UserID           // The user doing the inviting
	Invitee       spec.UserID           // The user being invited join the room
	IsTargetLocal bool                  // Whether the user being invited is local to this server
	EventTemplate ProtoEvent            // The original invite event
	StrippedState []InviteStrippedState // A small set of state events that can be used to identify the room
	KeyID         KeyID
	SigningKey    ed25519.PrivateKey
	EventTime     time.Time

	MembershipQuerier         MembershipQuerier    // Provides information about the room's membership
	StateQuerier              StateQuerier         // Provides access to state events
	UserIDQuerier             spec.UserIDForSender // Provides userID for a given senderID
	SenderIDQuerier           spec.SenderIDForUser // Provides senderID for a given userID
	SenderIDCreator           spec.CreateSenderID
	EventQuerier              GetLatestEvents
	StoreSenderIDFromPublicID spec.StoreSenderIDFromPublicID // Creates the senderID -> userID for the room creator
}

type PerformJoinInput

type PerformJoinInput struct {
	UserID     *spec.UserID           // The user joining the room
	RoomID     *spec.RoomID           // The room the user is joining
	ServerName spec.ServerName        // The server to attempt to join via
	Content    map[string]interface{} // The membership event content
	Unsigned   map[string]interface{} // The event unsigned content, if any

	PrivateKey ed25519.PrivateKey // Used to sign the join event
	KeyID      KeyID              // Used to sign the join event
	KeyRing    *KeyRing           // Used to verify the response from send_join

	EventProvider             EventProvider                  // Provides full events given a list of event IDs
	UserIDQuerier             spec.UserIDForSender           // Provides userID for a given senderID
	GetOrCreateSenderID       spec.CreateSenderID            // Creates, if needed, new senderID for this room.
	StoreSenderIDFromPublicID spec.StoreSenderIDFromPublicID // Creates the senderID -> userID for the room creator
}

type PerformJoinResponse

type PerformJoinResponse struct {
	JoinEvent     PDU
	StateSnapshot StateResponse
}

type PerspectiveKeyFetcher

type PerspectiveKeyFetcher struct {
	// The name of the perspective server to fetch keys from.
	PerspectiveServerName spec.ServerName
	// The ed25519 public keys the perspective server must sign responses with.
	PerspectiveServerKeys map[KeyID]ed25519.PublicKey
	// The federation client to use to fetch keys with.
	Client KeyClient
}

A PerspectiveKeyFetcher fetches server keys from a single perspective server.

func (*PerspectiveKeyFetcher) FetchKeys

FetchKeys implements KeyFetcher

func (PerspectiveKeyFetcher) FetcherName

func (p PerspectiveKeyFetcher) FetcherName() string

FetcherName implements KeyFetcher

type PowerLevelContent

type PowerLevelContent struct {
	Ban           int64            `json:"ban"`
	Invite        int64            `json:"invite"`
	Kick          int64            `json:"kick"`
	Redact        int64            `json:"redact"`
	Users         map[string]int64 `json:"users"`
	UsersDefault  int64            `json:"users_default"`
	Events        map[string]int64 `json:"events"`
	EventsDefault int64            `json:"events_default"`
	StateDefault  int64            `json:"state_default"`
	Notifications map[string]int64 `json:"notifications"`
}

PowerLevelContent is the JSON content of a m.room.power_levels event needed for auth checks. Typically the user calls NewPowerLevelContentFromAuthEvents instead of unmarshalling the content directly from JSON so defaults can be applied. However, the JSON key names are still preserved so it's possible to marshal the struct into JSON easily. See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-power-levels for descriptions of the fields.

func NewPowerLevelContentFromAuthEvents

func NewPowerLevelContentFromAuthEvents(authEvents AuthEventProvider, creatorUserID string) (c PowerLevelContent, err error)

NewPowerLevelContentFromAuthEvents loads the power level content from the power level event in the auth events or returns the default values if there is no power level event.

func NewPowerLevelContentFromEvent

func NewPowerLevelContentFromEvent(event PDU) (c PowerLevelContent, err error)

NewPowerLevelContentFromEvent loads the power level content from an event.

func (*PowerLevelContent) Defaults

func (c *PowerLevelContent) Defaults()

Defaults sets the power levels to their default values. See https://spec.matrix.org/v1.8/client-server-api/#mroompower_levels for defaults.

func (*PowerLevelContent) EventLevel

func (c *PowerLevelContent) EventLevel(eventType string, isState bool) int64

EventLevel returns the power level needed to send an event in the room.

func (*PowerLevelContent) NotificationLevel

func (c *PowerLevelContent) NotificationLevel(notification string) int64

UserLevel returns the power level a user has in the room.

func (*PowerLevelContent) UserLevel

func (c *PowerLevelContent) UserLevel(senderID spec.SenderID) int64

UserLevel returns the power level a user has in the room.

type PreviousRoom

type PreviousRoom struct {
	RoomID  string `json:"room_id"`
	EventID string `json:"event_id"`
}

PreviousRoom is the "Previous Room" structure defined at https://matrix.org/docs/spec/client_server/r0.5.0#m-room-create

type ProtoEvent

type ProtoEvent struct {
	// The sender ID of the user sending the event.
	SenderID string `json:"sender"`
	// The room ID of the room this event is in.
	RoomID string `json:"room_id"`
	// The type of the event.
	Type string `json:"type"`
	// The state_key of the event if the event is a state event or nil if the event is not a state event.
	StateKey *string `json:"state_key,omitempty"`
	// The events that immediately preceded this event in the room history. This can be
	// either []eventReference for room v1/v2, and []string for room v3 onwards.
	PrevEvents interface{} `json:"prev_events"`
	// The events needed to authenticate this event. This can be
	// either []eventReference for room v1/v2, and []string for room v3 onwards.
	AuthEvents interface{} `json:"auth_events"`
	// The event ID of the event being redacted if this event is a "m.room.redaction".
	Redacts string `json:"redacts,omitempty"`
	// The depth of the event, This should be one greater than the maximum depth of the previous events.
	// The create event has a depth of 1.
	Depth int64 `json:"depth"`
	// The JSON object for "signatures" key of the event.
	Signature spec.RawJSON `json:"signatures,omitempty"`
	// The JSON object for "content" key of the event.
	Content spec.RawJSON `json:"content"`
	// The JSON object for the "unsigned" key
	Unsigned spec.RawJSON `json:"unsigned,omitempty"`
}

func (*ProtoEvent) SetContent

func (pe *ProtoEvent) SetContent(content interface{}) (err error)

func (*ProtoEvent) SetUnsigned

func (pe *ProtoEvent) SetUnsigned(unsigned interface{}) (err error)

SetUnsigned sets the JSON unsigned key of the event.

type PublicKey

type PublicKey struct {
	PublicKey      spec.Base64Bytes `json:"public_key"`
	KeyValidityURL string           `json:"key_validity_url"`
}

PublicKey is the "PublicKeys" structure defined at https://matrix.org/docs/spec/client_server/r0.5.0#m-room-third-party-invite

type PublicKeyLookupRequest

type PublicKeyLookupRequest struct {
	// The server to fetch a key for.
	ServerName spec.ServerName `json:"server_name"`
	// The ID of the key to fetch.
	KeyID KeyID `json:"key_id"`
}

A PublicKeyLookupRequest is a request for a public key with a particular key ID.

func (PublicKeyLookupRequest) MarshalText

func (r PublicKeyLookupRequest) MarshalText() ([]byte, error)

MarshalText turns the public key lookup request into a string format, which allows us to use it as a JSON map key.

func (*PublicKeyLookupRequest) UnmarshalText

func (r *PublicKeyLookupRequest) UnmarshalText(text []byte) error

UnmarshalText turns the string format back into a public key lookup request, from a JSON map key.

type PublicKeyLookupResult

type PublicKeyLookupResult struct {
	VerifyKey
	// if this key has expired, the time it stopped being valid for event signing in milliseconds.
	// if the key has not expired, the magic value PublicKeyNotExpired.
	ExpiredTS spec.Timestamp `json:"expired_ts"`
	// When this result is valid until in milliseconds.
	// if the key has expired, the magic value PublicKeyNotValid.
	ValidUntilTS spec.Timestamp `json:"valid_until_ts"`
}

A PublicKeyLookupResult is the result of looking up a server signing key.

func (PublicKeyLookupResult) WasValidAt

func (r PublicKeyLookupResult) WasValidAt(atTs spec.Timestamp, signatureValidityCheck SignatureValidityCheckFunc) bool

WasValidAt checks if this signing key is valid for an event signed at the given timestamp.

type PublicKeyNotaryLookupRequest

type PublicKeyNotaryLookupRequest struct {
	ServerKeys map[spec.ServerName]map[KeyID]PublicKeyNotaryQueryCriteria `json:"server_keys"`
}

type PublicKeyNotaryQueryCriteria

type PublicKeyNotaryQueryCriteria struct {
	MinimumValidUntilTS spec.Timestamp `json:"minimum_valid_until_ts"`
}

type RelatesTo

type RelatesTo struct {
	EventID      string `json:"event_id"`
	RelationType string `json:"rel_type"`
}

type RelationContent

type RelationContent struct {
	Relations *RelatesTo `json:"m.relates_to"`
}

type RestrictedRoomJoinInfo

type RestrictedRoomJoinInfo struct {
	LocalServerInRoom bool
	UserJoinedToRoom  bool
	JoinedUsers       []PDU
}

type RestrictedRoomJoinQuerier

type RestrictedRoomJoinQuerier interface {
	CurrentStateEvent(ctx context.Context, roomID spec.RoomID, eventType string, stateKey string) (PDU, error)
	InvitePending(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (bool, error)
	RestrictedRoomJoinInfo(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID, localServerName spec.ServerName) (*RestrictedRoomJoinInfo, error)
}

RestrictedRoomJoinQuerier provides the information needed when processing a restricted room join request.

type RoomQuerier

type RoomQuerier interface {
	IsKnownRoom(ctx context.Context, roomID spec.RoomID) (bool, error)
}

type RoomVersion

type RoomVersion string

RoomVersion refers to the room version for a specific room.

const (
	RoomVersionV1        RoomVersion = "1"
	RoomVersionV2        RoomVersion = "2"
	RoomVersionV3        RoomVersion = "3"
	RoomVersionV4        RoomVersion = "4"
	RoomVersionV5        RoomVersion = "5"
	RoomVersionV6        RoomVersion = "6"
	RoomVersionV7        RoomVersion = "7"
	RoomVersionV8        RoomVersion = "8"
	RoomVersionV9        RoomVersion = "9"
	RoomVersionV10       RoomVersion = "10"
	RoomVersionV11       RoomVersion = "11"
	RoomVersionPseudoIDs RoomVersion = "org.matrix.msc4014"
)

Room version constants. These are strings because the version grammar allows for future expansion. https://matrix.org/docs/spec/#room-version-grammar

type RoomVersionImpl

type RoomVersionImpl struct {
	// contains filtered or unexported fields
}

RoomVersionDescription contains information about a room version, namely whether it is marked as supported or stable in this server version, along with the state resolution algorithm, event ID etc formats used.

A version is supported if the server has some support for rooms that are this version. A version is marked as stable or unstable in order to hint whether the version should be used to clients calling the /capabilities endpoint. https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-capabilities

func (RoomVersionImpl) CheckCanonicalJSON

func (v RoomVersionImpl) CheckCanonicalJSON(eventJSON []byte) error

CheckCanonicalJSON returns an error if the eventJSON is not canonical JSON.

func (RoomVersionImpl) CheckCreateEvent

func (v RoomVersionImpl) CheckCreateEvent(event PDU, knownRoomVersion knownRoomVersionFunc) error

func (RoomVersionImpl) CheckKnockingAllowed

func (v RoomVersionImpl) CheckKnockingAllowed(m *membershipAllower) error

CheckKnockingAllowed checks if this room version supports knocking on rooms.

func (RoomVersionImpl) CheckNotificationLevels

func (v RoomVersionImpl) CheckNotificationLevels(senderLevel int64, oldPowerLevels, newPowerLevels PowerLevelContent) error

CheckNotificationLevels checks that the changes in notification levels are allowed.

func (RoomVersionImpl) CheckRestrictedJoin

func (v RoomVersionImpl) CheckRestrictedJoin(
	ctx context.Context,
	localServerName spec.ServerName,
	roomQuerier RestrictedRoomJoinQuerier,
	roomID spec.RoomID, senderID spec.SenderID,
) (string, error)

func (RoomVersionImpl) CheckRestrictedJoinsAllowed

func (v RoomVersionImpl) CheckRestrictedJoinsAllowed() error

CheckRestrictedJoinsAllowed checks if this room version allows restricted joins.

func (RoomVersionImpl) EventFormat

func (v RoomVersionImpl) EventFormat() EventFormat

EventFormat returns the event format for the given room version.

func (RoomVersionImpl) EventIDFormat

func (v RoomVersionImpl) EventIDFormat() EventIDFormat

EventIDFormat returns the event ID format for the given room version.

func (RoomVersionImpl) NewEventBuilder

func (v RoomVersionImpl) NewEventBuilder() *EventBuilder

func (RoomVersionImpl) NewEventBuilderFromProtoEvent

func (v RoomVersionImpl) NewEventBuilderFromProtoEvent(pe *ProtoEvent) *EventBuilder

func (RoomVersionImpl) NewEventFromTrustedJSON

func (v RoomVersionImpl) NewEventFromTrustedJSON(eventJSON []byte, redacted bool) (result PDU, err error)

func (RoomVersionImpl) NewEventFromTrustedJSONWithEventID

func (v RoomVersionImpl) NewEventFromTrustedJSONWithEventID(eventID string, eventJSON []byte, redacted bool) (result PDU, err error)

func (RoomVersionImpl) NewEventFromUntrustedJSON

func (v RoomVersionImpl) NewEventFromUntrustedJSON(eventJSON []byte) (result PDU, err error)

func (RoomVersionImpl) ParsePowerLevels

func (v RoomVersionImpl) ParsePowerLevels(contentBytes []byte, c *PowerLevelContent) error

ParsePowerLevels parses the power_level directly into the passed PowerLevelContent.

func (RoomVersionImpl) RedactEventJSON

func (v RoomVersionImpl) RedactEventJSON(eventJSON []byte) ([]byte, error)

RedactEventJSON strips the user controlled fields from an event, but leaves the fields necessary for authenticating the event.

func (RoomVersionImpl) RestrictedJoinServername

func (v RoomVersionImpl) RestrictedJoinServername(content []byte) (spec.ServerName, error)

RestrictedJoinServername returns the severName from a potentially existing join_authorised_via_users_server content field. Used to verify event signatures.

func (RoomVersionImpl) SignatureValidityCheck

func (v RoomVersionImpl) SignatureValidityCheck(atTS, validUntilTS spec.Timestamp) bool

SignatureValidityCheck returns true if the signature check are passing.

func (RoomVersionImpl) Stable

func (v RoomVersionImpl) Stable() bool

func (RoomVersionImpl) StateResAlgorithm

func (v RoomVersionImpl) StateResAlgorithm() StateResAlgorithm

StateResAlgorithm returns the state resolution for the given room version.

func (RoomVersionImpl) Version

func (v RoomVersionImpl) Version() RoomVersion

type SendJoinResponse

type SendJoinResponse interface {
	GetAuthEvents() EventJSONs
	GetStateEvents() EventJSONs
	GetOrigin() spec.ServerName
	GetJoinEvent() spec.RawJSON
	GetMembersOmitted() bool
	GetServersInRoom() []string
}

type SendToDeviceEvent

type SendToDeviceEvent struct {
	Sender  string          `json:"sender"`
	Type    string          `json:"type"`
	Content json.RawMessage `json:"content"`
}

type ServerKeyFields

type ServerKeyFields struct {
	// The name of the server
	ServerName spec.ServerName `json:"server_name"`
	// The current signing keys in use on this server.
	// The keys of the map are the IDs of the keys.
	// These are valid while this response is valid.
	VerifyKeys map[KeyID]VerifyKey `json:"verify_keys"`
	// When this result is valid until in milliseconds.
	ValidUntilTS spec.Timestamp `json:"valid_until_ts"`
	// Old keys that are now only valid for checking historic events.
	// The keys of the map are the IDs of the keys.
	OldVerifyKeys map[KeyID]OldVerifyKey `json:"old_verify_keys"`
}

ServerKeyFields are the parsed JSON contents of the ed25519 signing keys published by a matrix server.

type ServerKeys

type ServerKeys struct {
	// Copy of the raw JSON for signature checking.
	Raw []byte
	// The decoded JSON fields.
	ServerKeyFields
}

ServerKeys are the ed25519 signing keys published by a matrix server. Contains SHA256 fingerprints of the TLS X509 certificates used by the server.

func (ServerKeys) MarshalJSON

func (keys ServerKeys) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler

func (ServerKeys) PublicKey

func (keys ServerKeys) PublicKey(keyID KeyID, atTS spec.Timestamp) []byte

PublicKey returns a public key with the given ID valid at the given TS or nil if no such key exists.

func (*ServerKeys) UnmarshalJSON

func (keys *ServerKeys) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler

type SignatureErr

type SignatureErr struct {
	// contains filtered or unexported fields
}

func (SignatureErr) Error

func (se SignatureErr) Error() string

func (SignatureErr) Is

func (se SignatureErr) Is(target error) bool

type SignatureValidityCheckFunc

type SignatureValidityCheckFunc func(atTS, validUntil spec.Timestamp) bool

SignatureValidityCheckFunc is a function used to validate signing keys

type StateIDResponse

type StateIDResponse interface {
	GetStateEventIDs() []string
	GetAuthEventIDs() []string
}

type StateKeyTuple

type StateKeyTuple struct {
	// The "type" key of a matrix event.
	EventType string
	// The "state_key" of a matrix event.
	// The empty string is a legitimate value for the "state_key" in matrix
	// so take care to initialise this field lest you accidentally request a
	// "state_key" with the go default of the empty string.
	StateKey string
}

A StateKeyTuple is the combination of an event type and an event state key. It is often used as a key in maps.

type StateNeeded

type StateNeeded struct {
	// Is the m.room.create event needed to auth the event.
	Create bool
	// Is the m.room.join_rules event needed to auth the event.
	JoinRules bool
	// Is the m.room.power_levels event needed to auth the event.
	PowerLevels bool
	// List of m.room.member state_keys needed to auth the event
	Member []string
	// List of m.room.third_party_invite state_keys
	ThirdPartyInvite []string
}

StateNeeded lists the event types and state_keys needed to authenticate an event.

func StateNeededForAuth

func StateNeededForAuth(events []PDU) (result StateNeeded)

StateNeededForAuth returns the event types and state_keys needed to authenticate an event. This takes a list of events to facilitate bulk processing when doing auth checks as part of state conflict resolution.

func StateNeededForProtoEvent

func StateNeededForProtoEvent(protoEvent *ProtoEvent) (result StateNeeded, err error)

StateNeededForProtoEvent returns the event types and state_keys needed to authenticate the event being built. These events should be put under 'auth_events' for the event being built. Returns an error if the state needed could not be calculated with the given builder, e.g if there is a m.room.member without a membership key.

func (StateNeeded) AuthEventReferences

func (s StateNeeded) AuthEventReferences(provider AuthEventProvider) (refs []string, err error)

AuthEventReferences returns the auth_events references for the StateNeeded. Returns an error if the provider returns an error. If an event is missing from the provider but is required in StateNeeded, it is skipped over: no error is returned.

func (StateNeeded) Tuples

func (s StateNeeded) Tuples() (res []StateKeyTuple)

Tuples returns the needed state key tuples for performing auth on an event.

type StateProvider

type StateProvider interface {
	// StateIDsBeforeEvent returns a list of state event IDs for the event ID provided, which represent the entire
	// room state before that event.
	StateIDsBeforeEvent(ctx context.Context, event PDU) ([]string, error)
	// StateBeforeEvent returns the state of the room before the given event. `eventIDs` will be populated with the output
	// of StateIDsAtEvent to aid in event retrieval.
	StateBeforeEvent(ctx context.Context, roomVer RoomVersion, event PDU, eventIDs []string) (map[string]PDU, error)
}

StateProvider is capable of returning the room state at any point in time.

type StateQuerier

type StateQuerier interface {
	GetAuthEvents(ctx context.Context, event PDU) (AuthEventProvider, error)
	GetState(ctx context.Context, roomID spec.RoomID, stateWanted []StateKeyTuple) ([]PDU, error)
}

type StateResAlgorithm

type StateResAlgorithm int

StateResAlgorithm refers to a version of the state resolution algorithm.

const (
	StateResV1 StateResAlgorithm = iota + 1 // state resolution v1
	StateResV2                              // state resolution v2
)

State resolution constants.

type StateResponse

type StateResponse interface {
	GetAuthEvents() EventJSONs
	GetStateEvents() EventJSONs
}

func CheckSendJoinResponse

func CheckSendJoinResponse(
	ctx context.Context, roomVersion RoomVersion, r StateResponse,
	keyRing JSONVerifier, joinEvent PDU,
	missingAuth EventProvider, userIDForSender spec.UserIDForSender,
) (StateResponse, error)

Check that a response to /send_join is valid. If it is then it returns a reference to the RespState that contains the room state excluding any events that failed signature checks. This checks that it would be valid as a response to /state. This also checks that the join event is allowed by the state. This function mutates the RespSendJoin to remove any events from AuthEvents or StateEvents that do not have valid signatures.

type ThirdPartyInviteContent

type ThirdPartyInviteContent struct {
	DisplayName    string `json:"display_name"`
	KeyValidityURL string `json:"key_validity_url"`
	PublicKey      string `json:"public_key"`
	// Public keys are used to verify the signature of a m.room.member event that
	// came from a m.room.third_party_invite event
	PublicKeys []PublicKey `json:"public_keys"`
}

ThirdPartyInviteContent is the JSON content of a m.room.third_party_invite event needed for auth checks. See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-third-party-invite for descriptions of the fields.

func NewThirdPartyInviteContentFromAuthEvents

func NewThirdPartyInviteContentFromAuthEvents(authEvents AuthEventProvider, token string) (t ThirdPartyInviteContent, err error)

NewThirdPartyInviteContentFromAuthEvents loads the third party invite content from the third party invite event for the state key (token) in the auth events. Returns an error if there was an error loading the third party invite event or parsing the event content.

type ToDeviceMessage

type ToDeviceMessage struct {
	Sender    string                                `json:"sender"`
	Type      string                                `json:"type"`
	MessageID string                                `json:"message_id"`
	Messages  map[string]map[string]json.RawMessage `json:"messages"`
}

type TopologicalOrder

type TopologicalOrder int

TopologicalOrder represents how to sort a list of events, used primarily in ReverseTopologicalOrdering

const (
	TopologicalOrderByPrevEvents TopologicalOrder = iota + 1
	TopologicalOrderByAuthEvents
)

Sort events by prev_events or auth_events

type Transaction

type Transaction struct {
	// The ID of the transaction.
	TransactionID TransactionID `json:"-"`
	// The server that sent the transaction.
	Origin spec.ServerName `json:"origin"`
	// The server that should receive the transaction.
	Destination spec.ServerName `json:"-"`
	// The millisecond posix timestamp on the origin server when the
	// transaction was created.
	OriginServerTS spec.Timestamp `json:"origin_server_ts"`
	// The IDs of the most recent transactions sent by the origin server to
	// the destination server. Multiple transactions can be sent by the origin
	// server to the destination server in parallel so there may be more than
	// one previous transaction.
	PreviousIDs []TransactionID `json:"-"`
	// The room events pushed from the origin server to the destination server
	// by this transaction. The events should either be events that originate
	// on the origin server or be join m.room.member events.
	PDUs []json.RawMessage `json:"pdus"`
	// The ephemeral events pushed from origin server to destination server
	// by this transaction. The events must orginate at the origin server.
	EDUs []EDU `json:"edus,omitempty"`
}

A Transaction is used to push data from one matrix server to another matrix server.

type TransactionID

type TransactionID string

A TransactionID identifies a transaction sent by a matrix server to another matrix server. The ID must be unique amongst the transactions sent from the origin server to the destination, but doesn't have to be globally unique. The ID must be safe to insert into a URL path segment. The ID should have a format matching '^[0-9A-Za-z\-_]*$'

type UnsupportedRoomVersionError

type UnsupportedRoomVersionError struct {
	Version RoomVersion
}

UnsupportedRoomVersionError occurs when a call has been made with a room version that is not supported by this version of gomatrixserverlib.

func (UnsupportedRoomVersionError) Error

type VerifyJSONRequest

type VerifyJSONRequest struct {
	// The name of the matrix server to check for a signature for.
	ServerName spec.ServerName
	// The millisecond posix timestamp the message needs to be valid at.
	AtTS spec.Timestamp
	// The JSON bytes.
	Message []byte
	// ValidityCheckingFunc is used to validate signatures. This can be used
	// to enforce strict validation of signatures.
	ValidityCheckingFunc SignatureValidityCheckFunc
}

A VerifyJSONRequest is a request to check for a signature on a JSON message. A JSON message is valid for a server if the message has at least one valid signature from that server.

type VerifyJSONResult

type VerifyJSONResult struct {
	// Whether the message passed the signature checks.
	// This will be nil if the message passed the checks.
	// This will have an error if the message did not pass the checks.
	Error error
}

A VerifyJSONResult is the result of checking the signature of a JSON message.

type VerifyKey

type VerifyKey struct {
	// The public key.
	Key spec.Base64Bytes `json:"key"`
}

A VerifyKey is a ed25519 public key for a server.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL