mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 14:25:53 +01:00
client,crypto,appservice: add MSC3202 features
This commit is contained in:
parent
5f49ca683a
commit
238cacf2d5
6 changed files with 66 additions and 14 deletions
|
|
@ -28,6 +28,7 @@ type Registration struct {
|
|||
|
||||
SoruEphemeralEvents bool `yaml:"de.sorunome.msc2409.push_ephemeral,omitempty" json:"de.sorunome.msc2409.push_ephemeral,omitempty"`
|
||||
EphemeralEvents bool `yaml:"push_ephemeral,omitempty" json:"push_ephemeral,omitempty"`
|
||||
MSC3202 bool `yaml:"org.matrix.msc3202,omitempty" json:"org.matrix.msc3202,omitempty"`
|
||||
}
|
||||
|
||||
// CreateRegistration creates a Registration with random appservice and homeserver tokens.
|
||||
|
|
|
|||
|
|
@ -110,6 +110,9 @@ type Client struct {
|
|||
// Should the ?user_id= query parameter be set in requests?
|
||||
// See https://spec.matrix.org/v1.6/application-service-api/#identity-assertion
|
||||
SetAppServiceUserID bool
|
||||
// Should the org.matrix.msc3202.device_id query parameter be set in requests?
|
||||
// See https://github.com/matrix-org/matrix-spec-proposals/pull/3202
|
||||
SetAppServiceDeviceID bool
|
||||
|
||||
syncingID uint32 // Identifies the current Sync. Only one Sync can be active at any given time.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ type CryptoHelper struct {
|
|||
|
||||
LoginAs *mautrix.ReqLogin
|
||||
|
||||
ASEventProcessor crypto.ASEventProcessor
|
||||
|
||||
DBAccountID string
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +60,7 @@ func NewCryptoHelper(cli *mautrix.Client, pickleKey []byte, store any) (*CryptoH
|
|||
return nil, fmt.Errorf("pickle key must be provided")
|
||||
}
|
||||
_, isExtensible := cli.Syncer.(mautrix.ExtensibleSyncer)
|
||||
if !isExtensible {
|
||||
if !cli.SetAppServiceDeviceID && !isExtensible {
|
||||
return nil, fmt.Errorf("the client syncer must implement ExtensibleSyncer")
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +113,11 @@ func (helper *CryptoHelper) Init(ctx context.Context) error {
|
|||
}
|
||||
syncer, ok := helper.client.Syncer.(mautrix.ExtensibleSyncer)
|
||||
if !ok {
|
||||
return fmt.Errorf("the client syncer must implement ExtensibleSyncer")
|
||||
if !helper.client.SetAppServiceDeviceID {
|
||||
return fmt.Errorf("the client syncer must implement ExtensibleSyncer")
|
||||
} else if helper.ASEventProcessor == nil {
|
||||
return fmt.Errorf("an appservice must be provided when using appservice mode encryption")
|
||||
}
|
||||
}
|
||||
|
||||
var stateStore crypto.StateStore
|
||||
|
|
@ -140,7 +146,27 @@ func (helper *CryptoHelper) Init(ctx context.Context) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to find existing device ID: %w", err)
|
||||
}
|
||||
if helper.LoginAs != nil {
|
||||
if helper.LoginAs != nil && helper.LoginAs.Type == mautrix.AuthTypeAppservice && helper.client.SetAppServiceDeviceID {
|
||||
if storedDeviceID == "" {
|
||||
helper.log.Debug().
|
||||
Str("username", helper.LoginAs.Identifier.User).
|
||||
Msg("Logging in with appservice")
|
||||
var resp *mautrix.RespLogin
|
||||
resp, err = helper.client.Login(ctx, helper.LoginAs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
managedCryptoStore.DeviceID = resp.DeviceID
|
||||
helper.client.DeviceID = resp.DeviceID
|
||||
} else {
|
||||
helper.log.Debug().
|
||||
Str("username", helper.LoginAs.Identifier.User).
|
||||
Stringer("device_id", storedDeviceID).
|
||||
Msg("Using existing device")
|
||||
managedCryptoStore.DeviceID = storedDeviceID
|
||||
helper.client.DeviceID = storedDeviceID
|
||||
}
|
||||
} else if helper.LoginAs != nil {
|
||||
if storedDeviceID != "" {
|
||||
helper.LoginAs.DeviceID = storedDeviceID
|
||||
}
|
||||
|
|
@ -177,16 +203,29 @@ func (helper *CryptoHelper) Init(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
syncer.OnSync(helper.mach.ProcessSyncResponse)
|
||||
syncer.OnEventType(event.StateMember, helper.mach.HandleMemberEvent)
|
||||
if _, ok = helper.client.Syncer.(mautrix.DispatchableSyncer); ok {
|
||||
syncer.OnEventType(event.EventEncrypted, helper.HandleEncrypted)
|
||||
if syncer != nil {
|
||||
syncer.OnSync(helper.mach.ProcessSyncResponse)
|
||||
syncer.OnEventType(event.StateMember, helper.mach.HandleMemberEvent)
|
||||
if _, ok = helper.client.Syncer.(mautrix.DispatchableSyncer); ok {
|
||||
syncer.OnEventType(event.EventEncrypted, helper.HandleEncrypted)
|
||||
} else {
|
||||
helper.log.Warn().Msg("Client syncer does not implement DispatchableSyncer. Events will not be decrypted automatically.")
|
||||
}
|
||||
if helper.managedStateStore != nil {
|
||||
syncer.OnEvent(helper.client.StateStoreSyncHandler)
|
||||
}
|
||||
} else {
|
||||
helper.log.Warn().Msg("Client syncer does not implement DispatchableSyncer. Events will not be decrypted automatically.")
|
||||
helper.mach.AddAppserviceListener(helper.ASEventProcessor)
|
||||
helper.ASEventProcessor.On(event.EventEncrypted, helper.HandleEncrypted)
|
||||
}
|
||||
if helper.managedStateStore != nil {
|
||||
syncer.OnEvent(helper.client.StateStoreSyncHandler)
|
||||
|
||||
if helper.client.SetAppServiceDeviceID {
|
||||
err = helper.mach.ShareKeys(ctx, -1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to share keys: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +320,11 @@ func (helper *CryptoHelper) HandleEncrypted(ctx context.Context, evt *event.Even
|
|||
|
||||
func (helper *CryptoHelper) postDecrypt(ctx context.Context, decrypted *event.Event) {
|
||||
decrypted.Mautrix.EventSource |= event.SourceDecrypted
|
||||
helper.client.Syncer.(mautrix.DispatchableSyncer).Dispatch(ctx, decrypted)
|
||||
if helper.ASEventProcessor != nil {
|
||||
helper.ASEventProcessor.Dispatch(ctx, decrypted)
|
||||
} else {
|
||||
helper.client.Syncer.(mautrix.DispatchableSyncer).Dispatch(ctx, decrypted)
|
||||
}
|
||||
}
|
||||
|
||||
func (helper *CryptoHelper) RequestSession(ctx context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, userID id.UserID, deviceID id.DeviceID) {
|
||||
|
|
|
|||
|
|
@ -208,13 +208,14 @@ func (mach *OlmMachine) OwnIdentity() *id.Device {
|
|||
}
|
||||
}
|
||||
|
||||
type asEventProcessor interface {
|
||||
type ASEventProcessor interface {
|
||||
On(evtType event.Type, handler func(ctx context.Context, evt *event.Event))
|
||||
OnOTK(func(ctx context.Context, otk *mautrix.OTKCount))
|
||||
OnDeviceList(func(ctx context.Context, lists *mautrix.DeviceLists, since string))
|
||||
Dispatch(ctx context.Context, evt *event.Event)
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) AddAppserviceListener(ep asEventProcessor) {
|
||||
func (mach *OlmMachine) AddAppserviceListener(ep ASEventProcessor) {
|
||||
// ToDeviceForwardedRoomKey and ToDeviceRoomKey should only be present inside encrypted to-device events
|
||||
ep.On(event.ToDeviceEncrypted, mach.HandleToDeviceEvent)
|
||||
ep.On(event.ToDeviceRoomKeyRequest, mach.HandleToDeviceEvent)
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ func (otk *OneTimeKey) MarshalJSON() ([]byte, error) {
|
|||
|
||||
type ReqUploadKeys struct {
|
||||
DeviceKeys *DeviceKeys `json:"device_keys,omitempty"`
|
||||
OneTimeKeys map[id.KeyID]OneTimeKey `json:"one_time_keys"`
|
||||
OneTimeKeys map[id.KeyID]OneTimeKey `json:"one_time_keys,omitempty"`
|
||||
}
|
||||
|
||||
type ReqKeysSignatures struct {
|
||||
|
|
|
|||
4
url.go
4
url.go
|
|
@ -102,6 +102,10 @@ func (cli *Client) BuildURLWithQuery(urlPath PrefixableURLPath, urlQuery map[str
|
|||
if cli.SetAppServiceUserID {
|
||||
query.Set("user_id", string(cli.UserID))
|
||||
}
|
||||
if cli.SetAppServiceDeviceID && cli.DeviceID != "" {
|
||||
query.Set("device_id", string(cli.DeviceID))
|
||||
query.Set("org.matrix.msc3202.device_id", string(cli.DeviceID))
|
||||
}
|
||||
if urlQuery != nil {
|
||||
for k, v := range urlQuery {
|
||||
query.Set(k, v)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue