Allow _ezbr_ to be put in suffix of usernames/room aliases instead of prefix
This commit is contained in:
parent
38a3f1bdb1
commit
2649e41c85
6 changed files with 92 additions and 27 deletions
19
README.md
19
README.md
|
@ -48,11 +48,22 @@ Easybridge is configured using a single JSON configuration file, which contains
|
|||
a dictionnary whose keys are the following:
|
||||
|
||||
- `log_level`: what log level Easybridge runs with (trace, debug, info, warn, error, fatal, panic). **Warning:** in `trace` level, the content of all calls to the Matrix API and some other information will be dumped, exposing user's credentials and messages. In `debug` level, room join/leave information will be exposed. The `info` level (default) does not expose any user's private information.
|
||||
- `easybridge_avatar`: path to the image that Easybridge uses as an avatar on Matrix
|
||||
|
||||
### Matrix configuration
|
||||
|
||||
- `registration`: path to the YAML appservice registration file
|
||||
- `appservice_bind_addr`: on what IP/port to bind as a Matrix app service (HTTP only, no HTTPS)
|
||||
- `homeserver_url`: HTTP address of the Matrix homeserver
|
||||
- `matrix_domain`: the domain name of the Matrix homeserver (i.e. the domain used in user identifiers, room identifiers, etc)
|
||||
- `name_format`: the format of identifiers that are created on Matrix for users and room aliases. `{}` is replaced by the concatenation of user/room identifier and protocol. Typically you want either `_ezbr_{}` or `{}_ezbr`, the latter having the advantage that the briged user's names are then used as prefixes for the created identifiers.
|
||||
|
||||
### Web interface configuration
|
||||
|
||||
- `web_bind_addr`: on what IP/port to bind for the web interface that allows adding and configuring accounts (HTTP only, no HTTPS, use a reverse proxy for that)
|
||||
- `web_url`: the outside HTTP/HTTPS address at which the web interface is made available. If set, a widget will be added in the Easybridge room so that users can configure the bridge without leaving the Riot client.
|
||||
- `registration`: path to the YAML appservice registration file
|
||||
- `homeserver_url`: HTTP address of the Matrix homeserver
|
||||
- `matrix_domain`: the dmoain name of the Matrix homeserver (i.e. the domain used in user identifiers, room identifiers, etc)
|
||||
- `db_type` and `db_path`: the database backend and path to use (see the [Gorm documentation](http://gorm.io/docs/connecting_to_the_database.html))
|
||||
- `session_key`: a key with which session cookies are encrypted for the web interface
|
||||
|
||||
### Storage configuration
|
||||
|
||||
- `db_type` and `db_path`: the database backend and path to use (see the [Gorm documentation](http://gorm.io/docs/connecting_to_the_database.html))
|
||||
|
|
23
db.go
23
db.go
|
@ -213,18 +213,21 @@ func dbGetMxRoom(protocol string, roomId connector.RoomID) (string, error) {
|
|||
|
||||
if must_create {
|
||||
alias := roomAlias(protocol, roomId)
|
||||
// Lookup alias
|
||||
mx_room_id, err := mx.DirectoryRoom(fmt.Sprintf("#%s:%s", alias, config.MatrixDomain))
|
||||
|
||||
// If no alias found, create room
|
||||
// Delete previous alias if it existed
|
||||
prev_full_alias := fmt.Sprintf("#%s:%s", alias, config.MatrixDomain)
|
||||
mx_room_id, err := mx.DirectoryRoom(prev_full_alias)
|
||||
if err == nil {
|
||||
mx.DirectoryDeleteRoom(prev_full_alias)
|
||||
}
|
||||
|
||||
// Create room
|
||||
name := fmt.Sprintf("%s (%s)", roomId, protocol)
|
||||
|
||||
mx_room_id, err = mx.CreateRoom(name, alias, []string{})
|
||||
if err != nil {
|
||||
name := fmt.Sprintf("%s (%s)", roomId, protocol)
|
||||
|
||||
mx_room_id, err = mx.CreateRoom(name, alias, []string{})
|
||||
if err != nil {
|
||||
log.Warnf("Could not create room for %s: %s", name, err)
|
||||
return "", err
|
||||
}
|
||||
log.Warnf("Could not create room for %s: %s", name, err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
room = DbRoomMap{
|
||||
|
|
26
main.go
26
main.go
|
@ -15,17 +15,22 @@ import (
|
|||
)
|
||||
|
||||
type ConfigFile struct {
|
||||
LogLevel string `json:"log_level"`
|
||||
ASBindAddr string `json:"appservice_bind_addr"`
|
||||
WebBindAddr string `json:"web_bind_addr"`
|
||||
WebURL string `json:"web_url"`
|
||||
LogLevel string `json:"log_level"`
|
||||
|
||||
Registration string `json:"registration"`
|
||||
ASBindAddr string `json:"appservice_bind_addr"`
|
||||
Server string `json:"homeserver_url"`
|
||||
DbType string `json:"db_type"`
|
||||
DbPath string `json:"db_path"`
|
||||
MatrixDomain string `json:"matrix_domain"`
|
||||
SessionKey string `json:"web_session_key"`
|
||||
AvatarFile string `json:"easybridge_avatar"`
|
||||
NameFormat string `json:"name_format"`
|
||||
|
||||
WebBindAddr string `json:"web_bind_addr"`
|
||||
WebURL string `json:"web_url"`
|
||||
SessionKey string `json:"web_session_key"`
|
||||
|
||||
DbType string `json:"db_type"`
|
||||
DbPath string `json:"db_path"`
|
||||
|
||||
AvatarFile string `json:"easybridge_avatar"`
|
||||
}
|
||||
|
||||
var configFlag = flag.String("config", "./config.json", "Configuration file path")
|
||||
|
@ -43,6 +48,7 @@ func readConfig() ConfigFile {
|
|||
WebBindAddr: "0.0.0.0:8281",
|
||||
Registration: "./registration.yaml",
|
||||
Server: "http://localhost:8008",
|
||||
NameFormat: "{}_ezbr_",
|
||||
DbType: "sqlite3",
|
||||
DbPath: "easybridge.db",
|
||||
AvatarFile: "./easybridge.jpg",
|
||||
|
@ -102,13 +108,13 @@ func readRegistration(file string) mxlib.Registration {
|
|||
Users: []mxlib.RegistrationNamespace{
|
||||
mxlib.RegistrationNamespace{
|
||||
Exclusive: true,
|
||||
Regex: "@_ezbr_.*",
|
||||
Regex: "@.*_ezbr_",
|
||||
},
|
||||
},
|
||||
Aliases: []mxlib.RegistrationNamespace{
|
||||
mxlib.RegistrationNamespace{
|
||||
Exclusive: true,
|
||||
Regex: "#_ezbr_.*",
|
||||
Regex: "#.*_ezbr_",
|
||||
},
|
||||
},
|
||||
Rooms: []mxlib.RegistrationNamespace{},
|
||||
|
|
|
@ -78,6 +78,17 @@ func (mx *Client) PostApiCall(endpoint string, data interface{}, response interf
|
|||
return mx.DoAndParse(req, response)
|
||||
}
|
||||
|
||||
func (mx *Client) DeleteApiCall(endpoint string, response interface{}) error {
|
||||
log.Debugf("Matrix DELETE request: %s\n", endpoint)
|
||||
|
||||
req, err := http.NewRequest("DELETE", mx.Server+endpoint, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mx.DoAndParse(req, response)
|
||||
}
|
||||
|
||||
func (mx *Client) DoAndParse(req *http.Request, response interface{}) error {
|
||||
if mx.Token != "" {
|
||||
req.Header.Add("Authorization", "Bearer "+mx.Token)
|
||||
|
@ -181,6 +192,15 @@ func (mx *Client) DirectoryRoom(alias string) (string, error) {
|
|||
return rep.RoomId, nil
|
||||
}
|
||||
|
||||
func (mx *Client) DirectoryDeleteRoom(alias string) error {
|
||||
var rep struct{}
|
||||
err := mx.DeleteApiCall("/_matrix/client/r0/directory/room/"+url.QueryEscape(alias), &rep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mx *Client) CreateRoom(name string, alias string, invite []string) (string, error) {
|
||||
rq := CreateRoomRequest{
|
||||
Preset: "private_chat",
|
||||
|
|
|
@ -102,7 +102,7 @@ func handleTxn(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
for i := range txn.Events {
|
||||
ev := &txn.Events[i]
|
||||
if strings.HasPrefix(ev.Sender, "@"+registration.SenderLocalpart) {
|
||||
if isBridgedIdentifier(ev.Sender) {
|
||||
// Don't do anything with ezbr events that come back to us
|
||||
continue
|
||||
}
|
||||
|
|
29
util.go
29
util.go
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -58,11 +59,13 @@ func ezbrSystemSendf(user_mx_id string, format string, args ...interface{}) {
|
|||
// ----
|
||||
|
||||
func roomAlias(protocol string, id RoomID) string {
|
||||
return fmt.Sprintf("%s_%s__%s", registration.SenderLocalpart, safeStringForId(string(id)), protocol)
|
||||
what := fmt.Sprintf("%s_%s", safeStringForId(string(id)), protocol)
|
||||
return strings.Replace(config.NameFormat, "{}", what, 1)
|
||||
}
|
||||
|
||||
func userMxId(protocol string, id UserID) string {
|
||||
return fmt.Sprintf("%s_%s__%s", registration.SenderLocalpart, safeStringForId(string(id)), protocol)
|
||||
what := fmt.Sprintf("%s_%s", safeStringForId(string(id)), protocol)
|
||||
return strings.Replace(config.NameFormat, "{}", what, 1)
|
||||
}
|
||||
|
||||
func safeStringForId(in string) string {
|
||||
|
@ -79,6 +82,28 @@ func safeStringForId(in string) string {
|
|||
return id2
|
||||
}
|
||||
|
||||
func isBridgedIdentifier(mxid string) bool {
|
||||
if mxid[0] == '@' || mxid[0] == '#' {
|
||||
return isBridgedIdentifier(mxid[1:])
|
||||
}
|
||||
|
||||
if strings.Contains(mxid, ":") {
|
||||
sp := strings.Split(mxid, ":")
|
||||
return (sp[1] == config.MatrixDomain) && isBridgedIdentifier(sp[0])
|
||||
}
|
||||
|
||||
nameformat_fixed_part := strings.Replace(config.NameFormat, "{}", "", 1)
|
||||
if strings.HasPrefix(config.NameFormat, "{}") {
|
||||
return strings.HasSuffix(mxid, nameformat_fixed_part)
|
||||
} else if strings.HasSuffix(config.NameFormat, "{}") {
|
||||
return strings.HasPrefix(mxid, nameformat_fixed_part)
|
||||
} else {
|
||||
// This is not supported
|
||||
log.Fatal("Invalid name format %s, please put {} at the beginning or at the end", config.NameFormat)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Encoding and encryption of account config
|
||||
|
||||
func encryptAccountConfig(config map[string]string, key *[32]byte) string {
|
||||
|
|
Loading…
Reference in a new issue