federation

package
v0.26.3 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2026 License: MPL-2.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MinCacheDuration     = 1 * time.Hour
	MaxCacheDuration     = 72 * time.Hour
	DefaultCacheDuration = 24 * time.Hour
)
View Source
const MaxBackoff = 7 * 24 * time.Hour

Variables

View Source
var (
	ErrInvalidServerName = errors.New("invalid server name")
)
View Source
var ErrRecentKeyQueryFailed = errors.New("last retry was too recent")
View Source
var MUnauthorized = mautrix.RespError{ErrCode: "M_UNAUTHORIZED", StatusCode: http.StatusUnauthorized}
View Source
var NoopCache *noopCache

Functions

func DestinationServerName

func DestinationServerName(ctx context.Context) string

func DestinationServerNameFromRequest

func DestinationServerNameFromRequest(r *http.Request) string

func OriginServerName

func OriginServerName(ctx context.Context) string

func OriginServerNameFromRequest

func OriginServerNameFromRequest(r *http.Request) string

func ParseServerName

func ParseServerName(serverName string) (host string, port uint16, ok bool)

ParseServerName parses the port and hostname from a Matrix server name and validates that it matches the grammar specified in https://spec.matrix.org/v1.11/appendices/#server-name

func RequestSRV

func RequestSRV(ctx context.Context, cli *net.Resolver, hostname string) ([]*net.SRV, error)

RequestSRV resolves the `_matrix-fed._tcp` SRV record for the given hostname. If the new matrix-fed record is not found, it falls back to the old `_matrix._tcp` record.

Types

type Client

type Client struct {
	HTTP       *http.Client
	ServerName string
	UserAgent  string
	Key        *SigningKey

	ResponseSizeLimit int64
}

func NewClient

func NewClient(serverName string, key *SigningKey, cache ResolutionCache) *Client

func (*Client) Backfill

func (c *Client) Backfill(ctx context.Context, req *ReqBackfill) (resp *RespBackfill, err error)

func (*Client) GetEvent

func (c *Client) GetEvent(ctx context.Context, serverName string, eventID id.EventID) (resp *RespBackfill, err error)

func (*Client) GetEventAuthChain

func (c *Client) GetEventAuthChain(ctx context.Context, serverName string, roomID id.RoomID, eventID id.EventID) (resp *RespGetEventAuthChain, err error)

func (*Client) GetMissingEvents

func (c *Client) GetMissingEvents(ctx context.Context, req *ReqGetMissingEvents) (resp *RespGetMissingEvents, err error)

func (*Client) GetOpenIDUserInfo

func (c *Client) GetOpenIDUserInfo(ctx context.Context, serverName, accessToken string) (resp *RespOpenIDUserInfo, err error)

func (*Client) GetState

func (c *Client) GetState(ctx context.Context, serverName string, roomID id.RoomID, eventID id.EventID) (resp *RespGetState, err error)

func (*Client) GetStateIDs

func (c *Client) GetStateIDs(ctx context.Context, serverName string, roomID id.RoomID, eventID id.EventID) (resp *RespGetStateIDs, err error)

func (*Client) MakeFullRequest

func (c *Client) MakeFullRequest(ctx context.Context, params RequestParams) ([]byte, *http.Response, error)

func (*Client) MakeJoin added in v0.26.1

func (c *Client) MakeJoin(ctx context.Context, req *ReqMakeJoin) (resp *RespMakeJoin, err error)

func (*Client) MakeKnock added in v0.26.1

func (c *Client) MakeKnock(ctx context.Context, req *ReqMakeKnock) (resp *RespMakeKnock, err error)

func (*Client) MakeLeave added in v0.26.1

func (c *Client) MakeLeave(ctx context.Context, req *ReqMakeLeave) (resp *RespMakeLeave, err error)

func (*Client) MakeRequest

func (c *Client) MakeRequest(ctx context.Context, serverName string, authenticate bool, method string, path mautrix.PrefixableURLPath, reqJSON, respJSON any) error

func (*Client) PublicRooms

func (c *Client) PublicRooms(ctx context.Context, serverName string, req *mautrix.ReqPublicRooms) (resp *mautrix.RespPublicRooms, err error)

func (*Client) Query

func (c *Client) Query(ctx context.Context, serverName, queryType string, queryParams url.Values, respStruct any) (err error)

func (*Client) QueryDirectory

func (c *Client) QueryDirectory(ctx context.Context, serverName string, roomAlias id.RoomAlias) (resp *mautrix.RespAliasResolve, err error)

