wip
This commit is contained in:
BIN
src/matrix/.client.go.swp
Normal file
BIN
src/matrix/.client.go.swp
Normal file
Binary file not shown.
@@ -1,7 +1,147 @@
|
|||||||
package matrix
|
package matrix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"maunium.net/go/mautrix"
|
||||||
|
"maunium.net/go/mautrix/crypto"
|
||||||
|
"maunium.net/go/mautrix/crypto/cryptohelper"
|
||||||
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *mautrix.Client
|
client *mautrix.Client
|
||||||
|
accessToken string
|
||||||
|
deviceId string
|
||||||
|
pickleKeyString string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New // https://chrastecky.dev/post/11
|
func NewClient(ctx context.Context, uid, password, recoveryKey string) (*Client, error) {
|
||||||
|
ctx, can := context.WithCancel(ctx)
|
||||||
|
defer can()
|
||||||
|
|
||||||
|
// uid like @username:homeserver.com
|
||||||
|
username := strings.Split(uid, ":")[0]
|
||||||
|
homeserver := strings.Split(uid, ":")[1]
|
||||||
|
|
||||||
|
c, err := mautrix.NewClient(homeserver, uid, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
syncer := mautrix.NewDefaultSyncer()
|
||||||
|
c.Syncer = syncer
|
||||||
|
cryptoHelper, err := setupCryptoHelper(ctx, client)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
c.Crypto = cryptoHelper
|
||||||
|
|
||||||
|
readyChan := make(chan bool)
|
||||||
|
var once sync.Once
|
||||||
|
syncer.OnSync(func(ctx context.Context, resp *mautrix.RespSync, since string) bool {
|
||||||
|
once.Do(func() {
|
||||||
|
close(readyChan)
|
||||||
|
})
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
go func() {
|
||||||
|
if err := c.Sync(); err != nil {
|
||||||
|
can()
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
case <-readyChan:
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := verifyWithRecoveryKey(ctx, cryptoHelper.Machine()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
client: c,
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, client.login(ctx, username, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) login(ctx context.Context, username, password string) error {
|
||||||
|
if c.accessToken != "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.client.Login(ctx, &mautrix.ReqLogin{
|
||||||
|
Type: mautrix.AuthTypePassword,
|
||||||
|
Identifier: mautrix.UserIdentifier{
|
||||||
|
User: username,
|
||||||
|
Type: mautrix.IdentifierTypeUser,
|
||||||
|
},
|
||||||
|
Password: password,
|
||||||
|
StoreCredentials: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.deviceId = resp.DeviceID
|
||||||
|
c.accessToken = resp.AccessToken
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
content := event.MessageEventContent{
|
||||||
|
MsgType: event.MsgText,
|
||||||
|
Body: "Hello world from Go!",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.SendMessageEvent(context.Background(), roomID, event.EventMessage, content)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func setupCryptoHelper(ctx context.Context, cli *mautrix.Client) (*cryptohelper.CryptoHelper, error) {
|
||||||
|
// remember to use a secure key for the pickle key in production
|
||||||
|
pickleKey := []byte(pickleKeyString)
|
||||||
|
|
||||||
|
// this is a path to the SQLite database you will use to store various data about your bot
|
||||||
|
dbPath := "crypto.db"
|
||||||
|
|
||||||
|
helper, err := cryptohelper.NewCryptoHelper(cli, pickleKey, dbPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize the database and other stuff
|
||||||
|
err = helper.Init(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return helper, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyWithRecoveryKey(ctx context.Context, machine *crypto.OlmMachine) (err error) {
|
||||||
|
keyId, keyData, err := machine.SSSS.GetDefaultKeyData(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key, err := keyData.VerifyRecoveryKey(keyId, recoveryKey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = machine.FetchCrossSigningKeysFromSSSS(ctx, key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = machine.SignOwnDevice(ctx, machine.OwnIdentity())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = machine.SignOwnMasterKey(ctx)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user