1
1
Fork 0
otprunner/main.go

170 γραμμές
3,7 KiB
Go

2021-07-20 18:20:29 +03:00
package main
import (
"log"
"os/exec"
"strings"
2021-07-23 12:29:55 +03:00
"github.com/99designs/keyring"
2021-07-20 18:20:29 +03:00
"github.com/godbus/dbus"
"github.com/godbus/dbus/introspect"
)
var messages = map[string]string{
"errconn": "DBus Connection Problem",
"errname": "DBus Unable to request name or name taken",
}
const servicename = "labs.infl00p.otp"
const ifacename = "org.kde.krunner1"
const ifacepath = "/krunner"
const intro = `
<node>
<interface name="org.kde.krunner1">
<method name="Actions">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RemoteActions" />
<arg name="matches" type="a(sss)" direction="out" />
</method>
<method name="Run">
<arg name="matchId" type="s" direction="in"/>
<arg name="actionId" type="s" direction="in"/>
</method>
<method name="Match">
<arg name="query" type="s" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RemoteMatches"/>
<arg name="matches" type="a(sssida{sv})" direction="out"/>
</method>
</interface>` + introspect.IntrospectDataString + `</node>`
type runner struct {
wallet keyring.Keyring
}
type match struct {
ID string
Text string
IconName string
Type int32
Relevance float64
Properties map[string]interface{}
}
func main() {
var r runner
// Open Dbus Connection
conn, err := dbus.SessionBus()
if err != nil {
log.Fatal(messages["errconn"])
}
rep, err := conn.RequestName(servicename, dbus.NameFlagDoNotQueue)
if err != nil || rep != dbus.RequestNameReplyPrimaryOwner {
log.Fatal(messages["errname"])
}
// KWallet
wallet, err := keyring.Open(keyring.Config{
AllowedBackends: []keyring.BackendType{keyring.KWalletBackend},
ServiceName: "kdewallet",
KWalletFolder: "otprunner",
2021-07-23 12:29:55 +03:00
KWalletAppID: "otprunner",
2021-07-20 18:20:29 +03:00
})
if err != nil {
log.Fatal("Unable to Open KDE Wallet ", err.Error())
}
r.wallet = wallet
2021-07-23 12:29:55 +03:00
// test data
r.wallet.Set(keyring.Item{"koko1",[]byte("lala1"),"Label koko1", "Description1", true, true})
r.wallet.Set(keyring.Item{"koko2",[]byte("lala2"),"Label koko2", "Description2", true, true})
2021-07-20 18:20:29 +03:00
conn.Export(r, ifacepath, ifacename)
conn.Export(introspect.Introspectable(intro), ifacepath, "org.freedesktop.DBus.Introspectable")
// block
select {}
}
func (r runner) Actions() ([]string, *dbus.Error) {
return []string{}, nil
}
func (r runner) Match(query string) ([]match, *dbus.Error) {
key := strings.Split(query, " ")
matches := make([]match,0,100)
// List all keys in keyring
keys, err := r.wallet.Keys()
if err != nil {
log.Fatal("List Keys ", err.Error())
}
if len(key) > 1 && key[0] == "otp" {
if len(keys) > 0 {
size:=0
rel:=1.0
for i, v := range(keys) {
if v != "" && strings.Contains(v,key[1]) {
log.Println(size)
matches=matches[:size+1]
matches[size].ID = strings.ToLower(strings.Replace(v," ", "_",-1))
matches[size].Text = v
matches[size].IconName = "document-export-key"
matches[size].Type = 100
matches[size].Relevance = rel
rel= rel/1.1
size+=1
log.Println(i, matches[i])
}
}
return matches, nil
}
}
return matches, nil
}
func (r runner) Run(selection string, id string) *dbus.Error {
2021-07-23 12:29:55 +03:00
code, err := r.wallet.Get(selection)
if err != nil {
log.Println(code)
log.Println(err)
}
err = AddToClipboard(string(code.Data))
2021-07-20 18:20:29 +03:00
if err != nil {
log.Fatal(err)
}
return nil
}
func AddToClipboard(s string) error {
cmd := exec.Command("xclip","-r","-selection","clipboard")
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
err = cmd.Start()
if err != nil {
return err
}
_, err = stdin.Write([]byte(s))
if err != nil {
return err
}
err = stdin.Close()
if err != nil {
return err
}
err = cmd.Wait()
if err != nil {
return err
}
return nil
}