package appservice import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" _ "github.com/jinzhu/gorm/dialects/postgres" _ "github.com/jinzhu/gorm/dialects/sqlite" log "github.com/sirupsen/logrus" "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector" "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib" ) var db *gorm.DB func InitDb() error { var err error db, err = gorm.Open(config.DbType, config.DbPath) if err != nil { return err } db.AutoMigrate(&DbUserMap{}) db.Model(&DbUserMap{}).AddIndex("idx_protocol_user", "protocol", "user_id") db.AutoMigrate(&DbRoomMap{}) db.Model(&DbRoomMap{}).AddIndex("idx_protocol_room", "protocol", "room_id") db.AutoMigrate(&DbPmRoomMap{}) db.Model(&DbPmRoomMap{}).AddIndex("idx_protocol_user_account_user", "protocol", "user_id", "mx_user_id", "account_name") return nil } // User mapping between protocol user IDs and puppeted matrix ids type DbUserMap struct { gorm.Model Protocol string UserID connector.UserID MxUserID string `gorm:"index:mxuserid"` } // Room mapping between Matrix rooms and outside rooms type DbRoomMap struct { gorm.Model // Network protocol Protocol string // Room id on the bridged network RoomID connector.RoomID // Bridged room matrix id MxRoomID string `gorm:"index:mxroomid"` } // Room mapping between Matrix rooms and private messages type DbPmRoomMap struct { gorm.Model // User id and account name of the local end viewed on Matrix MxUserID string Protocol string AccountName string // User id to reach them UserID connector.UserID // Bridged room for PMs MxRoomID string `gorm:"index:mxroomoid"` } // ---- func dbGetMxRoom(protocol string, roomId connector.RoomID) (string, error) { var room DbRoomMap // Check if room exists in our mapping, // If not create it must_create := db.First(&room, DbRoomMap{ Protocol: protocol, RoomID: roomId, }).RecordNotFound() if must_create { alias := roomAlias(protocol, roomId) // Lookup alias mx_room_id, err := mxDirectoryRoom(fmt.Sprintf("#%s:%s", alias, config.MatrixDomain)) // If no alias found, create room if err != nil { name := fmt.Sprintf("%s (%s)", roomId, protocol) mx_room_id, err = mxCreateRoom(name, alias, []string{}) if err != nil { log.Printf("Could not create room for %s: %s", name, err) return "", err } } room = DbRoomMap{ Protocol: protocol, RoomID: roomId, MxRoomID: mx_room_id, } db.Create(&room) } log.Debugf("Got room id: %s", room.MxRoomID) return room.MxRoomID, nil } func dbGetMxPmRoom(protocol string, them connector.UserID, themMxId string, usMxId string, usAccount string) (string, error) { var room DbPmRoomMap must_create := db.First(&room, DbPmRoomMap{ MxUserID: usMxId, Protocol: protocol, AccountName: usAccount, UserID: them, }).RecordNotFound() if must_create { name := fmt.Sprintf("%s (%s)", them, protocol) mx_room_id, err := mxCreateDirectRoomAs(name, []string{usMxId}, themMxId) if err != nil { log.Printf("Could not create room for %s: %s", name, err) return "", err } err = mxRoomJoinAs(mx_room_id, themMxId) if err != nil { log.Printf("Could not join %s as %s", mx_room_id, themMxId) return "", err } room = DbPmRoomMap{ MxUserID: usMxId, Protocol: protocol, AccountName: usAccount, UserID: them, MxRoomID: mx_room_id, } db.Create(&room) } log.Debugf("Got PM room id: %s", room.MxRoomID) return room.MxRoomID, nil } func dbGetMxUser(protocol string, userId connector.UserID) (string, error) { var user DbUserMap must_create := db.First(&user, DbUserMap{ Protocol: protocol, UserID: userId, }).RecordNotFound() if must_create { username := userMxId(protocol, userId) err := mxRegisterUser(username) if err != nil { if mxE, ok := err.(*mxlib.MxError); !ok || mxE.ErrCode != "M_USER_IN_USE" { log.Printf("Could not register %s: %s", username, err) return "", err } } mxid := fmt.Sprintf("@%s:%s", username, config.MatrixDomain) mxProfileDisplayname(mxid, fmt.Sprintf("%s (%s)", userId, protocol)) user = DbUserMap{ Protocol: protocol, UserID: userId, MxUserID: mxid, } db.Create(&user) } return user.MxUserID, nil } func dbIsPmRoom(mxRoomId string) *DbPmRoomMap { var pm_room DbPmRoomMap if db.First(&pm_room, DbPmRoomMap{MxRoomID: mxRoomId}).RecordNotFound() { return nil } else { return &pm_room } } func dbIsPublicRoom(mxRoomId string) *DbRoomMap { var room DbRoomMap if db.First(&room, DbRoomMap{MxRoomID: mxRoomId}).RecordNotFound() { return nil } else { return &room } }