def updateSelectedVCards(self):
     status = IStatusMessage(self.request)
     widget = self.widgets.get('users')
     if widget.extract() == NO_VALUE:
         status.add(_(u"You first need to choose the users"), "error")
         return
     self.updateVCards(member_ids=self.getChosenMembers())
     return status.add(_(u"The selected users' vCards are being updated in "
                         u"the background."), "info")
 def deregisterSelected(self):
     status = IStatusMessage(self.request)
     widget = self.widgets.get('users')
     if widget.extract() == NO_VALUE:
         status.add(_(u"You first need to choose the users to deregister"),
                    "error")
         return
     setup.deregisterXMPPUsers(self.context, self.getChosenMembers())
     return status.add(_(u"The selected users are being deregistered in "
                         u"the background."), "info")
Esempio n. 3
0
 def updateSelectedVCards(self):
     status = IStatusMessage(self.request)
     widget = self.widgets.get('users')
     if widget.extract() == NO_VALUE:
         status.add(_(u"You first need to choose the users"), "error")
         return
     self.updateVCards(member_ids=self.getChosenMembers())
     return status.add(
         _(u"The selected users' vCards are being updated in "
           u"the background."), "info")
Esempio n. 4
0
 def deregisterSelected(self):
     status = IStatusMessage(self.request)
     widget = self.widgets.get('users')
     if widget.extract() == NO_VALUE:
         status.add(_(u"You first need to choose the users to deregister"),
                    "error")
         return
     setup.deregisterXMPPUsers(self.context, self.getChosenMembers())
     return status.add(
         _(u"The selected users are being deregistered in "
           u"the background."), "info")
 def registerAll(self):
     status = IStatusMessage(self.request)
     member_ids = users.getAllMemberIds()
     try:
         setup.registerXMPPUsers(self.context, member_ids)
     except AdminClientNotConnected:
         status.add(
             _(u"We are not yet connected to the XMPP "
               u"server. Either your settings are incorrect, or "
               u"you're trying to register users immediately after the "
               u"ZServer has been restarted. If your settings are correct, "
               u"then try again, it should work now. "), "warn")
         return
     status.add(_(
         u"All users are being registered in the background. "
         "This might take a few minutes and your site might become "
         "unresponsive."), "info")
Esempio n. 6
0
 def registerAll(self):
     status = IStatusMessage(self.request)
     member_ids = users.getAllMemberIds()
     try:
         setup.registerXMPPUsers(self.context, member_ids)
     except AdminClientNotConnected:
         status.add(
             _(u"We are not yet connected to the XMPP "
               u"server. Either your settings are incorrect, or "
               u"you're trying to register users immediately after the "
               u"ZServer has been restarted. If your settings are correct, "
               u"then try again, it should work now. "), "warn")
         return
     status.add(
         _(u"All users are being registered in the background. "
           "This might take a few minutes and your site might become "
           "unresponsive."), "info")
Esempio n. 7
0
 def handleSave(self, action):
     data, errors = self.extractData()
     if errors:
         self.status = self.formErrorsMessage
         return
     self.applyChanges(data)
     IStatusMessage(self.request).addStatusMessage(_(u"Changes saved"),
                                                   "info")
     self.context.REQUEST.RESPONSE.redirect("@@xmpp-settings")
 def handleSave(self, action):
     data, errors = self.extractData()
     if errors:
         self.status = self.formErrorsMessage
         return
     self.applyChanges(data)
     IStatusMessage(self.request).addStatusMessage(_(u"Changes saved"),
                                                   "info")
     self.context.REQUEST.RESPONSE.redirect("@@xmpp-settings")
 def registerSelected(self):
     status = IStatusMessage(self.request)
     widget = self.widgets.get('users')
     if widget.extract() == NO_VALUE:
         status.add(_(u"You first need to choose the users to register"),
                    "error")
         return
     try:
         setup.registerXMPPUsers(self.context, self.getChosenMembers())
     except AdminClientNotConnected:
         status.add(
             _(u"We are not yet connected to the XMPP "
               u"server. Either your settings are incorrect, or "
               u"you're trying to register users immediately after the "
               u"ZServer has been restarted. If your settings are correct, "
               u"then try again, it should work now. "), "warn")
         return
     return status.add(_(u"The selected users are being registered "
                         u"in the background."), "info")
