diff --git a/Containerfile.debian b/Containerfile.debian index 91c3d81..36047bd 100644 --- a/Containerfile.debian +++ b/Containerfile.debian @@ -28,7 +28,7 @@ COPY pygomx /pygomx RUN < +mxdiscover --- -screenshot: +(old) screenshot: ~/p/m/pygomx (main|✚4) $ docker compose run --rm dev /bin/bash Container pygomx-dev-run-401f3ed5da9c Creating Container pygomx-dev-run-401f3ed5da9c Created diff --git a/libmxclient/go.mod b/libmxclient/go.mod index 0bdbfcc..9d5cde0 100644 --- a/libmxclient/go.mod +++ b/libmxclient/go.mod @@ -10,13 +10,13 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/rs/zerolog v1.34.0 // indirect github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect go.mau.fi/util v0.9.4 // indirect - golang.org/x/crypto v0.46.0 // indirect - golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect ) diff --git a/libmxclient/go.sum b/libmxclient/go.sum index 382e5d0..5b62646 100644 --- a/libmxclient/go.sum +++ b/libmxclient/go.sum @@ -18,6 +18,8 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= +github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -27,16 +29,26 @@ go.mau.fi/util v0.9.4 h1:gWdUff+K2rCynRPysXalqqQyr2ahkSWaestH6YhSpso= go.mau.fi/util v0.9.4/go.mod h1:647nVfwUvuhlZFOnro3aRNPmRd2y3iDha9USb8aKSmM= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= maunium.net/go/mautrix v0.26.1 h1:FWCC1xY5vwJ5ou3duEBjB6w9IIlwfc9el3q3Mju3Dlg= maunium.net/go/mautrix v0.26.1/go.mod h1:UySSpb8OqXG1sMJ6dDqyzmfcqr2ayZK+KzwqOTAkAOM= diff --git a/libmxclient/mxclient/utils.go b/libmxclient/mxclient/utils.go index 18c9ee6..0e34ad4 100644 --- a/libmxclient/mxclient/utils.go +++ b/libmxclient/mxclient/utils.go @@ -1,31 +1,41 @@ +// Copyright (C) 2026 saces@c-base.org +// SPDX-License-Identifier: AGPL-3.0-only package mxclient import ( "context" "encoding/json" "fmt" + "time" "maunium.net/go/mautrix" "maunium.net/go/mautrix/id" ) func DiscoverHS(ids string) string { - mxid := id.UserID(ids) - _, hs, err := mxid.Parse() + var domainname string + + // probe for mxid + _mxid := id.UserID(ids) + + _, _hs, err := _mxid.Parse() if err != nil { - return fmt.Sprintf("ERR: %v", err) + // not a mxid + domainname = ids + } else { + domainname = _hs } - fmt.Printf("Attempt to discover '%s'\n", hs) + fmt.Printf("Attempt to discover '%s'\n", domainname) - wk, err := mautrix.DiscoverClientAPI(context.Background(), hs) + wk, err := mautrix.DiscoverClientAPI(context.Background(), domainname) if err != nil { return fmt.Sprintf("ERR: %v", err) } if wk == nil { - return fmt.Sprintf("No well-known. hs from input: %s", hs) + return fmt.Sprintf("No well-known. hs from input: %s", domainname) } j, err := json.Marshal(wk) @@ -34,3 +44,64 @@ func DiscoverHS(ids string) string { } return string(j) } + +func MkToken(ids string, pw string) string { + + mxid := id.UserID(ids) + + _, hs, err := mxid.Parse() + if err != nil { + return fmt.Sprintf("ERR: %v", err) + } + + wk, err := mautrix.DiscoverClientAPI(context.Background(), hs) + if err != nil { + return fmt.Sprintf("ERR: %v", err) + } + + if wk != nil { + hs = wk.Homeserver.BaseURL + } + + mauclient, err := mautrix.NewClient(hs, mxid, "") + if err != nil { + return fmt.Sprintf("ERR: %v", err) + } + + deviceName := fmt.Sprintf("mxtokenizer-%d", time.Now().Unix()) + + resp, err := mauclient.Login(context.Background(), &mautrix.ReqLogin{ + Type: "m.login.password", + Identifier: mautrix.UserIdentifier{ + Type: "m.id.user", + User: mxid.Localpart(), + }, + Password: pw, + DeviceID: id.DeviceID(deviceName), + InitialDeviceDisplayName: deviceName, + StoreCredentials: false, + StoreHomeserverURL: false, + RefreshToken: false, + }) + if err != nil { + return fmt.Sprintf("ERR: %v", err) + } + + return resp.AccessToken +} + +func Whoami(hs string, accessToken string) string { + return "nope. whoami" +} + +func AccountInfo(hs string, accessToken string) string { + return "nope. accountinfo" +} + +func ClearAccount(hs string, accessToken string) string { + return "nope. clearaccount" +} + +func ServerInfo(url string) string { + return "nope. serverinfo" +} diff --git a/libmxclient/mxclientlib.go b/libmxclient/mxclientlib.go index f8e2152..436fa81 100644 --- a/libmxclient/mxclientlib.go +++ b/libmxclient/mxclientlib.go @@ -1,23 +1,79 @@ +// Copyright (C) 2026 saces@c-base.org +// SPDX-License-Identifier: AGPL-3.0-only package main import ( + "fmt" "mxclientlib/mxclient" ) import "C" -//export discoverhs -func discoverhs(id *C.char) *C.char { +/* +cli tools +*/ +//export cli_discoverhs +func cli_discoverhs(id *C.char) *C.char { mxid := C.GoString(id) result := mxclient.DiscoverHS(mxid) return C.CString(result) } -//export hello -func hello(name *C.char) *C.char { - goName := C.GoString(name) - result := "Hello " + goName +//export cli_mkmxtoken +func cli_mkmxtoken(id *C.char, pw *C.char) *C.char { + mxid := C.GoString(id) + mxpw := C.GoString(pw) + result := mxclient.MkToken(mxid, mxpw) return C.CString(result) } +//export cli_whoami +func cli_whoami(hs *C.char, tk *C.char) *C.char { + _hs := C.GoString(hs) + _tk := C.GoString(tk) + result := mxclient.Whoami(_hs, _tk) + return C.CString(result) +} + +//export cli_accountinfo +func cli_accountinfo(hs *C.char, tk *C.char) *C.char { + _hs := C.GoString(hs) + _tk := C.GoString(tk) + result := mxclient.AccountInfo(_hs, _tk) + return C.CString(result) +} + +//export cli_clearaccount +func cli_clearaccount(hs *C.char, tk *C.char) *C.char { + _hs := C.GoString(hs) + _tk := C.GoString(tk) + result := mxclient.ClearAccount(_hs, _tk) + return C.CString(result) +} + +//export cli_serverinfo +func cli_serverinfo(url *C.char) *C.char { + _url := C.GoString(url) + result := mxclient.ServerInfo(_url) + return C.CString(result) +} + +/* +high api +*/ +//export createclient +func createclient(url *C.char, userID *C.char, accessToken *C.char) C.int { + err := mxclient.CreateClient(C.GoString(url), C.GoString(userID), C.GoString(accessToken)) + if err != nil { + fmt.Printf("ERR: %v", err) + return 1 + } + return 0 +} + +//export shutdown +func shutdown() C.int { + return 0 +} + func main() {} diff --git a/pygomx/build_ffi.py b/pygomx/build_ffi.py index 0d5efa4..bba549d 100644 --- a/pygomx/build_ffi.py +++ b/pygomx/build_ffi.py @@ -13,8 +13,13 @@ ffibuilder.set_source( ffibuilder.cdef( csource=""" - extern char* discoverhs(char* p0); - extern char* hello(char* p0); + extern char* cli_discoverhs(char* mxid); + extern char* cli_mkmxtoken(char* mxid, char* pw); + extern char* cli_whoami(char* hs, char* accessToken); + extern char* cli_accountinfo(char* hs, char* accessToken); + extern char* cli_clearaccount(char* hs, char* accessToken); + extern char* cli_serverinfo(char* url); + extern int createclient(char* url, char* userID, char* accessToken); """ ) diff --git a/smal/pyproject.toml b/smal/pyproject.toml index 6d8df0f..39c1824 100644 --- a/smal/pyproject.toml +++ b/smal/pyproject.toml @@ -27,4 +27,9 @@ repository = "https://code.c-base.org/saces/pygomx" egg_base = "/tmp" [project.scripts] -discoverhs = "pygomx.mxutils:discoverhs" +mxdiscover = "pygomx.mxutils:discoverhs" +mxwhoami = "pygomx.mxutils:whoami" +mxtoken = "pygomx.mxutils:mktoken" +mxaccountinfo = "pygomx.mxutils:accountinfo" +mxclearaccount = "pygomx.mxutils:clearaccount" +mxserverinfo = "pygomx.mxutils:serverinfo" diff --git a/smal/src/pygomx/mxutils/__init__.py b/smal/src/pygomx/mxutils/__init__.py index b84a711..25409a5 100644 --- a/smal/src/pygomx/mxutils/__init__.py +++ b/smal/src/pygomx/mxutils/__init__.py @@ -1 +1,6 @@ from .discoverhs import discoverhs +from .mktoken import mktoken +from .whoami import whoami +from .accountinfo import accountinfo +from .clearaccount import clearaccount +from .serverinfo import serverinfo diff --git a/smal/src/pygomx/mxutils/accountinfo.py b/smal/src/pygomx/mxutils/accountinfo.py new file mode 100644 index 0000000..a492b1e --- /dev/null +++ b/smal/src/pygomx/mxutils/accountinfo.py @@ -0,0 +1,15 @@ +import sys +from _pygomx import lib, ffi + + +def accountinfo(): + if len(sys.argv) != 3: + print("usage: ", sys.argv[0], " url acesstoken") + return 1 + + url = sys.argv[1].encode(encoding="utf-8") + tk = sys.argv[1].encode(encoding="utf-8") + + r = lib.cli_accountinfo(url, tk) + result = ffi.string(r) + print(result) diff --git a/smal/src/pygomx/mxutils/clearaccount.py b/smal/src/pygomx/mxutils/clearaccount.py new file mode 100644 index 0000000..8d494f1 --- /dev/null +++ b/smal/src/pygomx/mxutils/clearaccount.py @@ -0,0 +1,15 @@ +import sys +from _pygomx import lib, ffi + + +def clearaccount(): + if len(sys.argv) != 3: + print("usage: ", sys.argv[0], " url accesstoken") + return 1 + + url = sys.argv[1].encode(encoding="utf-8") + tk = sys.argv[2].encode(encoding="utf-8") + + r = lib.cli_clearaccount(url, tk) + result = ffi.string(r) + print(result) diff --git a/smal/src/pygomx/mxutils/discoverhs.py b/smal/src/pygomx/mxutils/discoverhs.py index 5e8e953..547232e 100644 --- a/smal/src/pygomx/mxutils/discoverhs.py +++ b/smal/src/pygomx/mxutils/discoverhs.py @@ -4,13 +4,13 @@ from _pygomx import lib, ffi def discoverhs(): if len(sys.argv) != 2: - print("usage: ", sys.argv[0], " matrixid") + print("usage: ", sys.argv[0], " matrixid|domainname") return 1 mxid = sys.argv[1].encode(encoding="utf-8") print("try to discover from: ", mxid) - r = lib.discoverhs(mxid) + r = lib.cli_discoverhs(mxid) result = ffi.string(r) print(result) diff --git a/smal/src/pygomx/mxutils/mktoken.py b/smal/src/pygomx/mxutils/mktoken.py new file mode 100644 index 0000000..38fdc58 --- /dev/null +++ b/smal/src/pygomx/mxutils/mktoken.py @@ -0,0 +1,15 @@ +import sys +from _pygomx import lib, ffi + + +def mktoken(): + if len(sys.argv) != 3: + print("usage: ", sys.argv[0], " matrixid password") + return 1 + + mxid = sys.argv[1].encode(encoding="utf-8") + pw = sys.argv[2].encode(encoding="utf-8") + + r = lib.cli_mkmxtoken(mxid, pw) + result = ffi.string(r) + print(result) diff --git a/smal/src/pygomx/mxutils/serverinfo.py b/smal/src/pygomx/mxutils/serverinfo.py new file mode 100644 index 0000000..f72807f --- /dev/null +++ b/smal/src/pygomx/mxutils/serverinfo.py @@ -0,0 +1,14 @@ +import sys +from _pygomx import lib, ffi + + +def serverinfo(): + if len(sys.argv) != 2: + print("usage: ", sys.argv[0], " url|domainname") + return 1 + + mxdomain = sys.argv[1].encode(encoding="utf-8") + + r = lib.cli_serverinfo(mxdomain) + result = ffi.string(r) + print(result) diff --git a/smal/src/pygomx/mxutils/whoami.py b/smal/src/pygomx/mxutils/whoami.py new file mode 100644 index 0000000..e41241d --- /dev/null +++ b/smal/src/pygomx/mxutils/whoami.py @@ -0,0 +1,15 @@ +import sys +from _pygomx import lib, ffi + + +def whoami(): + if len(sys.argv) != 3: + print("usage: ", sys.argv[0], " url accesstoken") + return 1 + + url = sys.argv[1].encode(encoding="utf-8") + tk = sys.argv[2].encode(encoding="utf-8") + + r = lib.cli_whoami(url, tk) + result = ffi.string(r) + print(result)