forked from MirrorHub/mautrix-whatsapp
Merge remote-tracking branch 'HelderFSFerreira/createSpace'
This commit is contained in:
commit
3a9b3ab41f
6 changed files with 92 additions and 11 deletions
12
database/upgrades/2021-12-28-management-space.go
Normal file
12
database/upgrades/2021-12-28-management-space.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package upgrades
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
upgrades[32] = upgrade{"Store space in user table", func(tx *sql.Tx, ctx context) error {
|
||||||
|
_, err := tx.Exec(`ALTER TABLE "user" ADD COLUMN space_room TEXT NOT NULL DEFAULT ''`)
|
||||||
|
return err
|
||||||
|
}}
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ type upgrade struct {
|
||||||
fn upgradeFunc
|
fn upgradeFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
const NumberOfUpgrades = 33
|
const NumberOfUpgrades = 34
|
||||||
|
|
||||||
var upgrades [NumberOfUpgrades]upgrade
|
var upgrades [NumberOfUpgrades]upgrade
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (uq *UserQuery) New() *User {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uq *UserQuery) GetAll() (users []*User) {
|
func (uq *UserQuery) GetAll() (users []*User) {
|
||||||
rows, err := uq.db.Query(`SELECT mxid, username, agent, device, management_room FROM "user"`)
|
rows, err := uq.db.Query(`SELECT mxid, username, agent, device, management_room, space_room FROM "user"`)
|
||||||
if err != nil || rows == nil {
|
if err != nil || rows == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func (uq *UserQuery) GetAll() (users []*User) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uq *UserQuery) GetByMXID(userID id.UserID) *User {
|
func (uq *UserQuery) GetByMXID(userID id.UserID) *User {
|
||||||
row := uq.db.QueryRow(`SELECT mxid, username, agent, device, management_room FROM "user" WHERE mxid=$1`, userID)
|
row := uq.db.QueryRow(`SELECT mxid, username, agent, device, management_room, space_room FROM "user" WHERE mxid=$1`, userID)
|
||||||
if row == nil {
|
if row == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ func (uq *UserQuery) GetByMXID(userID id.UserID) *User {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uq *UserQuery) GetByUsername(username string) *User {
|
func (uq *UserQuery) GetByUsername(username string) *User {
|
||||||
row := uq.db.QueryRow(`SELECT mxid, username, agent, device, management_room FROM "user" WHERE username=$1`, username)
|
row := uq.db.QueryRow(`SELECT mxid, username, agent, device, management_room, space_room FROM "user" WHERE username=$1`, username)
|
||||||
if row == nil {
|
if row == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -72,12 +72,13 @@ type User struct {
|
||||||
MXID id.UserID
|
MXID id.UserID
|
||||||
JID types.JID
|
JID types.JID
|
||||||
ManagementRoom id.RoomID
|
ManagementRoom id.RoomID
|
||||||
|
SpaceRoom id.RoomID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Scan(row Scannable) *User {
|
func (user *User) Scan(row Scannable) *User {
|
||||||
var username sql.NullString
|
var username sql.NullString
|
||||||
var device, agent sql.NullByte
|
var device, agent sql.NullByte
|
||||||
err := row.Scan(&user.MXID, &username, &agent, &device, &user.ManagementRoom)
|
err := row.Scan(&user.MXID, &username, &agent, &device, &user.ManagementRoom, &user.SpaceRoom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != sql.ErrNoRows {
|
if err != sql.ErrNoRows {
|
||||||
user.log.Errorln("Database scan failed:", err)
|
user.log.Errorln("Database scan failed:", err)
|
||||||
|
@ -112,16 +113,16 @@ func (user *User) devicePtr() *uint8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Insert() {
|
func (user *User) Insert() {
|
||||||
_, err := user.db.Exec(`INSERT INTO "user" (mxid, username, agent, device, management_room) VALUES ($1, $2, $3, $4, $5)`,
|
_, err := user.db.Exec(`INSERT INTO "user" (mxid, username, agent, device, management_room, space_room) VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||||
user.MXID, user.usernamePtr(), user.agentPtr(), user.devicePtr(), user.ManagementRoom)
|
user.MXID, user.usernamePtr(), user.agentPtr(), user.devicePtr(), user.ManagementRoom, user.SpaceRoom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user.log.Warnfln("Failed to insert %s: %v", user.MXID, err)
|
user.log.Warnfln("Failed to insert %s: %v", user.MXID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Update() {
|
func (user *User) Update() {
|
||||||
_, err := user.db.Exec(`UPDATE "user" SET username=$1, agent=$2, device=$3, management_room=$4 WHERE mxid=$5`,
|
_, err := user.db.Exec(`UPDATE "user" SET username=$1, agent=$2, device=$3, management_room=$4, space_room=$5 WHERE mxid=$6`,
|
||||||
user.usernamePtr(), user.agentPtr(), user.devicePtr(), user.ManagementRoom, user.MXID)
|
user.usernamePtr(), user.agentPtr(), user.devicePtr(), user.ManagementRoom, user.SpaceRoom, user.MXID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user.log.Warnfln("Failed to update %s: %v", user.MXID, err)
|
user.log.Warnfln("Failed to update %s: %v", user.MXID, err)
|
||||||
}
|
}
|
||||||
|
|
3
main.go
3
main.go
|
@ -179,6 +179,8 @@ type Bridge struct {
|
||||||
usersByMXID map[id.UserID]*User
|
usersByMXID map[id.UserID]*User
|
||||||
usersByUsername map[string]*User
|
usersByUsername map[string]*User
|
||||||
usersLock sync.Mutex
|
usersLock sync.Mutex
|
||||||
|
spaceRooms map[id.RoomID]*User
|
||||||
|
spaceRoomsLock sync.Mutex
|
||||||
managementRooms map[id.RoomID]*User
|
managementRooms map[id.RoomID]*User
|
||||||
managementRoomsLock sync.Mutex
|
managementRoomsLock sync.Mutex
|
||||||
portalsByMXID map[id.RoomID]*Portal
|
portalsByMXID map[id.RoomID]*Portal
|
||||||
|
@ -479,6 +481,7 @@ func main() {
|
||||||
(&Bridge{
|
(&Bridge{
|
||||||
usersByMXID: make(map[id.UserID]*User),
|
usersByMXID: make(map[id.UserID]*User),
|
||||||
usersByUsername: make(map[string]*User),
|
usersByUsername: make(map[string]*User),
|
||||||
|
spaceRooms: make(map[id.RoomID]*User),
|
||||||
managementRooms: make(map[id.RoomID]*User),
|
managementRooms: make(map[id.RoomID]*User),
|
||||||
portalsByMXID: make(map[id.RoomID]*Portal),
|
portalsByMXID: make(map[id.RoomID]*Portal),
|
||||||
portalsByJID: make(map[database.PortalKey]*Portal),
|
portalsByJID: make(map[database.PortalKey]*Portal),
|
||||||
|
|
12
portal.go
12
portal.go
|
@ -1141,6 +1141,8 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
|
||||||
portal.ensureUserInvited(user)
|
portal.ensureUserInvited(user)
|
||||||
user.syncChatDoublePuppetDetails(portal, true)
|
user.syncChatDoublePuppetDetails(portal, true)
|
||||||
|
|
||||||
|
portal.addToSpace(user.getSpaceRoom(), portal.MXID, portal.bridge.Config.Homeserver.Domain)
|
||||||
|
|
||||||
if groupInfo != nil {
|
if groupInfo != nil {
|
||||||
portal.SyncParticipants(user, groupInfo)
|
portal.SyncParticipants(user, groupInfo)
|
||||||
if groupInfo.IsAnnounce {
|
if groupInfo.IsAnnounce {
|
||||||
|
@ -1176,6 +1178,16 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) addToSpace(spaceID id.RoomID, portalID id.RoomID, homeserverDomain string) {
|
||||||
|
|
||||||
|
parentSpaceContent := make(map[string]interface{})
|
||||||
|
parentSpaceContent["via"] = []string{homeserverDomain}
|
||||||
|
|
||||||
|
portal.log.Debugfln("adding room %s to the space %s", portalID, spaceID)
|
||||||
|
|
||||||
|
portal.MainIntent().SendStateEvent(spaceID, event.Type{Type: "m.space.child", Class: event.StateEventType}, portalID.String(), parentSpaceContent)
|
||||||
|
}
|
||||||
|
|
||||||
func (portal *Portal) IsPrivateChat() bool {
|
func (portal *Portal) IsPrivateChat() bool {
|
||||||
return portal.Key.JID.Server == types.DefaultUserServer
|
return portal.Key.JID.Server == types.DefaultUserServer
|
||||||
}
|
}
|
||||||
|
|
57
user.go
57
user.go
|
@ -57,8 +57,9 @@ type User struct {
|
||||||
Whitelisted bool
|
Whitelisted bool
|
||||||
RelayWhitelisted bool
|
RelayWhitelisted bool
|
||||||
|
|
||||||
mgmtCreateLock sync.Mutex
|
mgmtCreateLock sync.Mutex
|
||||||
connLock sync.Mutex
|
spaceCreateLock sync.Mutex
|
||||||
|
connLock sync.Mutex
|
||||||
|
|
||||||
historySyncs chan *events.HistorySync
|
historySyncs chan *events.HistorySync
|
||||||
prevBridgeStatus *BridgeState
|
prevBridgeStatus *BridgeState
|
||||||
|
@ -179,6 +180,58 @@ func (bridge *Bridge) NewUser(dbUser *database.User) *User {
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (user *User) getSpaceRoom() id.RoomID {
|
||||||
|
var roomID id.RoomID
|
||||||
|
|
||||||
|
if len(user.SpaceRoom) == 0 {
|
||||||
|
//TODO check if Spaces creation is enabled by config
|
||||||
|
|
||||||
|
//Create Space
|
||||||
|
user.log.Debugln("Locking to create space.")
|
||||||
|
user.spaceCreateLock.Lock()
|
||||||
|
defer user.spaceCreateLock.Unlock()
|
||||||
|
|
||||||
|
if len(user.SpaceRoom) != 0 {
|
||||||
|
roomID = user.SpaceRoom
|
||||||
|
user.log.Debugln("Returning space after lock" + user.SpaceRoom)
|
||||||
|
} else {
|
||||||
|
creationContent := make(map[string]interface{})
|
||||||
|
creationContent["type"] = "m.space"
|
||||||
|
|
||||||
|
user.log.Debugln("Creating a new space for the user")
|
||||||
|
|
||||||
|
user.log.Debugln("Inviting user " + user.MXID)
|
||||||
|
var invite []id.UserID
|
||||||
|
invite = append(invite, user.MXID)
|
||||||
|
|
||||||
|
resp, err := user.bridge.Bot.CreateRoom(&mautrix.ReqCreateRoom{
|
||||||
|
Visibility: "private",
|
||||||
|
Name: "WhatsApp",
|
||||||
|
Topic: "WhatsApp bridge Space",
|
||||||
|
Invite: invite,
|
||||||
|
CreationContent: creationContent,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
user.log.Errorln("Failed to auto-create space room:", err)
|
||||||
|
} else {
|
||||||
|
user.setSpaceRoom(resp.RoomID)
|
||||||
|
roomID = resp.RoomID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
user.log.Debugln("Space found" + user.SpaceRoom)
|
||||||
|
roomID = user.SpaceRoom
|
||||||
|
}
|
||||||
|
|
||||||
|
return roomID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (user *User) setSpaceRoom(spaceID id.RoomID) {
|
||||||
|
user.SpaceRoom = spaceID
|
||||||
|
user.bridge.spaceRooms[user.SpaceRoom] = user
|
||||||
|
user.Update()
|
||||||
|
}
|
||||||
|
|
||||||
func (user *User) GetManagementRoom() id.RoomID {
|
func (user *User) GetManagementRoom() id.RoomID {
|
||||||
if len(user.ManagementRoom) == 0 {
|
if len(user.ManagementRoom) == 0 {
|
||||||
user.mgmtCreateLock.Lock()
|
user.mgmtCreateLock.Lock()
|
||||||
|
|
Loading…
Reference in a new issue