econnman: add agent support (passwords)
add a very simplistic ConnMan agent when you give it --agent/-a. It will list every requested input and return those that you've filled, that simple. You can use it to enter passwords/passphrases/login whenever ConnMan requires it. Ideally this should be in e17 connman module, but until it gets there you can use this. NOTE-1: connman 1.0 has a bug that sometimes it will return "Failed I/O" even before you returned the password! NOTE-2: connman git (1.3) has a bug that it will NEVER abort Connect() calls even if the agent returns an error (is canceled). I've reported the NOTE-2 bug to their mail list and as soon as I get a reply I'll keep you informed. SVN revision: 73250
This commit is contained in:
parent
97b1311413
commit
8f8b2d04bd
164
econnman-bin
164
econnman-bin
|
@ -14,7 +14,9 @@
|
|||
import elementary as elm
|
||||
import evas
|
||||
import e_dbus
|
||||
import ecore
|
||||
import dbus
|
||||
import dbus.service
|
||||
import logging
|
||||
import argparse
|
||||
|
||||
|
@ -650,6 +652,15 @@ class ServicesList(object):
|
|||
lb.text = "%s: %s" % (type, state)
|
||||
return lb
|
||||
|
||||
def service_name_get(self, path):
|
||||
s = self.services.get(path)
|
||||
if not s:
|
||||
return None
|
||||
n = s.get("Name")
|
||||
if not n:
|
||||
return None
|
||||
return str(n)
|
||||
|
||||
|
||||
class ServiceView(ObjectView):
|
||||
"""Provides a detailed view of the service given by C{path}.
|
||||
|
@ -1120,6 +1131,150 @@ def show_service(path, properties):
|
|||
nf.item_push(name, None, None, sv.obj, "basic")
|
||||
|
||||
|
||||
########################################################################
|
||||
# Agent:
|
||||
def agent_method(in_signature="", out_signature="", **kargs):
|
||||
return dbus.service.method("net.connman.Agent",
|
||||
in_signature=in_signature,
|
||||
out_signature=out_signature,
|
||||
**kargs)
|
||||
|
||||
class Agent(dbus.service.Object):
|
||||
path = "/org/enlightenment/econnman/agent"
|
||||
|
||||
request_type_conv = {
|
||||
"SSID": dbus.ByteArray,
|
||||
}
|
||||
|
||||
class Canceled(dbus.DBusException):
|
||||
_dbus_error_name = "net.connman.Agent.Error.Canceled"
|
||||
|
||||
def __init__(self, serv_lst):
|
||||
dbus.service.Object.__init__(self, bus, self.path)
|
||||
self.dialog = None
|
||||
self.serv_lst = serv_lst
|
||||
|
||||
@agent_method()
|
||||
def Release(self):
|
||||
log.info("Agent released by ConnMan")
|
||||
if self.dialog:
|
||||
self.dialog.delete()
|
||||
self.dialog = None
|
||||
|
||||
@agent_method(in_signature="os")
|
||||
def RequestBrowser(self, path, url):
|
||||
log.info("Open browser for %s at %s", path, url)
|
||||
ecore.exe_run("xdg-open '%s'" % url)
|
||||
|
||||
@agent_method(in_signature="os")
|
||||
def ReportError(self, path, error):
|
||||
log.error("ConnMan error %s: %s", path, error)
|
||||
popup_error(win, "ConnMan Error", str(error))
|
||||
|
||||
@agent_method()
|
||||
def Cancel(self):
|
||||
log.info("Canceled dialog")
|
||||
if self.dialog:
|
||||
self.dialog.delete()
|
||||
self.dialog = None
|
||||
|
||||
@agent_method(in_signature="oa{sv}", out_signature="a{sv}",
|
||||
async_callbacks=("on_done", "on_error"))
|
||||
def RequestInput(self, path, fields, on_done, on_error):
|
||||
log.debug("Request Input for %s: %s", path, dbus_dict_to_str(fields))
|
||||
|
||||
def on_deleted(obj):
|
||||
w = self.dialog
|
||||
self.dialog = None
|
||||
if w:
|
||||
e = Agent.Canceled("user canceled")
|
||||
log.debug("User canceled agent request: %s", e)
|
||||
on_error(e)
|
||||
|
||||
def on_clicked(obj):
|
||||
response = {}
|
||||
keys = []
|
||||
for name, en in widgets.iteritems():
|
||||
conv = self.request_type_conv.get(name, dbus.String)
|
||||
v = conv(en.text)
|
||||
if v:
|
||||
response[name] = v
|
||||
keys.append(name)
|
||||
log.debug("User Replies with keys: %s", ", ".join(keys))
|
||||
w = self.dialog
|
||||
self.dialog = None
|
||||
on_done(response)
|
||||
w.delete()
|
||||
|
||||
self.dialog = w = elm.Window("econnman-agent", elm.ELM_WIN_DIALOG_BASIC)
|
||||
w.title = "ConnMan Requested Input"
|
||||
w.icon_name = "econnman"
|
||||
w.autodel = True
|
||||
w.on_del_add(on_deleted)
|
||||
w.show()
|
||||
|
||||
bg = elm.Background(w)
|
||||
bg.size_hint_weight = EXPAND_BOTH
|
||||
bg.show()
|
||||
w.resize_object_add(bg)
|
||||
|
||||
bx = elm.Box(w)
|
||||
bx.size_hint_align = FILL_BOTH
|
||||
bx.horizontal = False
|
||||
bx.show()
|
||||
w.resize_object_add(bx)
|
||||
|
||||
lb = elm.Label(bx)
|
||||
lb.size_hint_weight = EXPAND_HORIZ
|
||||
lb.size_hint_align = FILL_BOTH
|
||||
lb.text = "<b>ConnMan needs your input</b>"
|
||||
lb.show()
|
||||
bx.pack_end(lb)
|
||||
|
||||
name = self.serv_lst.service_name_get(path)
|
||||
if name:
|
||||
lb = elm.Label(bx)
|
||||
lb.size_hint_weight = EXPAND_HORIZ
|
||||
lb.size_hint_align = FILL_BOTH
|
||||
lb.text = "Service: %s" % (name,)
|
||||
lb.show()
|
||||
bx.pack_end(lb)
|
||||
|
||||
widgets = {}
|
||||
for name, desc in fields.iteritems():
|
||||
decos = ""
|
||||
t = desc.get("Type")
|
||||
if t and t != "informational":
|
||||
decos += " (type: %s)" % (t,)
|
||||
if desc.get("Requirement") == "mandatory":
|
||||
decos += " REQUIRED"
|
||||
lb = elm.Label(bx)
|
||||
lb.size_hint_weight = EXPAND_HORIZ
|
||||
lb.size_hint_align = FILL_BOTH
|
||||
lb.text = "%s:%s" % (name, decos)
|
||||
lb.show()
|
||||
bx.pack_end(lb)
|
||||
|
||||
en = elm.Entry(bx)
|
||||
en.size_hint_weight = EXPAND_HORIZ
|
||||
en.size_hint_align = FILL_BOTH
|
||||
en.single_line = True
|
||||
en.scrollable = True
|
||||
en.text = desc.get("Value", "")
|
||||
en.editable = (t != "informational")
|
||||
en.show()
|
||||
bx.pack_end(en)
|
||||
widgets[name] = en
|
||||
|
||||
bt = elm.Button(bx)
|
||||
bt.size_hint_weight = EXPAND_HORIZ
|
||||
bt.size_hint_align = FILL_BOTH
|
||||
bt.callback_clicked_add(on_clicked)
|
||||
bt.text = "Submit"
|
||||
bt.show()
|
||||
bx.pack_end(bt)
|
||||
|
||||
|
||||
########################################################################
|
||||
# GUI helpers:
|
||||
def popup_fatal(obj, title, message):
|
||||
|
@ -1139,6 +1294,7 @@ def popup_fatal(obj, title, message):
|
|||
bt.callback_clicked_add(lambda bt: elm.exit())
|
||||
pop.part_content_set("button1", bt)
|
||||
pop.show()
|
||||
return pop
|
||||
|
||||
|
||||
def popup_error(obj, title, message):
|
||||
|
@ -1155,12 +1311,14 @@ def popup_error(obj, title, message):
|
|||
bt.callback_clicked_add(lambda bt: pop.delete())
|
||||
pop.part_content_set("button1", bt)
|
||||
pop.show()
|
||||
return pop
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Connection Manager for Enlightenment")
|
||||
parser.add_argument("-v", "--verbose", action="count")
|
||||
parser.add_argument("-a", "--agent", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
level = logging.WARNING
|
||||
|
@ -1207,5 +1365,11 @@ if __name__ == "__main__":
|
|||
|
||||
nf.item_push("EConnMan", offline_mon.obj, techs, serv_lst.obj, "basic")
|
||||
|
||||
if args.agent:
|
||||
log.debug("create agent")
|
||||
agent = Agent(serv_lst)
|
||||
manager.RegisterAgent(agent.path)
|
||||
log.info("Registered agent at %s", agent.path)
|
||||
|
||||
elm.run()
|
||||
elm.shutdown()
|
||||
|
|
Loading…
Reference in New Issue