aboutsummaryrefslogblamecommitdiff
path: root/appservice/db.go
blob: 512e7b5a416bcb95333cba07f44458fe820a68b8 (plain) (tree)
1
2
3
4
5
6
7
8
9


                  
             
 



                                                    
                                        
 
                                                           
                                                       











                                                         








                                                                                                                                

                  





                                                                 
                                 





















                                                                     

                          


                                
                               




                                                








                                                                            
                                 


















                                                                                                     
                                         



                                             
                                                    







                                                                                                                              

                                      
                                       
                                  
















                                                                                         

                                              
                                               

                                                


                                
                                                       








                                                                            
                                 
















                                                                                                   
                                         






                                       

















                                                                                 
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
	}
}