Esempio n. 10
0
 def registerSelected(self):
     status = IStatusMessage(self.request)
     widget = self.widgets.get('users')
     if widget.extract() == NO_VALUE:
         status.add(_(u"You first need to choose the users to register"),
                    "error")
         return
     try:
         setup.registerXMPPUsers(self.context, self.getChosenMembers())
     except AdminClientNotConnected:
         status.add(
             _(u"We are not yet connected to the XMPP "
               u"server. Either your settings are incorrect, or "
               u"you're trying to register users immediately after the "
               u"ZServer has been restarted. If your settings are correct, "
               u"then try again, it should work now. "), "warn")
         return
     return status.add(
         _(u"The selected users are being registered "
           u"in the background."), "info")
Esempio n. 11
0
class XMPPSettingsEditForm(controlpanel.RegistryEditForm):
    """ XMPP settings form.
    """
    schema = IXMPPSettings
    id = "XMPPSettingsEditForm"
    label = _(u"XMPP settings")

    @button.buttonAndHandler(_('Save'), name=None)
    def handleSave(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        self.applyChanges(data)
        IStatusMessage(self.request).addStatusMessage(_(u"Changes saved"),
                                                      "info")
        self.context.REQUEST.RESPONSE.redirect("@@xmpp-settings")

    @button.buttonAndHandler(_('Cancel'), name='cancel')
    def handleCancel(self, action):
        IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"),
                                                      "info")
        self.request.response.redirect(
            "%s/%s" % (self.context.absolute_url(), self.control_panel_view))
Esempio n. 12
0
    def deregisterAll(self):
        portal = self.context
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IXMPPSettings, check=False)
        status = IStatusMessage(self.request)
        client = queryUtility(IAdminClient)
        if client is None:
            status.add(UTILITY_NOT_FOUND_MESSAGE, "error")
            return

        @newzodbconnection(portal=portal)
        def resultReceived(result):
            items = [item.attributes for item in result.query.children]
            if items[0].has_key('node'):
                for item in reversed(items):
                    iq = IQ(client.admin.xmlstream, 'get')
                    iq['to'] = settings.xmpp_domain
                    query = iq.addElement((NS_DISCO_ITEMS, 'query'))
                    query['node'] = item['node']
                    iq.send().addCallbacks(resultReceived)
            else:
                member_jids = [item['jid'] for item in items]
                if settings.admin_jid in member_jids:
                    member_jids.remove(settings.admin_jid)
                member_ids = [item.split('@')[0] for item in member_jids]
                if member_ids:
                    portal = getSite()
                    setup.deregisterXMPPUsers(portal, member_ids)
            return result

        d = client.admin.getRegisteredUsers()
        d.addCallbacks(resultReceived)
        status.add(_(u"The XMPP server is being instructed to deregister all "
                     u"the users. This might take some minutes to complete."),
                   "info")
        return d
Esempio n. 13
0
    def deregisterAll(self):
        portal = self.context
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IXMPPSettings, check=False)
        status = IStatusMessage(self.request)
        client = queryUtility(IAdminClient)
        if client is None:
            status.add(UTILITY_NOT_FOUND_MESSAGE, "error")
            return

        @newzodbconnection(portal=portal)
        def resultReceived(result):
            items = [item.attributes for item in result.query.children]
            if items[0].has_key('node'):
                for item in reversed(items):
                    iq = IQ(client.admin.xmlstream, 'get')
                    iq['to'] = settings.xmpp_domain
                    query = iq.addElement((NS_DISCO_ITEMS, 'query'))
                    query['node'] = item['node']
                    iq.send().addCallbacks(resultReceived)
            else:
                member_jids = [item['jid'] for item in items]
                if settings.admin_jid in member_jids:
                    member_jids.remove(settings.admin_jid)
                member_ids = [item.split('@')[0] for item in member_jids]
                if member_ids:
                    portal = getSite()
                    setup.deregisterXMPPUsers(portal, member_ids)
            return result

        d = client.admin.getRegisteredUsers()
        d.addCallbacks(resultReceived)
        status.add(
            _(u"The XMPP server is being instructed to deregister all "
              u"the users. This might take some minutes to complete."), "info")
        return d
Esempio n. 14
0
class IXMPPUserSetup(Interface):
    """
    """
    users = schema.List(
        title=_(u"label_users", default=u"Choose Users"),
        description=_(u"help_user_setup",
                      default=u"Choose here the users you'd like to register "
                      u"or deregister from the XMPP server."),
        value_type=schema.TextLine(),
        required=True,
    )

    register_selected = button.Button(
        title=_(u'label_register_selected',
                default=u"Register Selected Users"),
        description=_(u"help_register_selected",
                      default=u"Click this button to let the above "
                      "selected users be registered on the XMPP "
                      "server. Already registered users will be "
                      "ignored."),
        required=False,
    )

    deregister_selected = button.Button(
        title=_(u'label_deregister_selected',
                default=u"Deregister Selected Users"),
        description=_(u"help_deregister_selected",
                      default=u"Click this button to deregister the "
                      "above selected users from the XMPP server."),
        required=False,
    )

    update_selected_vcards = button.Button(
        title=_(u'label_update_selected_vcards',
                default=u"Update selected users' vCards"),
        description=_(
            u"help_update_selected_vcards",
            default=u"Click here to update the vCards of the above selected "
            "users in the site."),
        required=False,
    )

    register_all = button.Button(
        title=_(u'label_register_all', default=u"Register ALL Users"),
        description=_(u"help_register_all",
                      default=u"Click this button to register ALL "
                      "the users in the site on the XMPP "
                      "server. Already registered users will be "
                      "ignored. BE AWARE: if you register lots "
                      "of users and have auto-subscribe turned on, "
                      "your Plone server will be very busy with multiple "
                      "threads and may become unresponsive for some "
                      "minutes."),
        required=False,
    )

    deregister_all = button.Button(
        title=_(u'label_deregister_all', default=u"Deregister ALL Users"),
        description=_(u"help_deregister_all",
                      default=u"Click this button to deregister ALL "
                      "the users in the site from the XMPP server."),
        required=False,
    )

    update_vcards = button.Button(
        title=_(u'label_update_vcards', default=u"Update ALL Users' vCards"),
        description=_(u"help_update_vcards",
                      default=u"Click here to update the vCards of ALL "
                      "the users in the site."),
        required=False,
    )

    # XXX: Useful in certain circumstances, but dangerous and should probably
    # not be available by default.
    #
    clear_all_passwords = button.Button(
        title=_(u'label_clear_passwords',
                default=u"Completely wipe password storage"),
        description=_(u"help_clear_passwords",
                      default=u"DON'T CLICK THIS UNLESS YOU KNOW WHAT "
                      u"YOU'RE DOING! This will remove ALL the "
                      u"entries in the XMPP password storage "
                      u"utility in Plone and should only be useful "
                      u"in very rare cases or while developing."),
        required=False,
    )
Esempio n. 15
0
 def clearAllPasswords(self):
     status = IStatusMessage(self.request)
     pass_storage = getUtility(IXMPPPasswordStorage)
     pass_storage.clear()
     status.add(_(u"The password storage has been wiped."), "info")