func (*Client) QueryKeys

func (c *Client) QueryKeys(ctx context.Context, serverName string, req *ReqQueryKeys) (resp *QueryKeysResponse, err error)

func (*Client) QueryProfile

func (c *Client) QueryProfile(ctx context.Context, serverName string, userID id.UserID) (resp *mautrix.RespUserProfile, err error)

func (*Client) SendInvite added in v0.26.1

func (c *Client) SendInvite(ctx context.Context, req *ReqSendInvite) (resp *RespSendInvite, err error)

func (*Client) SendJoin added in v0.26.1

func (c *Client) SendJoin(ctx context.Context, req *ReqSendJoin) (resp *RespSendJoin, err error)

func (*Client) SendKnock added in v0.26.1

func (c *Client) SendKnock(ctx context.Context, req *ReqSendKnock) (resp *RespSendKnock, err error)

func (*Client) SendLeave added in v0.26.1

func (c *Client) SendLeave(ctx context.Context, req *ReqSendLeave) (err error)

func (*Client) SendTransaction

func (c *Client) SendTransaction(ctx context.Context, req *ReqSendTransaction) (resp *RespSendTransaction, err error)

func (*Client) ServerKeys

func (c *Client) ServerKeys(ctx context.Context, serverName string) (resp *ServerKeyResponse, err error)

func (*Client) TimestampToEvent

func (c *Client) TimestampToEvent(ctx context.Context, serverName string, roomID id.RoomID, timestamp time.Time, dir mautrix.Direction) (resp *mautrix.RespTimestampToEvent, err error)

func (*Client) Version

func (c *Client) Version(ctx context.Context, serverName string) (resp *RespServerVersion, err error)

type EDU

type EDU = json.RawMessage

type GetQueryKeysResponse

type GetQueryKeysResponse struct {
	ServerKeys []*ServerKeyResponse `json:"server_keys"`
}

GetQueryKeysResponse is the response body for the `GET /_matrix/key/v2/query/{serverName}` endpoint

type InMemoryCache

type InMemoryCache struct {
	MinKeyRefetchDelay time.Duration
	// contains filtered or unexported fields
}

func NewInMemoryCache

func NewInMemoryCache() *InMemoryCache

func (*InMemoryCache) LoadKeys

func (c *InMemoryCache) LoadKeys(serverName string) (*ServerKeyResponse, error)

func (*InMemoryCache) LoadResolution

func (c *InMemoryCache) LoadResolution(serverName string) (*ResolvedServerName, error)

func (*InMemoryCache) ShouldReQuery

func (c *InMemoryCache) ShouldReQuery(serverName string) bool

func (*InMemoryCache) StoreFetchError

func (c *InMemoryCache) StoreFetchError(serverName string, err error)

func (*InMemoryCache) StoreKeys

func (c *InMemoryCache) StoreKeys(keys *ServerKeyResponse)

func (*InMemoryCache) StoreResolution

func (c *InMemoryCache) StoreResolution(resolution *ResolvedServerName)

type KeyCache

type KeyCache interface {
	StoreKeys(*ServerKeyResponse)
	StoreFetchError(serverName string, err error)
	ShouldReQuery(serverName string) bool
	LoadKeys(serverName string) (*ServerKeyResponse, error)
}

type KeyServer

type KeyServer struct {
	KeyProvider     ServerKeyProvider
	Version         ServerVersion
	WellKnownTarget string
	OtherKeys       KeyCache
}

KeyServer implements a basic Matrix key server that can serve its own keys, plus the federation version endpoint.

It does not implement querying keys of other servers, nor any other federation endpoints.

func (*KeyServer) GetQueryKeys

func (ks *KeyServer) GetQueryKeys(w http.ResponseWriter, r *http.Request)

GetQueryKeys implements the `GET /_matrix/key/v2/query/{serverName}` endpoint

https://spec.matrix.org/v1.9/server-server-api/#get_matrixkeyv2queryservername

func (*KeyServer) GetServerKey

func (ks *KeyServer) GetServerKey(w http.ResponseWriter, r *http.Request)

GetServerKey implements the `GET /_matrix/key/v2/server` endpoint.

https://spec.matrix.org/v1.9/server-server-api/#get_matrixkeyv2server

func (*KeyServer) GetServerVersion

func (ks *KeyServer) GetServerVersion(w http.ResponseWriter, r *http.Request)

GetServerVersion implements the `GET /_matrix/federation/v1/version` endpoint

https://spec.matrix.org/v1.9/server-server-api/#get_matrixfederationv1version

