changeset 2219:77a3d0a28642

plugin invitations: added modify method (+ bridge) and fixed email setting in extra
author Goffi <goffi@goffi.org>
date Mon, 03 Apr 2017 00:23:01 +0200
parents 6a2fa651d7fa
children 0d27d95652a7
files src/plugins/plugin_misc_invitations.py
diffstat 1 files changed, 55 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_misc_invitations.py	Mon Apr 03 00:22:58 2017 +0200
+++ b/src/plugins/plugin_misc_invitations.py	Mon Apr 03 00:23:01 2017 +0200
@@ -48,7 +48,9 @@
 KEY_JID = u'jid'
 KEY_CREATED = u'created'
 KEY_LAST_CONNECTION = u'last_connection'
-EXTRA_RESERVED = {KEY_ID, KEY_JID, KEY_CREATED, u'jid_', u'jid', KEY_LAST_CONNECTION}
+KEY_GUEST_PROFILE = u'guest_profile'
+KEY_PASSWORD = u'password'
+EXTRA_RESERVED = {KEY_ID, KEY_JID, KEY_CREATED, u'jid_', u'jid', KEY_LAST_CONNECTION, KEY_GUEST_PROFILE, KEY_PASSWORD}
 DEFAULT_SUBJECT = D_(u"You have been invited by {host_name} to {app_name}")
 DEFAULT_BODY = D_(u"""Hello {name}!
 
@@ -70,13 +72,21 @@
         self.host = host
         self.invitations = persistent.LazyPersistentBinaryDict(u'invitations')
         host.bridge.addMethod("invitationCreate", ".plugin", in_sign='sssssssssa{ss}s', out_sign='a{ss}',
-                              method=self._createInvitation,
+                              method=self._create,
                               async=True)
         host.bridge.addMethod("invitationGet", ".plugin", in_sign='s', out_sign='a{ss}',
-                              method=self.getInvitation,
+                              method=self.get,
+                              async=True)
+        host.bridge.addMethod("invitationModify", ".plugin", in_sign='sa{ss}b', out_sign='',
+                              method=self._modify,
                               async=True)
 
-    def _createInvitation(self, jid_=u'', password=u'', name=u'', host_name=u'', email=u'', language=u'', url_template=u'', message_subject=u'', message_body=u'', extra=None, profile=u''):
+    def checkExtra(self, extra):
+        if EXTRA_RESERVED.intersection(extra):
+            raise ValueError(_(u"You can't use following key(s) in extra, they are reserved: {}").format(
+                u', '.join(EXTRA_RESERVED.intersection(extra))))
+
+    def _create(self, jid_=u'', password=u'', name=u'', host_name=u'', email=u'', language=u'', url_template=u'', message_subject=u'', message_body=u'', extra=None, profile=u''):
         # XXX: we don't use **kwargs here to keep arguments name for introspection with D-Bus bridge
 
         if extra is None:
@@ -90,14 +100,14 @@
             value = locals()[key]
             if value:
                 kwargs[key] = unicode(value)
-        d = self.createInvitation(**kwargs)
+        d = self.create(**kwargs)
         def serialize(data):
             data[KEY_JID] = data[KEY_JID].full()
         d.addCallback(serialize)
         return d
 
     @defer.inlineCallbacks
-    def createInvitation(self, **kwargs):
+    def create(self, **kwargs):
         ur"""create an invitation
 
         this will create an XMPP account and a profile, and use a UUID to retrieve them.
@@ -146,12 +156,10 @@
         ## initial checks
         extra = kwargs.pop('extra', {})
         if set(kwargs).intersection(extra):
-            raise exceptions.ValueError(_(u"You can't use following key(s) in both args and extra: {}").format(
+            raise ValueError(_(u"You can't use following key(s) in both args and extra: {}").format(
                 u', '.join(set(kwargs).intersection(extra))))
 
-        if EXTRA_RESERVED.intersection(extra):
-            raise exceptions.ValueError(_(u"You can't use following key(s) in extra, they are reserved: {}").format(
-                u', '.join(EXTRA_RESERVED.intersection(extra))))
+        self.checkExtra(extra)
 
         if not 'url_template' in extra and not 'message_body' in extra:
             raise ValueError(_(u"You need to provide url_template if you use default message body"))
@@ -172,7 +180,7 @@
         # FIXME: we could add an extra encryption key which would be used with the uuid
         #        when the invitee is connecting (e.g. with URL). This key would not be saved
         #        and could be used to encrypt profile password.
-        extra[u'password'] = password
+        extra[KEY_PASSWORD] = password
 
         jid_ = kwargs.pop(u'jid_', None)
         if not jid_:
@@ -206,7 +214,7 @@
             log.info(_(u"account {jid_} created").format(jid_=jid_.full()))
 
         ## profile creation
-        extra['guest_profile'] = guest_profile = INVITEE_PROFILE_TPL.format(uuid=id_)
+        extra[KEY_GUEST_PROFILE] = guest_profile = INVITEE_PROFILE_TPL.format(uuid=id_)
         # profile creation should not fail as we generate unique name ourselves
         yield self.host.memory.createProfile(guest_profile, password)
         yield self.host.memory.startSession(password, guest_profile)
@@ -220,6 +228,7 @@
         email = kwargs.pop(u'email', None)
 
         if email is not None:
+            extra[u'email'] = email
             url_template = kwargs.pop(u'url_template', '')
             format_args = {
                 u'uuid': id_,
@@ -264,11 +273,43 @@
         extra[KEY_JID] = jid
         defer.returnValue(extra)
 
-    def getInvitation(self, id_):
+    def get(self, id_):
         """Retrieve invitation linked to uuid if it exists
 
         @param id_(unicode): UUID linked to an invitation
-        @return dict(unicode, unicode): data associated to the invitation
+        @return (dict[unicode, unicode]): data associated to the invitation
         @raise KeyError: there is not invitation with this id_
         """
         return self.invitations[id_]
+
+    def _modify(self, id_, new_extra, replace):
+        return self.modify(id_, {unicode(k): unicode(v) for k,v in new_extra.iteritems()}, replace)
+
+    def modify(self, id_, new_extra, replace=False):
+        """Modify invitation data
+
+        @param id_(unicode): UUID linked to an invitation
+        @param new_extra(dict[unicode, unicode]): data to update
+        @param replace(bool): if True replace the data
+            else update them
+        @raise KeyError: there is not invitation with this id_
+        """
+        self.checkExtra(new_extra)
+        def gotCurrentData(current_data):
+            if replace:
+                new_data = new_extra
+                for k in EXTRA_RESERVED:
+                    try:
+                        new_data[k] = current_data[k]
+                    except KeyError:
+                        continue
+            else:
+                new_data = current_data
+                for k,v in new_extra.iteritems():
+                    new_data[k] = v
+
+            self.invitations[id_] = new_data
+
+        d = self.invitations[id_]
+        d.addCallback(gotCurrentData)
+        return d