diff options
| -rwxr-xr-x | src/leap/bitmask/cli/bitmask_cli.py | 6 | ||||
| -rw-r--r-- | src/leap/bitmask/cli/webui.py | 39 | ||||
| -rw-r--r-- | src/leap/bitmask/core/_web.py | 7 | ||||
| -rw-r--r-- | src/leap/bitmask/core/dispatcher.py | 59 | ||||
| -rw-r--r-- | src/leap/bitmask/core/service.py | 18 | 
5 files changed, 114 insertions, 15 deletions
| diff --git a/src/leap/bitmask/cli/bitmask_cli.py b/src/leap/bitmask/cli/bitmask_cli.py index 1f104c9..3fa134a 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 0000000..d4d5f78 --- /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 <http://www.gnu.org/licenses/>. + +""" +Bitmask Command Line interface: webui +""" + +from leap.bitmask.cli import command + + +class WebUI(command.Command): +    service = 'webui' +    usage = '''{name} webui <subcommand> + +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 3f39e43..c597d18 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 0ea4e47..368a5bb 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 b473f58..c254564 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() | 
