import logging import os from twisted.web import server, guard from twisted.internet import defer, reactor, error from twisted.cred import portal from lbrynet import conf from lbrynet.daemon.Daemon import Daemon from lbrynet.daemon.Resources import LBRYindex, HostedEncryptedFile, EncryptedFileUpload from lbrynet.daemon.auth.auth import PasswordChecker, HttpPasswordRealm from lbrynet.daemon.auth.util import initialize_api_key_file from lbrynet.daemon.DaemonRequest import DaemonRequest log = logging.getLogger(__name__) class DaemonServer(object): def __init__(self, analytics_manager=None): self._api = None self.root = None self.server_port = None self.analytics_manager = analytics_manager def _setup_server(self, use_auth): ui_path = os.path.join(conf.settings.ensure_data_dir(), "lbry-ui", "active") self.root = LBRYindex(ui_path) self._api = Daemon(self.root, self.analytics_manager) self.root.putChild("view", HostedEncryptedFile(self._api)) self.root.putChild("upload", EncryptedFileUpload(self._api)) self.root.putChild(conf.settings['API_ADDRESS'], self._api) lbrynet_server = server.Site(get_site_base(use_auth, self.root)) lbrynet_server.requestFactory = DaemonRequest try: self.server_port = reactor.listenTCP( conf.settings['api_port'], lbrynet_server, interface=conf.settings['api_host']) except error.CannotListenError: log.info('Daemon already running, exiting app') raise return defer.succeed(True) @defer.inlineCallbacks def start(self, use_auth): yield self._setup_server(use_auth) yield self._api.setup() @defer.inlineCallbacks def stop(self): if self._api is not None: yield self._api._shutdown() if self.server_port is not None: yield self.server_port.stopListening() def get_site_base(use_auth, root): if use_auth: log.info("Using authenticated API") return create_auth_session(root) else: log.info("Using non-authenticated API") return server.Site(root) def create_auth_session(root): pw_path = os.path.join(conf.settings['data_dir'], ".api_keys") initialize_api_key_file(pw_path) checker = PasswordChecker.load_file(pw_path) realm = HttpPasswordRealm(root) portal_to_realm = portal.Portal(realm, [checker, ]) factory = guard.BasicCredentialFactory('Login to lbrynet api') _lbrynet_server = guard.HTTPAuthSessionWrapper(portal_to_realm, [factory, ]) return _lbrynet_server