func (*KeyServer) GetWellKnown

func (ks *KeyServer) GetWellKnown(w http.ResponseWriter, r *http.Request)

GetWellKnown implements the `GET /.well-known/matrix/server` endpoint

https://spec.matrix.org/v1.9/server-server-api/#get_well-knownmatrixserver

func (*KeyServer) PostQueryKeys

func (ks *KeyServer) PostQueryKeys(w http.ResponseWriter, r *http.Request)

PostQueryKeys implements the `POST /_matrix/key/v2/query` endpoint

https://spec.matrix.org/v1.9/server-server-api/#post_matrixkeyv2query

func (*KeyServer) Register

func (ks *KeyServer) Register(r *http.ServeMux, log zerolog.Logger)

Register registers the key server endpoints to the given router.

type KeyURLPath

type KeyURLPath []any

func (KeyURLPath) FullPath

func (fkup KeyURLPath) FullPath() []any

type OldVerifyKey

type OldVerifyKey struct {
	Key       id.SigningKey      `json:"key"`
	ExpiredTS jsontime.UnixMilli `json:"expired_ts"`
}

type PDU

type PDU = json.RawMessage

type PDUProcessingResult

type PDUProcessingResult struct {
	Error string `json:"error,omitempty"`
}

type PostQueryKeysResponse

type PostQueryKeysResponse struct {
	ServerKeys map[string]*ServerKeyResponse `json:"server_keys"`
}

PostQueryKeysResponse is the response body for the `POST /_matrix/key/v2/query` endpoint

type QueryKeysCriteria

type QueryKeysCriteria struct {
	MinimumValidUntilTS jsontime.UnixMilli `json:"minimum_valid_until_ts"`
}

type QueryKeysResponse

type QueryKeysResponse struct {
	ServerKeys []*ServerKeyResponse `json:"server_keys"`
}

type ReqBackfill

type ReqBackfill struct {
	ServerName   string
	RoomID       id.RoomID
	Limit        int
	BackfillFrom []id.EventID
}

type ReqGetMissingEvents

type ReqGetMissingEvents struct {
	ServerName     string       `json:"-"`
	RoomID         id.RoomID    `json:"-"`
	EarliestEvents []id.EventID `json:"earliest_events"`
	LatestEvents   []id.EventID `json:"latest_events"`
	Limit          int          `json:"limit,omitempty"`
	MinDepth       int          `json:"min_depth,omitempty"`
}

type ReqMakeJoin added in v0.26.1

type ReqMakeJoin struct {
	RoomID            id.RoomID
	UserID            id.UserID
	Via               string
	SupportedVersions []id.RoomVersion
}

type ReqMakeKnock added in v0.26.1

type ReqMakeKnock = ReqMakeJoin

type ReqMakeLeave added in v0.26.1

type ReqMakeLeave struct {
	RoomID id.RoomID
	UserID id.UserID
	Via    string
}

type ReqQueryKeys

type ReqQueryKeys struct {
	ServerKeys map[string]map[id.KeyID]QueryKeysCriteria `json:"server_keys"`
}

ReqQueryKeys is the request body for the `POST /_matrix/key/v2/query` endpoint

type ReqSendInvite added in v0.26.1

type ReqSendInvite struct {
	RoomID          id.RoomID      `json:"-"`
	UserID          id.UserID      `json:"-"`
	Event           PDU            `json:"event"`
	InviteRoomState []PDU          `json:"invite_room_state"`
	RoomVersion     id.RoomVersion `json:"room_version"`
}

type ReqSendJoin added in v0.26.1

type ReqSendJoin struct {
	RoomID      id.RoomID
	EventID     id.EventID
	OmitMembers bool
	Event       PDU
	Via         string
}

type ReqSendKnock added in v0.26.1

type ReqSendKnock struct {
	RoomID  id.RoomID
	EventID id.EventID
	Event   PDU
	Via     string
}

type ReqSendLeave added in v0.26.1

type ReqSendLeave struct {
	RoomID  id.RoomID
	EventID id.EventID
	Event   PDU
	Via     string
}

type ReqSendTransaction

type ReqSendTransaction struct {
	Destination string `json:"destination"`
	TxnID       string `json:"-"`

	Origin         string             `json:"origin"`
	OriginServerTS jsontime.UnixMilli `json:"origin_server_ts"`
	PDUs           []PDU              `json:"pdus"`
	EDUs           []EDU              `json:"edus,omitempty"`
}

type RequestParams

