2022-10-21 14:18:02 +00:00
// mautrix-groupme - A Matrix-GroupMe puppeting bridge.
// Copyright (C) 2022 Sumner Evans, Karmanyaah Malhotra
2018-08-12 22:00:23 +00:00
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package main
2018-08-13 20:24:44 +00:00
import (
2019-05-15 20:04:09 +00:00
"fmt"
2020-05-09 11:31:06 +00:00
2020-09-24 12:25:36 +00:00
"maunium.net/go/mautrix"
2022-10-21 19:02:33 +00:00
"maunium.net/go/mautrix/bridge"
2020-05-08 19:32:22 +00:00
"maunium.net/go/mautrix/event"
2019-05-15 20:04:09 +00:00
"maunium.net/go/mautrix/format"
2020-05-08 19:32:22 +00:00
"maunium.net/go/mautrix/id"
2020-07-05 15:57:03 +00:00
2022-10-21 14:48:03 +00:00
"github.com/beeper/groupme/database"
2018-08-13 20:24:44 +00:00
)
2018-08-12 22:00:23 +00:00
2022-10-21 19:02:33 +00:00
func ( br * GMBridge ) CreatePrivatePortal ( roomID id . RoomID , brInviter bridge . User , brGhost bridge . Ghost ) {
inviter := brInviter . ( * User )
puppet := brGhost . ( * Puppet )
key := database . NewPortalKey ( puppet . GMID , inviter . GMID )
portal := br . GetPortalByGMID ( key )
2020-07-10 12:23:32 +00:00
if len ( portal . MXID ) == 0 {
2022-10-21 19:02:33 +00:00
br . createPrivatePortalFromInvite ( roomID , inviter , puppet , portal )
2020-07-10 12:23:32 +00:00
return
}
2022-10-21 19:02:33 +00:00
ok := portal . ensureUserInvited ( inviter )
if ! ok {
br . Log . Warnfln ( "Failed to invite %s to existing private chat portal %s with %s. Redirecting portal to new room..." , inviter . MXID , portal . MXID , puppet . GMID )
br . createPrivatePortalFromInvite ( roomID , inviter , puppet , portal )
2020-07-05 15:57:03 +00:00
return
}
intent := puppet . DefaultIntent ( )
2022-10-21 19:02:33 +00:00
errorMessage := fmt . Sprintf ( "You already have a private chat portal with me at [%[1]s](https://matrix.to/#/%[1]s)" , portal . MXID )
errorContent := format . RenderMarkdown ( errorMessage , true , false )
_ , _ = intent . SendMessageEvent ( roomID , event . EventMessage , errorContent )
br . Log . Debugfln ( "Leaving private chat room %s as %s after accepting invite from %s as we already have chat with the user" , roomID , puppet . MXID , inviter . MXID )
2020-07-05 15:57:03 +00:00
_ , _ = intent . LeaveRoom ( roomID )
}
2022-10-21 19:02:33 +00:00
func ( br * GMBridge ) createPrivatePortalFromInvite ( roomID id . RoomID , inviter * User , puppet * Puppet , portal * Portal ) {
// TODO check if room is already encrypted
var existingEncryption event . EncryptionEventContent
var encryptionEnabled bool
err := portal . MainIntent ( ) . StateEvent ( roomID , event . StateEncryption , "" , & existingEncryption )
if err != nil {
portal . log . Warnfln ( "Failed to check if encryption is enabled in private chat room %s" , roomID )
} else {
encryptionEnabled = existingEncryption . Algorithm == id . AlgorithmMegolmV1
}
2020-07-05 15:57:03 +00:00
portal . MXID = roomID
_ , _ = portal . MainIntent ( ) . SetRoomTopic ( portal . MXID , portal . Topic )
2022-10-21 19:02:33 +00:00
if portal . bridge . Config . Bridge . PrivateChatPortalMeta || br . Config . Bridge . Encryption . Default || encryptionEnabled {
portal . Name = puppet . Displayname
portal . AvatarURL = puppet . AvatarURL
portal . Avatar = puppet . Avatar
2020-07-05 15:57:03 +00:00
_ , _ = portal . MainIntent ( ) . SetRoomName ( portal . MXID , portal . Name )
2022-10-21 14:35:03 +00:00
_ , _ = portal . MainIntent ( ) . SetRoomAvatar ( portal . MXID , portal . AvatarURL )
2020-07-05 15:57:03 +00:00
} else {
portal . Name = ""
}
2022-10-21 19:02:33 +00:00
portal . log . Infofln ( "Created private chat portal in %s after invite from %s" , roomID , inviter . MXID )
2020-07-05 15:57:03 +00:00
intent := puppet . DefaultIntent ( )
2022-10-21 19:02:33 +00:00
if br . Config . Bridge . Encryption . Default || encryptionEnabled {
_ , err := intent . InviteUser ( roomID , & mautrix . ReqInviteUser { UserID : br . Bot . UserID } )
2020-07-05 15:57:03 +00:00
if err != nil {
portal . log . Warnln ( "Failed to invite bridge bot to enable e2be:" , err )
}
2022-10-21 19:02:33 +00:00
err = br . Bot . EnsureJoined ( roomID )
2020-07-05 15:57:03 +00:00
if err != nil {
portal . log . Warnln ( "Failed to join as bridge bot to enable e2be:" , err )
}
2022-10-21 19:02:33 +00:00
if ! encryptionEnabled {
_ , err = intent . SendStateEvent ( roomID , event . StateEncryption , "" , portal . GetEncryptionEventContent ( ) )
if err != nil {
portal . log . Warnln ( "Failed to enable e2be:" , err )
}
2020-07-05 15:57:03 +00:00
}
2022-10-21 19:02:33 +00:00
br . AS . StateStore . SetMembership ( roomID , inviter . MXID , event . MembershipJoin )
br . AS . StateStore . SetMembership ( roomID , puppet . MXID , event . MembershipJoin )
br . AS . StateStore . SetMembership ( roomID , br . Bot . UserID , event . MembershipJoin )
2020-07-05 15:57:03 +00:00
portal . Encrypted = true
}
2022-10-21 19:02:33 +00:00
portal . Update ( nil )
2020-07-05 15:57:03 +00:00
portal . UpdateBridgeInfo ( )
_ , _ = intent . SendNotice ( roomID , "Private chat portal created" )
2019-05-15 22:59:36 +00:00
}