Esempio n. 16
0
    def updateVCards(self):
        """
        """
        portal = self.context
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IXMPPSettings, check=False)
        status = IStatusMessage(self.request)
        client = queryUtility(IAdminClient)
        portal_url = getToolByName(portal, 'portal_url')()
        member_dicts = []
        pass_storage = getUtility(IXMPPPasswordStorage)
        if client is None:
            status.add(UTILITY_NOT_FOUND_MESSAGE, "error")
            return

        # XXX: This is a hack. We get vcard data for all users in the site,
        # without yet knowing whether they are actually registered in the
        # XMPP server. We do this here because getPersonalPortrait doesn't
        # work in callbacks (due to Request not being set up properly).
        xmpp_users = getUtility(IXMPPUsers)
        mtool = getToolByName(portal, 'portal_membership')
        member_ids = users.getAllMemberIds()
        for member_id in member_ids:
            member = mtool.getMemberById(member_id)
            fullname = member.getProperty('fullname').decode('utf-8')
            user_jid = xmpp_users.getUserJID(member_id)
            portrait = mtool.getPersonalPortrait(member_id)
            if isinstance(portrait, FSImage):
                raw_image = portrait._data
            else:
                raw_image = portrait.data
            udict = {
                'fullname': fullname,
                'nickname': member_id,
                'email': member.getProperty('email'),
                'userid': user_jid.userhost(),
                'jabberid': user_jid.userhost(),
                'url': '%s/author/%s' % (portal_url, member_id),
                'image_type': portrait.content_type,
                'raw_image': raw_image,
                'jid_obj': user_jid,
                'pass': pass_storage.get(member_id)
            }
            member_dicts.append(udict)

        @newzodbconnection(portal=portal)
        def resultReceived(result):
            items = [item.attributes for item in result.query.children]
            if 'node' in items[0]:
                for item in reversed(items):
                    iq = IQ(client.admin.xmlstream, 'get')
                    iq['to'] = settings.xmpp_domain
                    query = iq.addElement((NS_DISCO_ITEMS, 'query'))
                    query['node'] = item['node']
                    iq.send().addCallbacks(resultReceived)
            else:
                member_jids = [item['jid'] for item in items]
                if settings.admin_jid in member_jids:
                    member_jids.remove(settings.admin_jid)
                registered_member_dicts = \
                    [d for d in member_dicts if d['jabberid'] in member_jids]

                @newzodbconnection(portal=portal)
                def updateVCard():
                    mdict = registered_member_dicts.pop()
                    setup.setVCard(
                        mdict,
                        mdict['jid_obj'],
                        mdict['pass'],
                        updateVCard)

                if len(registered_member_dicts):
                    zr = getUtility(IZopeReactor)
                    zr.reactor.callInThread(updateVCard)
            return

        d = client.admin.getRegisteredUsers()
        d.addCallbacks(resultReceived)
        status.add(_(u"Each XMPP-registered user is having their vCard "
                     u"updated. This might take some minutes to complete."),
                   "info")
        return d
Esempio n. 17
0
    def updateVCards(self, member_ids=[]):
        """ """
        portal = self.context
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IXMPPSettings, check=False)
        status = IStatusMessage(self.request)
        client = queryUtility(IAdminClient)
        portal_url = getToolByName(portal, 'portal_url')()
        member_dicts = []
        pass_storage = getUtility(IXMPPPasswordStorage)
        if client is None:
            status.add(UTILITY_NOT_FOUND_MESSAGE, "error")
            return

        # XXX: This is a hack. We get vcard data for all users in the site,
        # without yet knowing whether they are actually registered in the
        # XMPP server. We do this here because getPersonalPortrait doesn't
        # work in callbacks (due to Request not being set up properly).
        xmpp_users = getUtility(IXMPPUsers)
        mtool = getToolByName(portal, 'portal_membership')
        member_ids = member_ids or users.getAllMemberIds()
        log.info('Total members are: %d' % len(member_ids))
        i = 0
        for member_id in member_ids:
            member = mtool.getMemberById(member_id)
            fullname = member.getProperty('fullname').decode('utf-8')
            user_jid = xmpp_users.getUserJID(member_id)
            portrait = mtool.getPersonalPortrait(member_id)
            if isinstance(portrait, FSImage):
                raw_image = portrait._data
            else:
                raw_image = portrait.data
            udict = {
                'fullname': fullname,
                'nickname': member_id,
                'email': member.getProperty('email'),
                'userid': user_jid.userhost(),
                'jabberid': user_jid.userhost(),
                'url': '%s/author/%s' % (portal_url, member_id),
                'image_type': portrait.content_type,
                'raw_image': raw_image,
                'jid_obj': user_jid,
                'pass': pass_storage.get(member_id)
            }
            member_dicts.append(udict)
            i += 1
            log.info('Fetched details for member %d, %s' % (i, fullname))

        @newzodbconnection(portal=portal)
        def resultReceived(result):
            items = [item.attributes for item in result.query.children]
            if 'node' in items[0]:
                for item in reversed(items):
                    iq = IQ(client.admin.xmlstream, 'get')
                    iq['to'] = settings.xmpp_domain
                    query = iq.addElement((NS_DISCO_ITEMS, 'query'))
                    query['node'] = item['node']
                    iq.send().addCallbacks(resultReceived)
            else:
                member_jids = [item['jid'] for item in items]
                if settings.admin_jid in member_jids:
                    member_jids.remove(settings.admin_jid)
                registered_member_dicts = \
                    [d for d in member_dicts if d['jabberid'] in member_jids]

                @newzodbconnection(portal=portal)
                def updateVCard():
                    mdict = registered_member_dicts.pop()
                    setup.setVCard(mdict, mdict['jid_obj'], mdict['pass'],
                                   updateVCard)

                if len(registered_member_dicts):
                    zr = getUtility(IZopeReactor)
                    zr.reactor.callInThread(updateVCard)
            return

        d = client.admin.getRegisteredUsers()
        d.addCallbacks(resultReceived)
        status.add(
            _(u"Each XMPP-registered user is having their vCard "
              u"updated. This might take some minutes to complete."), "info")
        return d
