From c3a44068c01a3b01fa40ca56704b82c0a7c2ae34 Mon Sep 17 00:00:00 2001 From: Malte E Date: Wed, 31 Jan 2024 20:38:20 +0100 Subject: [PATCH] bridge join rule, disappearing messages timer via group change S->M --- config/upgrade.go | 1 + pkg/signalmeow/groups.go | 50 ++++++++++++++++++------------- portal.go | 65 ++++++++++++++++++++++++++++++++-------- 3 files changed, 82 insertions(+), 34 deletions(-) diff --git a/config/upgrade.go b/config/upgrade.go index ba0daf97..eb924d2c 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -93,6 +93,7 @@ func DoUpgrade(helper *up.Helper) { helper.Copy(up.Bool, "bridge", "message_error_notices") helper.Copy(up.Bool, "bridge", "sync_direct_chat_list") helper.Copy(up.Bool, "bridge", "resend_bridge_info") + helper.Copy(up.Bool, "bridge", "public_portals") helper.Copy(up.Bool, "bridge", "caption_in_message") helper.Copy(up.Bool, "bridge", "federate_rooms") helper.Copy(up.Map, "bridge", "double_puppet_server_map") diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 5d98f7f1..b1af597c 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -140,27 +140,27 @@ type BannedMember struct { type GroupChange struct { groupMasterKey types.SerializedGroupMasterKey - Revision uint32 - AddMembers []*AddMember - DeleteMembers []*uuid.UUID - ModifyMemberRoles []*RoleMember - ModifyMemberProfileKeys []*ProfileKeyMember - AddPendingMembers []*PendingMember - DeletePendingMembers []*uuid.UUID - PromotePendingMembers []*ProfileKeyMember - ModifyTitle *string - ModifyAvatar *string - ModifyDisappearingMessagesTimer *uint32 - ModifyAttributesAccess *AccessControl - ModifyMemberAccess *AccessControl - ModifyAddFromInviteLinkAccess *AccessControl - AddRequestingMembers []*RequestingMember - DeleteRequestingMembers []*uuid.UUID - PromoteRequestingMembers []*RoleMember - ModifyDescription *string - ModifyAnnouncementsOnly *bool - AddBannedMembers []*BannedMember - DeleteBannedMembers []*uuid.UUID + Revision uint32 + AddMembers []*AddMember + DeleteMembers []*uuid.UUID + ModifyMemberRoles []*RoleMember + ModifyMemberProfileKeys []*ProfileKeyMember + AddPendingMembers []*PendingMember + DeletePendingMembers []*uuid.UUID + PromotePendingMembers []*ProfileKeyMember + ModifyTitle *string + ModifyAvatar *string + ModifyDisappearingMessagesDuration *uint32 + ModifyAttributesAccess *AccessControl + ModifyMemberAccess *AccessControl + ModifyAddFromInviteLinkAccess *AccessControl + AddRequestingMembers []*RequestingMember + DeleteRequestingMembers []*uuid.UUID + PromoteRequestingMembers []*RoleMember + ModifyDescription *string + ModifyAnnouncementsOnly *bool + AddBannedMembers []*BannedMember + DeleteBannedMembers []*uuid.UUID //PromotePendingPniAciMembers []*PromotePniAciMember //ModifyInviteLinkPassword []byte } @@ -922,6 +922,14 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp if encryptedActions.ModifyAnnouncementsOnly != nil { decryptedGroupChange.ModifyAnnouncementsOnly = &encryptedActions.ModifyAnnouncementsOnly.AnnouncementsOnly } + if encryptedActions.ModifyDisappearingMessagesTimer != nil && len(encryptedActions.ModifyDisappearingMessagesTimer.Timer) > 0 { + timerBlob, err := decryptGroupPropertyIntoBlob(groupSecretParams, encryptedActions.ModifyDisappearingMessagesTimer.Timer) + if err != nil { + return nil, err + } + newDisappaeringMessagesDuration := timerBlob.GetDisappearingMessagesDuration() + decryptedGroupChange.ModifyDisappearingMessagesDuration = &newDisappaeringMessagesDuration + } return decryptedGroupChange, nil } diff --git a/portal.go b/portal.go index f5e57a67..e2ac1e45 100644 --- a/portal.go +++ b/portal.go @@ -933,6 +933,9 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou if groupChange.ModifyAvatar != nil { portal.updateAvatarWithInfo(ctx, source, groupChange, sender) } + if groupChange.ModifyDisappearingMessagesDuration != nil { + portal.updateExpirationTimer(ctx, *groupChange.ModifyDisappearingMessagesDuration) + } intent := sender.IntentFor(portal) modifyRoles := groupChange.ModifyMemberRoles for _, deleteBannedMember := range groupChange.DeleteBannedMembers { @@ -950,21 +953,46 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } modifyRoles = append(modifyRoles, &signalmeow.RoleMember{UserID: addMember.UserID, Role: addMember.Role}) } - // signal deletes, then bans, matrix can ban directly. We might want to reduce noise by removing - // members that are to be banned from those to be deleted for _, deleteMember := range groupChange.DeleteMembers { + banned := false + for _, addBannedMember := range groupChange.AddBannedMembers { + if *&addBannedMember.UserID == *deleteMember { + banned = true + } + } + if banned { + continue + } _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deleteMember, event.MembershipLeave, "deleted") if err != nil { log.Warn().Stringer("signal_user_id", deleteMember).Msg("Couldn't get puppet for removal") } } for _, deletePendingMember := range groupChange.DeletePendingMembers { + banned := false + for _, addBannedMember := range groupChange.AddBannedMembers { + if *&addBannedMember.UserID == *deletePendingMember { + banned = true + } + } + if banned { + continue + } _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deletePendingMember, event.MembershipLeave, "invite withdrawn") if err != nil { log.Warn().Stringer("signal_user_id", deletePendingMember).Msg("Couldn't get puppet for removal") } } for _, deleteRequestingMember := range groupChange.DeleteRequestingMembers { + banned := false + for _, addBannedMember := range groupChange.AddBannedMembers { + if *&addBannedMember.UserID == *deleteRequestingMember { + banned = true + } + } + if banned { + continue + } _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deleteRequestingMember, event.MembershipLeave, "request rejected") if err != nil { log.Warn().Stringer("signal_user_id", deleteRequestingMember).Msg("Couldn't get puppet for removal") @@ -1066,15 +1094,26 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } } } - // TODO: join rules - // if groupChange.ModifyAddFromInviteLinkAccess != nil { - // joinRule := event.JoinRuleInvite - // if *groupChange.ModifyAddFromInviteLinkAccess == signalmeow.AccessControl_ADMINISTRATOR { - // joinRule = event.JoinRuleKnock - // } else if *groupChange.ModifyAddFromInviteLinkAccess == signalmeow.AccessControl_ANY && portal.bridge.Config.Bridge.PublicPortals { - // joinRule = event.JoinRulePublic - // } - // } + if groupChange.ModifyAddFromInviteLinkAccess != nil { + joinRule := event.JoinRuleInvite + if *groupChange.ModifyAddFromInviteLinkAccess == signalmeow.AccessControl_ADMINISTRATOR { + joinRule = event.JoinRuleKnock + } else if *groupChange.ModifyAddFromInviteLinkAccess == signalmeow.AccessControl_ANY && portal.bridge.Config.Bridge.PublicPortals { + joinRule = event.JoinRulePublic + } + _, err = intent.SendMassagedStateEvent(ctx, portal.MXID, event.StateJoinRules, "", &event.JoinRulesEventContent{JoinRule: joinRule}, int64(ts)) + if errors.Is(err, mautrix.MForbidden) { + _, err = portal.MainIntent().SendMassagedStateEvent(ctx, portal.MXID, event.StateJoinRules, "", &event.JoinRulesEventContent{JoinRule: joinRule}, int64(ts)) + } + if err != nil { + log.Err(err).Msg("Couldn't set join rule") + } + } + err = portal.Update(ctx) + if err != nil { + log.Err(err).Msg("Failed to save portal in database after processing group change") + } + portal.UpdateBridgeInfo(ctx) } func (portal *Portal) sendMembershipForPuppetAndUser(ctx context.Context, sender *Puppet, target uuid.UUID, membership event.Membership, action string) (puppet *Puppet, err error) { @@ -1795,7 +1834,7 @@ func (portal *Portal) UpdateDMInfo(ctx context.Context, forceSave bool) { if update { err := portal.Update(ctx) if err != nil { - log.Err(err).Msg("Failed to save portal in database after updatin group info") + log.Err(err).Msg("Failed to save portal in database after updating group info") } portal.UpdateBridgeInfo(ctx) } @@ -1847,7 +1886,7 @@ func (portal *Portal) UpdateGroupInfo(ctx context.Context, source *User, info *s if update { err := portal.Update(ctx) if err != nil { - log.Err(err).Msg("Failed to save portal in database after updatin group info") + log.Err(err).Msg("Failed to save portal in database after updating group info") } portal.UpdateBridgeInfo(ctx) }