aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-16 23:27:03 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-16 23:27:03 +0100
commitc3b941841e193c1d5c32f9d6226a95475d627249 (patch)
treeb3ac238623f6cafa08a063e886d97806cfe836bc
parenta11be80cf0c13263791f3e4f82fda461acd77130 (diff)
downloadeasybridge-c3b941841e193c1d5c32f9d6226a95475d627249.tar.gz
easybridge-c3b941841e193c1d5c32f9d6226a95475d627249.zip
Basic bridging going on both ways successfully
-rw-r--r--appservice/account.go155
-rw-r--r--appservice/db.go113
-rw-r--r--appservice/server.go47
-rw-r--r--connector/irc/irc.go5
-rw-r--r--main.go2
5 files changed, 212 insertions, 110 deletions
diff --git a/appservice/account.go b/appservice/account.go
index 230860a..553165a 100644
--- a/appservice/account.go
+++ b/appservice/account.go
@@ -4,7 +4,6 @@ import (
"fmt"
"log"
- "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
)
@@ -13,9 +12,52 @@ type Account struct {
AccountName string
Protocol string
Conn Connector
+
+ JoinedRooms map[RoomID]bool
+}
+
+var registeredAccounts = map[string]map[string]*Account{}
+
+func AddAccount(a *Account) {
+ if _, ok := registeredAccounts[a.MatrixUser]; !ok {
+ registeredAccounts[a.MatrixUser] = make(map[string]*Account)
+ }
+ registeredAccounts[a.MatrixUser][a.AccountName] = a
+}
+
+func FindAccount(mxUser string, name string) *Account {
+ if u, ok := registeredAccounts[mxUser]; ok {
+ if a, ok := u[name]; ok {
+ return a
+ }
+ }
+ return nil
+}
+
+func FindJoinedAccount(mxUser string, protocol string, room RoomID) *Account {
+ if u, ok := registeredAccounts[mxUser]; ok {
+ for _, acct := range u {
+ if acct.Protocol == protocol {
+ if j, ok := acct.JoinedRooms[room]; ok && j {
+ return acct
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func RemoveAccount(mxUser string, name string) {
+ if u, ok := registeredAccounts[mxUser]; ok {
+ delete(u, name)
+ }
}
+// ----
+
func (a *Account) Joined(roomId RoomID) {
+ a.JoinedRooms[roomId] = true
+
mx_room_id, err := dbGetMxRoom(a.Protocol, roomId)
if err != nil {
return
@@ -30,6 +72,8 @@ func (a *Account) Joined(roomId RoomID) {
}
func (a *Account) Left(roomId RoomID) {
+ delete(a.JoinedRooms, roomId)
+
mx_room_id, err := dbGetMxRoom(a.Protocol, roomId)
if err != nil {
return
@@ -112,112 +156,3 @@ func (a *Account) Event(event *Event) {
}
}
-// ----
-
-func dbGetMxRoom(protocol string, roomId 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.Printf("Got room id: %s", room.MxRoomID)
-
- return room.MxRoomID, nil
-}
-
-func dbGetMxPmRoom(protocol string, them 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.Printf("Got PM room id: %s", room.MxRoomID)
-
- return room.MxRoomID, nil
-}
-
-func dbGetMxUser(protocol string, userId 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
-}
-
diff --git a/appservice/db.go b/appservice/db.go
index c2af428..fad78ba 100644
--- a/appservice/db.go
+++ b/appservice/db.go
@@ -1,7 +1,12 @@
package appservice
import (
+ "fmt"
+ "log"
+
+ "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
+
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/postgres"
@@ -69,3 +74,111 @@ type DbPmRoomMap struct {
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.Printf("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.Printf("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
+}
diff --git a/appservice/server.go b/appservice/server.go
index 3f52119..ed206ee 100644
--- a/appservice/server.go
+++ b/appservice/server.go
@@ -8,6 +8,7 @@ import (
"net/http"
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
+ "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
"github.com/gorilla/mux"
)
@@ -72,8 +73,54 @@ func handleTxn(w http.ResponseWriter, r *http.Request) {
}
log.Printf("Got transaction %#v\n", txn)
+
+ for i := range txn.Events {
+ handleTxnEvent(&txn.Events[i])
+ }
+
fmt.Fprintf(w, "{}\n")
} else {
http.Error(w, "Expected PUT request", http.StatusBadRequest)
}
}
+
+func handleTxnEvent(e *mxlib.Event) {
+ if e.Type == "m.room.message" {
+ ev := &connector.Event{
+ Type: connector.EVENT_MESSAGE,
+ Text: e.Content["body"].(string),
+ }
+ typ := e.Content["msgtype"].(string)
+ if typ == "m.emote" {
+ ev.Type = connector.EVENT_MESSAGE
+ }
+
+ // Look up if this is a private message room
+ var pm_room DbPmRoomMap
+ is_pm_room := !db.First(&pm_room, DbPmRoomMap{
+ MxRoomID: e.RoomId,
+ }).RecordNotFound()
+ if is_pm_room {
+ acct := FindAccount(pm_room.MxUserID, pm_room.AccountName)
+ if acct != nil && e.Sender == pm_room.MxUserID {
+ ev.Author = acct.Conn.User()
+ ev.Recipient = pm_room.UserID
+ acct.Conn.Send(ev)
+ }
+ }
+
+ // Look up if this is a regular room
+ var room DbRoomMap
+ is_room := !db.First(&room, DbRoomMap{
+ MxRoomID: e.RoomId,
+ }).RecordNotFound()
+ if is_room {
+ acct := FindJoinedAccount(e.Sender, room.Protocol, room.RoomID)
+ if acct != nil {
+ ev.Author = acct.Conn.User()
+ ev.Room = room.RoomID
+ acct.Conn.Send(ev)
+ }
+ }
+ }
+}
diff --git a/connector/irc/irc.go b/connector/irc/irc.go
index e57d71b..77359d0 100644
--- a/connector/irc/irc.go
+++ b/connector/irc/irc.go
@@ -170,6 +170,11 @@ func (irc *IRC) Leave(roomId RoomID) {
}
func (irc *IRC) Send(event *Event) error {
+ // Workaround girc bug
+ if event.Text[0] == ':' {
+ event.Text = " " + event.Text
+ }
+
dest := ""
if event.Room != "" {
ch, err := irc.checkRoomId(event.Room)
diff --git a/main.go b/main.go
index 0f8f3f0..eeff01e 100644
--- a/main.go
+++ b/main.go
@@ -188,8 +188,10 @@ func main() {
AccountName: name,
Protocol: params.Protocol,
Conn: conn,
+ JoinedRooms: map[connector.RoomID]bool{},
}
conn.SetHandler(account)
+ appservice.AddAccount(account)
go connectAndJoin(conn, params)
}
}