Update Openfire broadcast tool (#742)

Allow users to ignore invalid certificates.
Added some limited user feedback.
Removed threading.
Prevent infinite connection attempt loops.
This commit is contained in:
Basraah 2017-02-28 11:30:26 +10:00 committed by GitHub
parent c6118beddf
commit 2e274d3baf
4 changed files with 48 additions and 40 deletions

View File

@ -68,6 +68,7 @@ If using Openfire, the following need to be set in accordance with the [install
- [BROADCAST_USER](#broadcast-user) - [BROADCAST_USER](#broadcast-user)
- [BROADCAST_USER_PASSWORD](#broadcast-user-password) - [BROADCAST_USER_PASSWORD](#broadcast-user-password)
- [BROADCAST_SERVICE_NAME](#broadcast-service-name) - [BROADCAST_SERVICE_NAME](#broadcast-service-name)
- [BROADCAST_IGNORE_INVALID_CERT](#broadcast-ignore-invalid-cert)
### Mumble ### Mumble
If using Mumble, the following needs to be set to the address of the mumble server: If using Mumble, the following needs to be set to the address of the mumble server:

View File

@ -82,6 +82,8 @@ Navigate to the `Server` tab, `Server Manager` subtab, and select `System Proper
- Name: `plugin.broadcast.allowedUsers` - Name: `plugin.broadcast.allowedUsers`
- Value: `broadcast@example.com`, replacing the domain name with yours - Value: `broadcast@example.com`, replacing the domain name with yours
- Do not encrypt this property value - Do not encrypt this property value
If you have troubles getting broadcasts to work, you can try setting the optional (you will need to add it) `BROADCAST_IGNORE_INVALID_CERT` setting to `True`. This will allow invalid certificates to be used when connecting to the Openfire server to send a broadcast.
### Group Chat ### Group Chat
Channels are available which function like a chat room. Access can be controlled either by password or ACL (not unlike mumble). Channels are available which function like a chat room. Access can be controlled either by password or ACL (not unlike mumble).

View File

@ -11,7 +11,6 @@ except ImportError:
import sleekxmpp import sleekxmpp
from django.conf import settings from django.conf import settings
import threading
from ofrestapi.users import Users as ofUsers from ofrestapi.users import Users as ofUsers
from ofrestapi import exception from ofrestapi import exception
@ -24,12 +23,6 @@ class OpenfireManager:
def __init__(self): def __init__(self):
pass pass
@staticmethod
def send_broadcast_threaded(group_name, broadcast_message):
logger.debug("Starting broadcast to %s with message %s" % (group_name, broadcast_message))
broadcast_thread = XmppThread(1, "XMPP Broadcast Thread", 1, group_name, broadcast_message)
broadcast_thread.start()
@staticmethod @staticmethod
def __add_address_to_username(username): def __add_address_to_username(username):
address = urlparse(settings.OPENFIRE_ADDRESS).netloc.split(":")[0] address = urlparse(settings.OPENFIRE_ADDRESS).netloc.split(":")[0]
@ -169,11 +162,19 @@ class OpenfireManager:
xmpp = PingBot(settings.BROADCAST_USER, settings.BROADCAST_USER_PASSWORD, to_address, broadcast_message) xmpp = PingBot(settings.BROADCAST_USER, settings.BROADCAST_USER_PASSWORD, to_address, broadcast_message)
xmpp.register_plugin('xep_0030') # Service Discovery xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0199') # XMPP Ping xmpp.register_plugin('xep_0199') # XMPP Ping
if xmpp.connect(): if xmpp.connect(reattempt=False):
xmpp.process(block=True) xmpp.process(block=True)
logger.info("Sent jabber ping to group %s" % group_name) message = None
if xmpp.message_sent:
logger.debug("Sent jabber ping to group %s" % group_name)
return
else:
message = "Failed to send Openfire broadcast message."
logger.error(message)
raise PingBotException(message)
else: else:
raise ValueError("Unable to connect to jabber server.") logger.error("Unable to connect to jabber server")
raise PingBotException("Unable to connect to jabber server.")
class PingBot(sleekxmpp.ClientXMPP): class PingBot(sleekxmpp.ClientXMPP):
@ -184,17 +185,28 @@ class PingBot(sleekxmpp.ClientXMPP):
def __init__(self, jid, password, recipient, message): def __init__(self, jid, password, recipient, message):
sleekxmpp.ClientXMPP.__init__(self, jid, password) sleekxmpp.ClientXMPP.__init__(self, jid, password)
self.reconnect_max_attempts = 5
self.auto_reconnect = False
# The message we wish to send, and the JID that # The message we wish to send, and the JID that
# will receive it. # will receive it.
self.recipient = recipient self.recipient = recipient
self.msg = message self.msg = message
# Success checking
self.message_sent = False
# The session_start event will be triggered when # The session_start event will be triggered when
# the bot establishes its connection with the server # the bot establishes its connection with the server
# and the XML streams are ready for use. We want to # and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize # listen for this event so that we we can initialize
# our roster. # our roster.
self.add_event_handler("session_start", self.start) self.add_event_handler("session_start", self.start)
if getattr(settings, 'BROADCAST_IGNORE_INVALID_CERT', False):
self.add_event_handler("ssl_invalid_cert", self.discard)
def discard(self, *args, **kwargs):
# Discard the event
return
def start(self, event): def start(self, event):
self.send_presence() self.send_presence()
@ -203,20 +215,11 @@ class PingBot(sleekxmpp.ClientXMPP):
self.send_message(mto=self.recipient, self.send_message(mto=self.recipient,
mbody=self.msg, mbody=self.msg,
mtype='chat') mtype='chat')
self.message_sent = True
# Using wait=True ensures that the send queue will be # Using wait=True ensures that the send queue will be
# emptied before ending the session. # emptied before ending the session.
self.disconnect(wait=True) self.disconnect(wait=True)
class XmppThread(threading.Thread): class PingBotException(Exception):
def __init__(self, thread_id, name, counter, group, message, ): pass
threading.Thread.__init__(self)
self.threadID = thread_id
self.name = name
self.counter = counter
self.group = group
self.message = message
def run(self):
OpenfireManager.send_broadcast_message(self.group, self.message)

View File

@ -10,7 +10,7 @@ from eveonline.managers import EveManager
from eveonline.models import EveCharacter from eveonline.models import EveCharacter
from services.forms import ServicePasswordForm from services.forms import ServicePasswordForm
from .manager import OpenfireManager from .manager import OpenfireManager, PingBotException
from .tasks import OpenfireTasks from .tasks import OpenfireTasks
from .forms import JabberBroadcastForm from .forms import JabberBroadcastForm
from .models import OpenfireUser from .models import OpenfireUser
@ -103,27 +103,29 @@ def jabber_broadcast_view(request):
if form.is_valid(): if form.is_valid():
main_char = EveManager.get_main_character(request.user) main_char = EveManager.get_main_character(request.user)
logger.debug("Processing jabber broadcast for user %s with main character %s" % (request.user, main_char)) logger.debug("Processing jabber broadcast for user %s with main character %s" % (request.user, main_char))
if main_char is not None: try:
message_to_send = form.cleaned_data[ if main_char is not None:
'message'] + "\n##### SENT BY: " + "[" + main_char.corporation_ticker + "]" + \ message_to_send = form.cleaned_data[
main_char.character_name + " TO: " + \ 'message'] + "\n##### SENT BY: " + "[" + main_char.corporation_ticker + "]" + \
form.cleaned_data['group'] + " WHEN: " + datetime.datetime.utcnow().strftime( main_char.character_name + " TO: " + \
"%Y-%m-%d %H:%M:%S") + " #####\n##### Replies are NOT monitored #####\n" form.cleaned_data['group'] + " WHEN: " + datetime.datetime.utcnow().strftime(
group_to_send = form.cleaned_data['group'] "%Y-%m-%d %H:%M:%S") + " #####\n##### Replies are NOT monitored #####\n"
group_to_send = form.cleaned_data['group']
OpenfireManager.send_broadcast_threaded(group_to_send, message_to_send, ) else:
message_to_send = form.cleaned_data[
'message'] + "\n##### SENT BY: " + "No character but can send pings?" + " TO: " + \
form.cleaned_data['group'] + " WHEN: " + datetime.datetime.utcnow().strftime(
"%Y-%m-%d %H:%M:%S") + " #####\n##### Replies are NOT monitored #####\n"
group_to_send = form.cleaned_data['group']
else: OpenfireManager.send_broadcast_message(group_to_send, message_to_send)
message_to_send = form.cleaned_data[
'message'] + "\n##### SENT BY: " + "No character but can send pings?" + " TO: " + \
form.cleaned_data['group'] + " WHEN: " + datetime.datetime.utcnow().strftime(
"%Y-%m-%d %H:%M:%S") + " #####\n##### Replies are NOT monitored #####\n"
group_to_send = form.cleaned_data['group']
OpenfireManager.send_broadcast_threaded(group_to_send, message_to_send, ) messages.success(request, 'Sent jabber broadcast to %s' % group_to_send)
logger.info("Sent jabber broadcast on behalf of user %s" % request.user)
except PingBotException as e:
messages.error(request, e)
messages.success(request, 'Sent jabber broadcast to %s' % group_to_send)
logger.info("Sent jabber broadcast on behalf of user %s" % request.user)
else: else:
form = JabberBroadcastForm() form = JabberBroadcastForm()
form.fields['group'].choices = allchoices form.fields['group'].choices = allchoices