Esempio n. 18
0
UserAndGroupSelectionWidget_installed = True
try:
    # We have installed UserAndGroupSelectionWidget with version greated
    # then 2.0.4
    from Products.UserAndGroupSelectionWidget.z3cform.widget import \
        UsersAndGroupsSelectionWidgetFactory
except ImportError:
    # UserAndGroupSelectionWidget > 2.0.4 not found
    UserAndGroupSelectionWidget_installed = False


UTILITY_NOT_FOUND_MESSAGE = _(
    u"The XMPP Twisted utility could not be "
    u"found. Either your XMPP settings are incorrect, or the Zope "
    u"server was just restarted and the utility not yet "
    u"registered again (it's registered upon page load). If "
    u"it's the second case, please try again. Otherwise, check "
    u"your XMPP settings.")


class XMPPSettingsEditForm(controlpanel.RegistryEditForm):
    """ XMPP settings form.
    """
    schema = IXMPPSettings
    id = "XMPPSettingsEditForm"
    label = _(u"XMPP settings")

    @button.buttonAndHandler(_('Save'), name=None)
    def handleSave(self, action):
        data, errors = self.extractData()
Esempio n. 19
0
 def handleCancel(self, action):
     IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"),
                                                   "info")
     self.request.response.redirect(
         "%s/%s" % (self.context.absolute_url(), self.control_panel_view))
