From 42c1fde3558fc048902c1ac5ac7a7261d3d94cfc Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 29 Apr 2024 18:13:50 +0200 Subject: [PATCH] Add portal notifications on linux --- agent/notify/dbus.go | 17 ++++++++--------- agent/notify/libportal.go | 30 ++++++++++++++++++++++++++++++ agent/notify/linux.go | 26 ++++++++++++++++++++++++++ com.quexten.Goldwarden.yml | 3 --- go.mod | 1 + go.sum | 19 +++---------------- 6 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 agent/notify/libportal.go create mode 100644 agent/notify/linux.go diff --git a/agent/notify/dbus.go b/agent/notify/dbus.go index 59ab9dc..a5ac231 100644 --- a/agent/notify/dbus.go +++ b/agent/notify/dbus.go @@ -6,18 +6,15 @@ import ( "time" "github.com/godbus/dbus/v5" - "github.com/quexten/goldwarden/logging" ) var closeListenerMap = make(map[uint32]func()) -var notificationID uint32 = 1000000 -var log = logging.GetLogger("Goldwarden", "Dbus") -func Notify(title string, body string, actionName string, timeout time.Duration, onclose func()) { +func notifyDBus(title string, body string, actionName string, timeout time.Duration, onclose func()) error { bus, err := dbus.SessionBus() if err != nil { log.Error("could not get a dbus session: %s", err.Error()) - return + return err } obj := bus.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications") actions := []string{} @@ -30,16 +27,16 @@ func Notify(title string, body string, actionName string, timeout time.Duration, call := obj.Call("org.freedesktop.Notifications.Notify", 0, "goldwarden", uint32(notificationID), "", title, body, actions, map[string]dbus.Variant{}, int32(60000)) if call.Err != nil { log.Error("could not call dbus object: %s", call.Err.Error()) - return + return err } if len(call.Body) < 1 { - return + return err } id := call.Body[0].(uint32) closeListenerMap[id] = onclose if timeout == 0 { - return + return err } else { go func(id uint32) { time.Sleep(timeout) @@ -49,9 +46,11 @@ func Notify(title string, body string, actionName string, timeout time.Duration, } }(id) } + + return nil } -func ListenForNotifications() error { +func listenForNotificationsDBus() error { bus, err := dbus.SessionBus() if err != nil { return err diff --git a/agent/notify/libportal.go b/agent/notify/libportal.go new file mode 100644 index 0000000..968bea3 --- /dev/null +++ b/agent/notify/libportal.go @@ -0,0 +1,30 @@ +//go:build linux + +package notify + +import ( + "time" + + "github.com/rymdport/portal/notification" +) + +func notifyLibPortal(title string, body string, actionName string, timeout time.Duration, onclose func()) error { + notificationID++ + err := notification.Add(uint(notificationID), notification.Content{ + Title: title, + Body: body, + }) + if err != nil { + return err + } + + if timeout == 0 { + return nil + } else { + go func(id uint32) { + time.Sleep(timeout) + notification.Remove(uint(notificationID)) + }(notificationID) + } + return nil +} diff --git a/agent/notify/linux.go b/agent/notify/linux.go new file mode 100644 index 0000000..9470e84 --- /dev/null +++ b/agent/notify/linux.go @@ -0,0 +1,26 @@ +//go:build linux || freebsd + +package notify + +import ( + "time" + + "github.com/quexten/goldwarden/logging" +) + +var notificationID uint32 = 1000000 +var log = logging.GetLogger("Goldwarden", "Dbus") + +func Notify(title string, body string, actionName string, timeout time.Duration, onclose func()) { + err := notifyLibPortal(title, body, actionName, timeout, onclose) + if err != nil { + err = notifyDBus(title, body, actionName, timeout, onclose) + if err != nil { + log.Warn("error sending notification " + err.Error()) + } + } +} + +func ListenForNotifications() error { + return nil +} diff --git a/com.quexten.Goldwarden.yml b/com.quexten.Goldwarden.yml index 22c3e18..ac801f1 100644 --- a/com.quexten.Goldwarden.yml +++ b/com.quexten.Goldwarden.yml @@ -20,9 +20,6 @@ finish-args: # Lock on idle - --talk-name=org.gnome.Mutter.IdleMonitor - # Notifications - - --talk-name=org.freedesktop.Notifications - # pinentry & approval - --talk-name=org.gnome.keyring.SystemPrompter # biometric / user password auth diff --git a/go.mod b/go.mod index 97d4130..3567154 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/keybase/go-logging v0.0.0-20231213204715-4b3ff33ba5b6 // indirect github.com/keybase/msgpackzip v0.0.0-20231213201432-ee2f464d1f46 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect + github.com/rymdport/portal v0.2.2 // indirect github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect golang.org/x/net v0.24.0 // indirect ) diff --git a/go.sum b/go.sum index 9cfd57c..44ca906 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/gen2brain/beeep v0.0.0-20240112042604-c7bb2cd88fea h1:oWUHxzaBvwkRWiINbBOY39XIF+n9b4RJEPHdQ8waJUo= @@ -44,24 +42,18 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/keybase/backoff v1.0.1-0.20160517061000-726b63b835ec h1:D6qL2WCnAuxucGbmL+mDW8IKRK1pex+R1fw5rKa9nXc= github.com/keybase/backoff v1.0.1-0.20160517061000-726b63b835ec/go.mod h1:jeBKj+20GIDry3doFsAMYH9n7Y3l7ajE3xJrKvVB23s= -github.com/keybase/client/go v0.0.0-20240202160538-668db6be75e4 h1:MPUIAszF69Y8gZicAYxzDfrL5G3z/aKyfag8nPSq3js= -github.com/keybase/client/go v0.0.0-20240202160538-668db6be75e4/go.mod h1:V3kb71GXhlWkJjB906M5xyiCqO7ygb4R6peCA+CMHtw= github.com/keybase/client/go v0.0.0-20240424154521-52f30ea26cb1 h1:toSyN3iQ996iZzFWHYfiXN20wzcavqQUJ171t+n6LqI= github.com/keybase/client/go v0.0.0-20240424154521-52f30ea26cb1/go.mod h1:NHwdggxLBh4RNQzpCcI0PNArhokrX4Oj4TpnZ8/YIEM= github.com/keybase/clockwork v0.1.1-0.20161209210251-976f45f4a979 h1:WABVkjKJ3UjbSTgGayemkXfUyZrDwFShivsoIikbM3c= github.com/keybase/clockwork v0.1.1-0.20161209210251-976f45f4a979/go.mod h1:2j97e0ZjlWYV7dDdV8BjKwMUmBbXu6zZF8FAa9gXRss= github.com/keybase/go-codec v0.0.0-20180928230036-164397562123 h1:yg56lYPqh9suJepqxOMd/liFgU/x+maRPiB30JNYykM= github.com/keybase/go-codec v0.0.0-20180928230036-164397562123/go.mod h1:r/eVVWCngg6TsFV/3HuS9sWhDkAzGG8mXhiuYA+Z/20= -github.com/keybase/go-framed-msgpack-rpc v0.0.0-20230103225103-1f052922b096 h1:rMDGkwIszgGP7HodB/YdMVT39mMI5s+LUI6DOrJO0DE= -github.com/keybase/go-framed-msgpack-rpc v0.0.0-20230103225103-1f052922b096/go.mod h1:XO67nMjltHJ8OsBWnFiDU1F67wR+rtJB21NXtb1TKyA= github.com/keybase/go-framed-msgpack-rpc v0.0.0-20231213201819-78fffcb30e42 h1:r1ZY/j20qhaxcnLXRYf4YJ1hVHxOUqkcXW1AWbtlwRc= github.com/keybase/go-framed-msgpack-rpc v0.0.0-20231213201819-78fffcb30e42/go.mod h1:oJqYYlOzuyghCL4YfZ0hDLZOyJYcjpRYc2S79aitIBE= github.com/keybase/go-jsonw v0.0.0-20200325173637-df90f282c233 h1:zLk+cB/0ShMCBcgBOXYgellLZiZahXFicJleKyrlqiM= github.com/keybase/go-jsonw v0.0.0-20200325173637-df90f282c233/go.mod h1:lofKQwj13L0/7ji5VYaY0257JDlQE2BRRf+rI2Vk1rU= github.com/keybase/go-logging v0.0.0-20231213204715-4b3ff33ba5b6 h1:H4IvZdHXpeK963LgCMbTcEviEal4891UGf2iOqOGL94= github.com/keybase/go-logging v0.0.0-20231213204715-4b3ff33ba5b6/go.mod h1:0yOEB+QF1Ega1Cr7oMKb3yUAc3C9/eg6fBHB5HLP7AA= -github.com/keybase/msgpackzip v0.0.0-20221220225959-4abf538d2b9c h1:PRG2AXSelSy7MiDI+PwJR2QSqI1N3OybRUutsMiHtpo= -github.com/keybase/msgpackzip v0.0.0-20221220225959-4abf538d2b9c/go.mod h1:DkylHDco/FLr1+GM6wg0GF4E3CCKov54MSYojKYAbS0= github.com/keybase/msgpackzip v0.0.0-20231213201432-ee2f464d1f46 h1:HZwgh9xppsgOtC/KFuPOUKqtR70tmqoZKDdzFzMgofk= github.com/keybase/msgpackzip v0.0.0-20231213201432-ee2f464d1f46/go.mod h1:yBUdIgz7FWt9P/poJyPJ75v9WPDITnKGfwive77P8O4= github.com/keys-pub/go-libfido2 v1.5.4-0.20230628153049-536daffdd394 h1:zf+3yRJH5NIVOhLceS4P6AVQWEgQPhMCpxgMSB46HdI= @@ -89,11 +81,11 @@ github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJ github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas= github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e/go.mod h1:+5vNVvEWwEIx86DB9Ke/+a5wBI464eDRo3eF0LcfpWg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/rymdport/portal v0.2.2 h1:P2Q/4k673zxdFAsbD8EESZ7psfuO6/4jNu6EDrDICkM= +github.com/rymdport/portal v0.2.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -116,17 +108,12 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE= -golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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=