type RequestParams struct {
	ServerName   string
	Method       string
	Path         mautrix.PrefixableURLPath
	Query        url.Values
	Authenticate bool
	RequestJSON  any

	ResponseJSON any
	DontReadBody bool
}

type ResolutionCache

type ResolutionCache interface {
	StoreResolution(*ResolvedServerName)
	// LoadResolution loads a resolved server name from the cache.
	// Expired entries MUST NOT be returned.
	LoadResolution(serverName string) (*ResolvedServerName, error)
}

ResolutionCache is an interface for caching resolved server names.

type ResolveServerNameOpts

type ResolveServerNameOpts struct {
	HTTPClient *http.Client
	DNSClient  *net.Resolver
}

type ResolvedServerName

type ResolvedServerName struct {
	ServerName string    `json:"server_name"`
	HostHeader string    `json:"host_header"`
	IPPort     []string  `json:"ip_port"`
	Expires    time.Time `json:"expires"`
}

func ResolveServerName

func ResolveServerName(ctx context.Context, serverName string, opts ...*ResolveServerNameOpts) (*ResolvedServerName, error)

ResolveServerName implements the full server discovery algorithm as specified in https://spec.matrix.org/v1.11/server-server-api/#resolving-server-names

type RespBackfill

type RespBackfill struct {
	Origin         string             `json:"origin"`
	OriginServerTS jsontime.UnixMilli `json:"origin_server_ts"`
	PDUs           []PDU              `json:"pdus"`
}

type RespGetEventAuthChain

type RespGetEventAuthChain struct {
	AuthChain []PDU `json:"auth_chain"`
}

type RespGetMissingEvents

type RespGetMissingEvents struct {
	Events []PDU `json:"events"`
}

type RespGetState

type RespGetState struct {
	AuthChain []PDU `json:"auth_chain"`
	PDUs      []PDU `json:"pdus"`
}

type RespGetStateIDs

type RespGetStateIDs struct {
	AuthChain []id.EventID `json:"auth_chain_ids"`
	PDUs      []id.EventID `json:"pdu_ids"`
}

type RespMakeJoin added in v0.26.1

type RespMakeJoin struct {
	RoomVersion id.RoomVersion `json:"room_version"`
	Event       PDU            `json:"event"`
}

type RespMakeKnock added in v0.26.1

type RespMakeKnock = RespMakeJoin

type RespMakeLeave added in v0.26.1

type RespMakeLeave = RespMakeJoin

type RespOpenIDUserInfo

type RespOpenIDUserInfo struct {
	Sub id.UserID `json:"sub"`
}

type RespSendInvite added in v0.26.1

type RespSendInvite struct {
	Event PDU `json:"event"`
}

type RespSendJoin added in v0.26.1

type RespSendJoin struct {
	AuthChain      []PDU    `json:"auth_chain"`
	Event          PDU      `json:"event"`
	MembersOmitted bool     `json:"members_omitted"`
	ServersInRoom  []string `json:"servers_in_room"`
	State          []PDU    `json:"state"`
}

type RespSendKnock added in v0.26.1

type RespSendKnock struct {
	KnockRoomState []PDU `json:"knock_room_state"`
}

type RespSendTransaction

type RespSendTransaction struct {
	PDUs map[id.EventID]PDUProcessingResult `json:"pdus"`
}

type RespServerVersion

type RespServerVersion struct {
	Server ServerVersion `json:"server"`
}

RespServerVersion is the response body for the `GET /_matrix/federation/v1/version` endpoint

type RespWellKnown

type RespWellKnown struct {
	Server string `json:"m.server"`
}

RespWellKnown is the response body for the `GET /.well-known/matrix/server` endpoint.

func RequestWellKnown

func RequestWellKnown(ctx context.Context, cli *http.Client, hostname string) (*RespWellKnown, time.Time, error)

RequestWellKnown sends a request to the well-known endpoint of a server and returns the response, plus the time when the cache should expire.

type ServerAuth

type ServerAuth struct {
	Keys           KeyCache
	Client         *Client
	GetDestination func(XMatrixAuth) string
	MaxBodySize    int64
	// contains filtered or unexported fields
}

func NewServerAuth

func NewServerAuth(client *Client, keyCache KeyCache, getDestination func(auth XMatrixAuth) string) *ServerAuth

func (*ServerAuth) Authenticate

func (sa *ServerAuth) Authenticate(r *http.Request) (*http.Request, *mautrix.RespError)

func (*ServerAuth) AuthenticateMiddleware

func (sa *ServerAuth) AuthenticateMiddleware(next http.Handler) http.Handler

