Source code for paradrop.core.agent.wamp_session

'''
The WAMP session of the paradrop daemon
'''
from __future__ import print_function
from twisted.internet.defer import inlineCallbacks
from autobahn.wamp import auth

from paradrop.lib.misc import pdinstall
from paradrop.base.output import out
from paradrop.base import nexus
from paradrop.base.cxbr import BaseSession


[docs]def ensure_unicode(s): if hasattr(s, 'decode'): return s.decode('ascii') else: return s
[docs]class WampSession(BaseSession): # Make this a class variable because a new WampSession object is created # whenever the WAMP connection resets, but we only call set_update_fetcher # on program initialization. update_fetcher = None def __init__(self, *args, **kwargs): self.uriPrefix = 'org.paradrop.' super(WampSession, self).__init__(*args, **kwargs)
[docs] def onConnect(self): out.info('Router session connected.') if (nexus.core.info.pdid and nexus.core.getKey('apitoken')): out.info('Starting WAMP-CRA authentication on realm "{}" as user "{}"...'\ .format(self.config.realm, nexus.core.info.pdid)) self.join(self.config.realm, [u'wampcra'], ensure_unicode(nexus.core.info.pdid))
[docs] def onChallenge(self, challenge): if challenge.method == u"wampcra": out.verbose("WAMP-CRA challenge received: {}".format(challenge)) wampPassword = nexus.core.getKey('apitoken') if u'salt' in challenge.extra: # salted secret key = auth.derive_key(wampPassword, challenge.extra['salt'], challenge.extra['iterations'], challenge.extra['keylen']) else: # plain, unsalted secret key = wampPassword # compute signature for challenge, using the key signature = auth.compute_wcs(key, challenge.extra['challenge']) # return the signature to the router for verification return signature else: raise Exception("Invalid authmethod {}".format(challenge.method))
[docs] @inlineCallbacks def onJoin(self, details): out.info('Router session joined') yield self.subscribe(self.updatesPending, self.uriPrefix + 'updatesPending') yield self.register(self.update, self.uriPrefix + 'update') yield BaseSession.onJoin(self, details)
[docs] def onLeave(self, details): out.info("Router session left: {}".format(details)) nexus.core.wamp_connected = False self.disconnect()
[docs] def onDisconnect(self): out.info("Router session disconnected.")
[docs] def update(self, pdid, data): print("Sending command {} to pdinstall".format(data['command'])) success = pdinstall.sendCommand(data['command'], data) # NOTE: If successful, this process will probably be going down soon. if success: return "Sent command to pdinstall" else: return "Sending command to pdinstall failed"
[docs] @classmethod def set_update_fetcher(cls, update_fetcher): WampSession.update_fetcher = update_fetcher
[docs] @inlineCallbacks def updatesPending(self, pdid): out.info('Notified of updates...') if WampSession.update_fetcher is not None: out.info('Pulling updates from the server...') yield WampSession.update_fetcher.pull_update()