169 γραμμές
3,7 KiB
Go
169 γραμμές
3,7 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/99designs/keyring"
|
|
"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",
|
|
KWalletAppID: "otprunner",
|
|
})
|
|
if err != nil {
|
|
log.Fatal("Unable to Open KDE Wallet ", err.Error())
|
|
}
|
|
r.wallet = wallet
|
|
|
|
// 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})
|
|
|
|
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 {
|
|
code, err := r.wallet.Get(selection)
|
|
if err != nil {
|
|
log.Println(code)
|
|
log.Println(err)
|
|
}
|
|
err = AddToClipboard(string(code.Data))
|
|
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
|
|
|
|
}
|
|
|