func (*ServerAuth) GetKeysWithCache

func (sa *ServerAuth) GetKeysWithCache(ctx context.Context, serverName string, keyID id.KeyID) (*ServerKeyResponse, error)

type ServerKeyProvider

type ServerKeyProvider interface {
	Get(r *http.Request) (serverName string, key *SigningKey)
}

ServerKeyProvider is an interface that returns private server keys for server key requests.

type ServerKeyResponse

type ServerKeyResponse struct {
	ServerName    string                         `json:"server_name"`
	VerifyKeys    map[id.KeyID]ServerVerifyKey   `json:"verify_keys"`
	OldVerifyKeys map[id.KeyID]OldVerifyKey      `json:"old_verify_keys,omitempty"`
	Signatures    map[string]map[id.KeyID]string `json:"signatures,omitempty"`
	ValidUntilTS  jsontime.UnixMilli             `json:"valid_until_ts"`

	Raw json.RawMessage `json:"-"`
}

ServerKeyResponse is the response body for the `GET /_matrix/key/v2/server` endpoint. It's also used inside the query endpoint response structs.

func (*ServerKeyResponse) HasKey

func (skr *ServerKeyResponse) HasKey(keyID id.KeyID) bool

func (*ServerKeyResponse) UnmarshalJSON

func (skr *ServerKeyResponse) UnmarshalJSON(data []byte) error

func (*ServerKeyResponse) VerifySelfSignature

func (skr *ServerKeyResponse) VerifySelfSignature() error

type ServerResolvingTransport

type ServerResolvingTransport struct {
	ResolveOpts *ResolveServerNameOpts
	Transport   *http.Transport
	Dialer      *net.Dialer
	// contains filtered or unexported fields
}

ServerResolvingTransport is an http.RoundTripper that resolves Matrix server names before sending requests. It only allows requests using the "matrix-federation" scheme.

func NewServerResolvingTransport

func NewServerResolvingTransport(cache ResolutionCache) *ServerResolvingTransport

func (*ServerResolvingTransport) DialContext

func (srt *ServerResolvingTransport) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

func (*ServerResolvingTransport) RoundTrip

func (srt *ServerResolvingTransport) RoundTrip(request *http.Request) (*http.Response, error)

type ServerVerifyKey

type ServerVerifyKey struct {
	Key id.SigningKey `json:"key"`
}

func (*ServerVerifyKey) Decode

func (svk *ServerVerifyKey) Decode() (ed25519.PublicKey, error)

type ServerVersion

type ServerVersion struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

type SigningKey

type SigningKey struct {
	ID   id.KeyID
	Pub  id.SigningKey
	Priv ed25519.PrivateKey
}

SigningKey is a Matrix federation signing key pair.

func GenerateSigningKey

func GenerateSigningKey() *SigningKey

GenerateSigningKey generates a new random signing key.

func ParseSynapseKey

func ParseSynapseKey(key string) (*SigningKey, error)

ParseSynapseKey parses a Synapse-compatible private key string into a SigningKey.

func (*SigningKey) GenerateKeyResponse

func (sk *SigningKey) GenerateKeyResponse(serverName string, oldVerifyKeys map[id.KeyID]OldVerifyKey) *ServerKeyResponse

GenerateKeyResponse generates a key response signed by this key with the given server name and optionally some old verify keys.

func (*SigningKey) SignJSON

func (sk *SigningKey) SignJSON(data any) (string, error)

func (*SigningKey) SignRawJSON

func (sk *SigningKey) SignRawJSON(data json.RawMessage) []byte

func (*SigningKey) SynapseString

func (sk *SigningKey) SynapseString() string

SynapseString returns a string representation of the private key compatible with Synapse's .signing.key file format.

The output of this function can be parsed back into a SigningKey using the ParseSynapseKey function.

type StaticServerKey

type StaticServerKey struct {
	ServerName string
	Key        *SigningKey
}

StaticServerKey is an implementation of ServerKeyProvider that always returns the same server name and key.

func (*StaticServerKey) Get

func (ssk *StaticServerKey) Get(r *http.Request) (serverName string, key *SigningKey)

type URLPath

type URLPath []any

func (URLPath) FullPath

func (fup URLPath) FullPath() []any

type XMatrixAuth

type XMatrixAuth struct {
	Origin      string
	Destination string
	KeyID       id.KeyID
	Signature   string
}

func ParseXMatrixAuth

func ParseXMatrixAuth(auth string) (xma XMatrixAuth)

func (XMatrixAuth) String

func (xma XMatrixAuth) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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