Esempio n. 20
0
class IXMPPSettings(Interface):
    """ Global XMPP settings. This describes records stored in the
        configuration registry and obtainable via plone.registry.
    """
    xmpp_domain = schema.TextLine(
        title=_(u"label_xmpp_domain", default=u"XMPP Domain"),
        description=_(
            u"help_xmpp_domain",
            default=u"The domain which the XMPP server will serve."
            u"This is also the domain under which users are "
            u"registered. XMPP user ids are made up of the plone "
            u"username and domain, like this: ${username}@${domain}."),
        required=True,
        default=u'localhost',
    )

    hostname = schema.TextLine(
        title=_(u"label_server_hostname", default=u"XMPP Server Hostname"),
        description=_(
            u"help_server_hostname",
            default=u"The hostname of the server on which the XMPP server "
            u"is running. Useful when you are running your XMPP server "
            u"on the same server, LAN or VPN as your Plone site. "
            u"Otherwise, keep the same as the XMPP domain."),
        required=True,
        default=u'localhost',
    )

    port = schema.Int(
        title=_(u"label_server_port", default=u"XMPP Server Port"),
        description=_(
            u"help_server_port",
            default=u"The port number of the XMPP server. Default is 5222."),
        required=True,
        default=5222,
    )

    admin_jid = schema.TextLine(
        title=_(u"label_xmpp_admin_jid", default=u"XMPP Admin JID"),
        description=_(
            u"help_xmpp_admin_jid",
            default=u"The Jabber ID of an XMPP user with administration "
            u"rights. Plone uses this user to manage (e.g "
            u"register/unregister) other XMPP users."),
        required=True,
        default=u'admin@localhost',
    )

    admin_password = schema.Password(
        title=_(u"label_xmpp_admin_password", default="XMPP Admin Password"),
        required=True,
        default=u'admin',
    )

    auto_register_on_login = schema.Bool(
        title=_(u"label_xmpp_auto_register_on_login",
                default=u"Automatically register for XMPP on login"),
        description=_(u"help_xmpp_auto_register_on_login",
                      default=u"Check this option if you want users to be "
                      u"automatically registered on the XMPP server."
                      u"They will be registered once they visit "
                      u"this Plone site while logged in."
                      u"You can also register users manually on the XMPP "
                      u"user setup page."),
        default=False,
    )

    auto_subscribe = schema.Bool(
        title=_(u"label_xmpp_auto_subscribe",
                default=u"Auto-subscribe XMPP users"),
        description=_(
            u"help_xmpp_auto_subscribe",
            default=u"Should XMPP users automatically be subscribed to one "
            u"another? "
            u"Users will automatically subscribe to all other XMPP "
            u"users in the site, but each subscription will only "
            u"be confirmed once the user being subscribed to logs "
            u"in. Be aware that this is probably a bad idea on "
            u"sites with many users!"),
        default=False,
    )
Esempio n. 21
0
 def handleCancel(self, action):
     IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"),
                                                   "info")
     self.request.response.redirect("%s/%s" % (self.context.absolute_url(),
                                               self.control_panel_view))
Esempio n. 22
0
 def clearAllPasswords(self):
     status = IStatusMessage(self.request)
     pass_storage = getUtility(IXMPPPasswordStorage)
     pass_storage.clear()
     status.add(_(u"The password storage has been wiped."), "info")
