From 5a3fb4eb5a24e250a75dac4a2a39ce5632a175b6 Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Tue, 6 Sep 2016 22:22:07 -0400 Subject: [feat] add webui command: enable/disable/status --- src/leap/bitmask/cli/bitmask_cli.py | 6 ++++ src/leap/bitmask/cli/webui.py | 39 ++++++++++++++++++++++++ src/leap/bitmask/core/_web.py | 7 +++++ src/leap/bitmask/core/dispatcher.py | 59 +++++++++++++++++++++++++++++++++---- src/leap/bitmask/core/service.py | 18 +++++------ 5 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 src/leap/bitmask/cli/webui.py (limited to 'src/leap') diff --git a/src/leap/bitmask/cli/bitmask_cli.py b/src/leap/bitmask/cli/bitmask_cli.py index 1f104c9c..3fa134a6 100755 --- a/src/leap/bitmask/cli/bitmask_cli.py +++ b/src/leap/bitmask/cli/bitmask_cli.py @@ -27,6 +27,7 @@ from twisted.internet import reactor, defer from leap.bitmask.cli.eip import Eip from leap.bitmask.cli.keys import Keys from leap.bitmask.cli.mail import Mail +from leap.bitmask.cli.webui import WebUI from leap.bitmask.cli import command from leap.bitmask.cli.user import User @@ -42,6 +43,7 @@ SERVICE COMMANDS: mail Bitmask Encrypted Mail eip Encrypted Internet Proxy keys Bitmask Keymanager + webui Bitmask Web User Interface GENERAL COMMANDS: @@ -73,6 +75,10 @@ GENERAL COMMANDS: keys = Keys() return keys.execute(raw_args) + def webui(self, raw_args): + webui = WebUI() + return webui.execute(raw_args) + # Single commands def launch(self, raw_args): diff --git a/src/leap/bitmask/cli/webui.py b/src/leap/bitmask/cli/webui.py new file mode 100644 index 00000000..d4d5f782 --- /dev/null +++ b/src/leap/bitmask/cli/webui.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# webui.py +# Copyright (C) 2016 LEAP Encryption Access Project +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Bitmask Command Line interface: webui +""" + +from leap.bitmask.cli import command + + +class WebUI(command.Command): + service = 'webui' + usage = '''{name} webui + +Bitmask Web User Interface + +SUBCOMMANDS: + + enable Start service + disable Stop service + status Display status about service + +'''.format(name=command.appname) + + commands = ['enable', 'disable', 'status'] diff --git a/src/leap/bitmask/core/_web.py b/src/leap/bitmask/core/_web.py index 3f39e435..c597d18e 100644 --- a/src/leap/bitmask/core/_web.py +++ b/src/leap/bitmask/core/_web.py @@ -71,10 +71,17 @@ class HTTPDispatcherService(service.Service): # TODO use endpoints instead self.listener = reactor.listenTCP(self.port, site, interface='127.0.0.1') + self.running = True def stopService(self): self.site.stopFactory() self.listener.stopListening() + self.running = False + + def do_status(self): + status = 'running' if self.running else 'disabled' + return {'web': status} + class Api(Resource): diff --git a/src/leap/bitmask/core/dispatcher.py b/src/leap/bitmask/core/dispatcher.py index 0ea4e478..368a5bb6 100644 --- a/src/leap/bitmask/core/dispatcher.py +++ b/src/leap/bitmask/core/dispatcher.py @@ -39,9 +39,12 @@ class SubCommand(object): __metaclass__ = APICommand def dispatch(self, service, *parts, **kw): - subcmd = parts[1] + try: + subcmd = parts[1] + _method = getattr(self, 'do_' + subcmd.upper(), None) + except IndexError: + _method = None - _method = getattr(self, 'do_' + subcmd.upper(), None) if not _method: raise RuntimeError('No such subcommand') return defer.maybeDeferred(_method, service, *parts, **kw) @@ -155,6 +158,27 @@ class MailCmd(SubCommand): return d +class WebUICmd(SubCommand): + + label = 'web' + + @register_method('dict') + def do_ENABLE(self, service, *parts, **kw): + d = service.do_enable_service(self.label) + return d + + @register_method('dict') + def do_DISABLE(self, service, *parts, **kw): + d = service.do_disable_service(self.label) + return d + + @register_method('dict') + def do_STATUS(self, webui, *parts, **kw): + print 'webui', webui + d = webui.do_status() + return d + + class KeysCmd(SubCommand): label = 'keys' @@ -267,6 +291,7 @@ class CommandDispatcher(object): self.subcommand_mail = MailCmd() self.subcommand_keys = KeysCmd() self.subcommand_events = EventsCmd() + self.subcommand_webui = WebUICmd() # XXX -------------------------------------------- # TODO move general services to another subclass @@ -298,7 +323,7 @@ class CommandDispatcher(object): def do_EIP(self, *parts): eip = self._get_service(self.subcommand_eip.label) if not eip: - return _format_result('eip: disabled') + return _format_result({'eip': 'disabled'}) subcmd = parts[1] dispatch = self._subcommand_eip.dispatch @@ -322,16 +347,39 @@ class CommandDispatcher(object): kw = {'bonafide': bonafide} if not mail: - return _format_result('mail: disabled') + return _format_result({'mail': 'disabled'}) if subcmd == 'disable': d = dispatch(self.core) - else: + elif subcmd != 'enable': d = dispatch(mail, *parts, **kw) d.addCallbacks(_format_result, _format_error) return d + + def do_WEBUI(self, *parts): + subcmd = parts[1] + dispatch = self.subcommand_webui.dispatch + + if subcmd == 'enable': + d = dispatch(self.core, *parts) + + webui_label = 'web' + webui = self._get_service(webui_label) + kw = {} + + if not webui: + return _format_result({'webui': 'disabled'}) + if subcmd == 'disable': + d = dispatch(self.core, *parts) + elif subcmd != 'enable': + d = dispatch(webui, *parts, **kw) + + d.addCallbacks(_format_result, _format_error) + return d + + def do_KEYS(self, *parts): dispatch = self.subcommand_keys.dispatch @@ -353,6 +401,7 @@ class CommandDispatcher(object): d.addCallbacks(_format_result, _format_error) return d + def dispatch(self, msg): cmd = msg[0] diff --git a/src/leap/bitmask/core/service.py b/src/leap/bitmask/core/service.py index b473f58f..c254564c 100644 --- a/src/leap/bitmask/core/service.py +++ b/src/leap/bitmask/core/service.py @@ -81,7 +81,7 @@ class BitmaskBackend(configurable.ConfigurableService): def init_bonafide(self): bf = BonafideService(self.basedir) - bf.setName("bonafide") + bf.setName('bonafide') bf.setServiceParent(self) # TODO ---- these hooks should be activated only if # (1) we have enabled that service @@ -119,9 +119,9 @@ class BitmaskBackend(configurable.ConfigurableService): zs.setServiceParent(self) def init_web(self): - # FIXME try to import leap.bitmask_www and fail otherwise - http = _web.HTTPDispatcherService(self) - http.setServiceParent(self) + service = _web.HTTPDispatcherService + web = self._maybe_start_service( + 'web', service, self) def init_websockets(self): from leap.bitmask.core import websocket @@ -169,15 +169,13 @@ class BitmaskBackend(configurable.ConfigurableService): elif service == 'web': self.init_web() - self.init_http() - - return 'ok' + return {'enabled': 'ok'} def do_disable_service(self, service): assert service in self.service_names # TODO -- should stop also? self.set_config('services', service, 'False') - return 'ok' + return {'disabled': 'ok'} class BackendCommands(object): @@ -191,7 +189,7 @@ class BackendCommands(object): def do_status(self): # we may want to make this tuple a class member - services = ('soledad', 'keymanager', 'mail', 'eip') + services = ('soledad', 'keymanager', 'mail', 'eip', 'web') status = {} for name in services: @@ -212,7 +210,7 @@ class BackendCommands(object): def do_stats(self): log.msg('BitmaskCore Service STATS') mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss - return {'mem_usage': '%s KB' % (mem / 1024)} + return {'mem_usage': '%s MB' % (mem / 1024)} def do_shutdown(self): self.core.stopService() -- cgit v1.2.3