Esempio n. 23
0
class XMPPUserSetupForm(form.Form):
    """ XMPP User Setup Form.
    """
    ignoreContext = True
    id = "XMPPUserSetupForm"
    label = _(u"XMPP User Setup")
    description = _(
        "help_xmpp_user_setup", """
        This page lets you register and deregister Plone users on the XMPP
        server. You can either choose specific users, or do it for all users in
        the site. Make sure you have set the correct settings for you XMPP
        server before submitting.
        """)
    fields = field.Fields(IXMPPUserSetup)

    if UserAndGroupSelectionWidget_installed:
        fields['users'].widgetFactory = UsersAndGroupsSelectionWidgetFactory

    def update(self):
        super(XMPPUserSetupForm, self).update()
        if self.request.form.get('form.widgets.register_all'):
            return self.registerAll()
        elif self.request.form.get('form.widgets.deregister_all'):
            return self.deregisterAll()
        elif self.request.form.get('form.widgets.update_vcards'):
            return self.updateVCards()
        elif self.request.form.get('form.widgets.update_selected_vcards'):
            return self.updateSelectedVCards()
        elif self.request.form.get('form.widgets.register_selected'):
            return self.registerSelected()
        elif self.request.form.get('form.widgets.deregister_selected'):
            return self.deregisterSelected()
        elif self.request.form.get('form.widgets.clear_all_passwords'):
            return self.clearAllPasswords()

    def registerAll(self):
        status = IStatusMessage(self.request)
        member_ids = users.getAllMemberIds()
        try:
            setup.registerXMPPUsers(self.context, member_ids)
        except AdminClientNotConnected:
            status.add(
                _(u"We are not yet connected to the XMPP "
                  u"server. Either your settings are incorrect, or "
                  u"you're trying to register users immediately after the "
                  u"ZServer has been restarted. If your settings are correct, "
                  u"then try again, it should work now. "), "warn")
            return
        status.add(
            _(u"All users are being registered in the background. "
              "This might take a few minutes and your site might become "
              "unresponsive."), "info")

    def deregisterAll(self):
        portal = self.context
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IXMPPSettings, check=False)
        status = IStatusMessage(self.request)
        client = queryUtility(IAdminClient)
        if client is None:
            status.add(UTILITY_NOT_FOUND_MESSAGE, "error")
            return

        @newzodbconnection(portal=portal)
        def resultReceived(result):
            items = [item.attributes for item in result.query.children]
            if items[0].has_key('node'):
                for item in reversed(items):
                    iq = IQ(client.admin.xmlstream, 'get')
                    iq['to'] = settings.xmpp_domain
                    query = iq.addElement((NS_DISCO_ITEMS, 'query'))
                    query['node'] = item['node']
                    iq.send().addCallbacks(resultReceived)
            else:
                member_jids = [item['jid'] for item in items]
                if settings.admin_jid in member_jids:
                    member_jids.remove(settings.admin_jid)
                member_ids = [item.split('@')[0] for item in member_jids]
                if member_ids:
                    portal = getSite()
                    setup.deregisterXMPPUsers(portal, member_ids)
            return result

        d = client.admin.getRegisteredUsers()
        d.addCallbacks(resultReceived)
        status.add(
            _(u"The XMPP server is being instructed to deregister all "
              u"the users. This might take some minutes to complete."), "info")
        return d

    def updateVCards(self, member_ids=[]):
        """ """
        portal = self.context
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IXMPPSettings, check=False)
        status = IStatusMessage(self.request)
        client = queryUtility(IAdminClient)
        portal_url = getToolByName(portal, 'portal_url')()
        member_dicts = []
        pass_storage = getUtility(IXMPPPasswordStorage)
        if client is None:
            status.add(UTILITY_NOT_FOUND_MESSAGE, "error")
            return

        # XXX: This is a hack. We get vcard data for all users in the site,
        # without yet knowing whether they are actually registered in the
        # XMPP server. We do this here because getPersonalPortrait doesn't
        # work in callbacks (due to Request not being set up properly).
        xmpp_users = getUtility(IXMPPUsers)
        mtool = getToolByName(portal, 'portal_membership')
        member_ids = member_ids or users.getAllMemberIds()
        log.info('Total members are: %d' % len(member_ids))
        i = 0
        for member_id in member_ids:
            member = mtool.getMemberById(member_id)
            fullname = member.getProperty('fullname').decode('utf-8')
            user_jid = xmpp_users.getUserJID(member_id)
            portrait = mtool.getPersonalPortrait(member_id)
            if isinstance(portrait, FSImage):
                raw_image = portrait._data
            else:
                raw_image = portrait.data
            udict = {
                'fullname': fullname,
                'nickname': member_id,
                'email': member.getProperty('email'),
                'userid': user_jid.userhost(),
                'jabberid': user_jid.userhost(),
                'url': '%s/author/%s' % (portal_url, member_id),
                'image_type': portrait.content_type,
                'raw_image': raw_image,
                'jid_obj': user_jid,
                'pass': pass_storage.get(member_id)
            }
            member_dicts.append(udict)
            i += 1
            log.info('Fetched details for member %d, %s' % (i, fullname))

        @newzodbconnection(portal=portal)
        def resultReceived(result):
            items = [item.attributes for item in result.query.children]
            if 'node' in items[0]:
                for item in reversed(items):
                    iq = IQ(client.admin.xmlstream, 'get')
                    iq['to'] = settings.xmpp_domain
                    query = iq.addElement((NS_DISCO_ITEMS, 'query'))
                    query['node'] = item['node']
                    iq.send().addCallbacks(resultReceived)
            else:
                member_jids = [item['jid'] for item in items]
                if settings.admin_jid in member_jids:
                    member_jids.remove(settings.admin_jid)
                registered_member_dicts = \
                    [d for d in member_dicts if d['jabberid'] in member_jids]

                @newzodbconnection(portal=portal)
                def updateVCard():
                    mdict = registered_member_dicts.pop()
                    setup.setVCard(mdict, mdict['jid_obj'], mdict['pass'],
                                   updateVCard)

                if len(registered_member_dicts):
                    zr = getUtility(IZopeReactor)
                    zr.reactor.callInThread(updateVCard)
            return

        d = client.admin.getRegisteredUsers()
        d.addCallbacks(resultReceived)
        status.add(
            _(u"Each XMPP-registered user is having their vCard "
              u"updated. This might take some minutes to complete."), "info")
        return d

    def getChosenMembers(self):
        """ The Products.UserAndGroupSelectionWidget can return users and
            groups.

            Identify the chosen groups and return their members as well as the
            individually chosen members (while removing duplicates).
        """
        members_and_groups = self.request.form.get('form.widgets.users')
        members = []

        if UserAndGroupSelectionWidget_installed:
            pg = getToolByName(self.context, 'portal_groups')
            groups = pg.getGroupIds()
            chosen_groups = \
                list(set(members_and_groups).intersection(set(groups)))
            chosen_members = \
                list(set(members_and_groups).difference(set(groups)))

            for g in chosen_groups:
                chosen_members += pg.getGroupById(g).getGroupMemberIds()

            members = list(set(chosen_members))
        else:
            # Case when Products.UserAndGroupSelectionWidget is not
            # installed/used
            members = [
                member for member in members_and_groups.split('\r\n') if member
            ]
        return members

    def updateSelectedVCards(self):
        status = IStatusMessage(self.request)
        widget = self.widgets.get('users')
        if widget.extract() == NO_VALUE:
            status.add(_(u"You first need to choose the users"), "error")
            return
        self.updateVCards(member_ids=self.getChosenMembers())
        return status.add(
            _(u"The selected users' vCards are being updated in "
              u"the background."), "info")

    def deregisterSelected(self):
        status = IStatusMessage(self.request)
        widget = self.widgets.get('users')
        if widget.extract() == NO_VALUE:
            status.add(_(u"You first need to choose the users to deregister"),
                       "error")
            return
        setup.deregisterXMPPUsers(self.context, self.getChosenMembers())
        return status.add(
            _(u"The selected users are being deregistered in "
              u"the background."), "info")

    def registerSelected(self):
        status = IStatusMessage(self.request)
        widget = self.widgets.get('users')
        if widget.extract() == NO_VALUE:
            status.add(_(u"You first need to choose the users to register"),
                       "error")
            return
        try:
            setup.registerXMPPUsers(self.context, self.getChosenMembers())
        except AdminClientNotConnected:
            status.add(
                _(u"We are not yet connected to the XMPP "
                  u"server. Either your settings are incorrect, or "
                  u"you're trying to register users immediately after the "
                  u"ZServer has been restarted. If your settings are correct, "
                  u"then try again, it should work now. "), "warn")
            return
        return status.add(
            _(u"The selected users are being registered "
              u"in the background."), "info")

    def clearAllPasswords(self):
        status = IStatusMessage(self.request)
        pass_storage = getUtility(IXMPPPasswordStorage)
        pass_storage.clear()
        status.add(_(u"The password storage has been wiped."), "info")
Esempio n. 24
0
log = logging.getLogger(__name__)
UserAndGroupSelectionWidget_installed = True
try:
    # We have installed UserAndGroupSelectionWidget with version greated
    # then 2.0.4
    from Products.UserAndGroupSelectionWidget.z3cform.widget import \
        UsersAndGroupsSelectionWidgetFactory
except ImportError:
    # UserAndGroupSelectionWidget > 2.0.4 not found
    UserAndGroupSelectionWidget_installed = False

UTILITY_NOT_FOUND_MESSAGE = _(
    u"The XMPP Twisted utility could not be "
    u"found. Either your XMPP settings are incorrect, or the Zope "
    u"server was just restarted and the utility not yet "
    u"registered again (it's registered upon page load). If "
    u"it's the second case, please try again. Otherwise, check "
    u"your XMPP settings.")


class XMPPSettingsEditForm(controlpanel.RegistryEditForm):
    """ XMPP settings form.
    """
    schema = IXMPPSettings
    id = "XMPPSettingsEditForm"
    label = _(u"XMPP settings")

    @button.buttonAndHandler(_('Save'), name=None)
    def handleSave(self, action):
        data, errors = self.extractData()