Improve XEP-0070 and examples
This commit is contained in:
parent
9019e2bc71
commit
39ee833c29
3 changed files with 64 additions and 54 deletions
|
@ -29,18 +29,33 @@ class AnswerConfirm(slixmpp.ClientXMPP):
|
||||||
def __init__(self, jid, password, trusted):
|
def __init__(self, jid, password, trusted):
|
||||||
slixmpp.ClientXMPP.__init__(self, jid, password)
|
slixmpp.ClientXMPP.__init__(self, jid, password)
|
||||||
|
|
||||||
self.trusted = trusted
|
self.add_event_handler("http_confirm", self.confirm)
|
||||||
self.api.register(self.confirm, 'xep_0070', 'get_confirm')
|
self.add_event_handler("session_start", self.start)
|
||||||
|
|
||||||
def confirm(self, jid, id, url, method):
|
def start(self, *args):
|
||||||
log.info('Received confirm request %s from %s to access %s using '
|
self.make_presence().send()
|
||||||
'method %s' % (id, jid, url, method))
|
|
||||||
if jid not in self.trusted:
|
|
||||||
log.info('Denied')
|
|
||||||
return False
|
|
||||||
log.info('Confirmed')
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
def prompt(self, stanza):
|
||||||
|
confirm = stanza['confirm']
|
||||||
|
print('Received confirm request %s from %s to access %s using '
|
||||||
|
'method %s' % (
|
||||||
|
confirm['id'], stanza['from'], confirm['url'],
|
||||||
|
confirm['method'])
|
||||||
|
)
|
||||||
|
result = input("Do you accept (y/N)? ")
|
||||||
|
return 'y' == result.lower()
|
||||||
|
|
||||||
|
def confirm(self, stanza):
|
||||||
|
if self.prompt(stanza):
|
||||||
|
reply = stanza.reply()
|
||||||
|
else:
|
||||||
|
reply = stanza.reply()
|
||||||
|
reply.enable('error')
|
||||||
|
reply['error']['type'] = 'auth'
|
||||||
|
reply['error']['code'] = '401'
|
||||||
|
reply['error']['condition'] = 'not-authorized'
|
||||||
|
reply.append(stanza['confirm'])
|
||||||
|
reply.send()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Setup the command line arguments.
|
# Setup the command line arguments.
|
||||||
|
|
|
@ -16,7 +16,7 @@ from getpass import getpass
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
import slixmpp
|
import slixmpp
|
||||||
from slixmpp.exceptions import XMPPError
|
from slixmpp.exceptions import XMPPError, IqError
|
||||||
from slixmpp import asyncio
|
from slixmpp import asyncio
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -37,24 +37,40 @@ class AskConfirm(slixmpp.ClientXMPP):
|
||||||
self.method = method
|
self.method = method
|
||||||
|
|
||||||
# Will be used to set the proper exit code.
|
# Will be used to set the proper exit code.
|
||||||
self.confirmed = None
|
self.confirmed = asyncio.Future()
|
||||||
|
|
||||||
self.add_event_handler("session_start", self.start)
|
self.add_event_handler("session_start", self.start)
|
||||||
|
self.add_event_handler("message", self.start)
|
||||||
|
self.add_event_handler("http_confirm_message", self.confirm)
|
||||||
|
|
||||||
|
def confirm(self, message):
|
||||||
|
print(message)
|
||||||
|
if message['confirm']['id'] == self.id:
|
||||||
|
if message['type'] == 'error':
|
||||||
|
self.confirmed.set_result(False)
|
||||||
|
else:
|
||||||
|
self.confirmed.set_result(True)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def start(self, event):
|
def start(self, event):
|
||||||
log.info('Sending confirm request %s to %s who wants to access %s using '
|
log.info('Sending confirm request %s to %s who wants to access %s using '
|
||||||
'method %s...' % (self.id, self.recipient, self.url, self.method))
|
'method %s...' % (self.id, self.recipient, self.url, self.method))
|
||||||
confirmed = yield from self['xep_0070'].ask_confirm(self.recipient,
|
try:
|
||||||
id=self.id,
|
confirmed = yield from self['xep_0070'].ask_confirm(self.recipient,
|
||||||
url=self.url,
|
id=self.id,
|
||||||
method=self.method,
|
url=self.url,
|
||||||
message='Plz say yes or no for {method} {url} ({id}).')
|
method=self.method,
|
||||||
|
message='Plz say yes or no for {method} {url} ({id}).')
|
||||||
|
if isinstance(confirmed, slixmpp.Message):
|
||||||
|
confirmed = yield from self.confirmed
|
||||||
|
else:
|
||||||
|
confirmed = True
|
||||||
|
except IqError:
|
||||||
|
confirmed = False
|
||||||
if confirmed:
|
if confirmed:
|
||||||
print('Confirmed')
|
print('Confirmed')
|
||||||
else:
|
else:
|
||||||
print('Denied')
|
print('Denied')
|
||||||
self.confirmed = confirmed
|
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
from slixmpp.plugins import BasePlugin, register_plugin
|
from slixmpp.plugins import BasePlugin, register_plugin
|
||||||
from slixmpp import future_wrapper, Iq, Message
|
from slixmpp import future_wrapper, Iq, Message
|
||||||
from slixmpp.exceptions import XMPPError, IqError, IqTimeout
|
from slixmpp.exceptions import XMPPError, IqError, IqTimeout
|
||||||
|
from slixmpp.jid import JID
|
||||||
from slixmpp.xmlstream import JID, register_stanza_plugin
|
from slixmpp.xmlstream import JID, register_stanza_plugin
|
||||||
from slixmpp.xmlstream.handler import Callback
|
from slixmpp.xmlstream.handler import Callback
|
||||||
from slixmpp.xmlstream.matcher import StanzaPath
|
from slixmpp.xmlstream.matcher import StanzaPath
|
||||||
|
@ -46,10 +48,6 @@ class XEP_0070(BasePlugin):
|
||||||
StanzaPath('message/confirm'),
|
StanzaPath('message/confirm'),
|
||||||
self._handle_message_confirm))
|
self._handle_message_confirm))
|
||||||
|
|
||||||
#self.api.register(self._default_get_confirm,
|
|
||||||
# 'get_confirm',
|
|
||||||
# default=True)
|
|
||||||
|
|
||||||
def plugin_end(self):
|
def plugin_end(self):
|
||||||
self.xmpp.remove_handler('Confirm')
|
self.xmpp.remove_handler('Confirm')
|
||||||
self.xmpp['xep_0030'].del_feature(feature='http://jabber.org/protocol/http-auth')
|
self.xmpp['xep_0030'].del_feature(feature='http://jabber.org/protocol/http-auth')
|
||||||
|
@ -57,51 +55,32 @@ class XEP_0070(BasePlugin):
|
||||||
def session_bind(self, jid):
|
def session_bind(self, jid):
|
||||||
self.xmpp['xep_0030'].add_feature('http://jabber.org/protocol/http-auth')
|
self.xmpp['xep_0030'].add_feature('http://jabber.org/protocol/http-auth')
|
||||||
|
|
||||||
|
@future_wrapper
|
||||||
def ask_confirm(self, jid, id, url, method, *, ifrom=None, message=None):
|
def ask_confirm(self, jid, id, url, method, *, ifrom=None, message=None):
|
||||||
if message is None:
|
jid = JID(jid)
|
||||||
|
if jid.resource:
|
||||||
stanza = self.xmpp.Iq()
|
stanza = self.xmpp.Iq()
|
||||||
stanza['type'] = 'get'
|
stanza['type'] = 'get'
|
||||||
else:
|
else:
|
||||||
stanza = self.xmpp.Message()
|
stanza = self.xmpp.Message()
|
||||||
|
stanza['thread'] = uuid4().hex
|
||||||
stanza['from'] = ifrom
|
stanza['from'] = ifrom
|
||||||
stanza['to'] = jid
|
stanza['to'] = jid
|
||||||
stanza['confirm']['id'] = id
|
stanza['confirm']['id'] = id
|
||||||
stanza['confirm']['url'] = url
|
stanza['confirm']['url'] = url
|
||||||
stanza['confirm']['method'] = method
|
stanza['confirm']['method'] = method
|
||||||
if message is not None:
|
if not jid.resource:
|
||||||
stanza['body'] = message.format(id=id, url=url, method=method)
|
if message is not None:
|
||||||
|
stanza['body'] = message.format(id=id, url=url, method=method)
|
||||||
stanza.send()
|
stanza.send()
|
||||||
|
return stanza
|
||||||
else:
|
else:
|
||||||
try:
|
return stanza.send()
|
||||||
yield from stanza.send()
|
|
||||||
except IqError:
|
|
||||||
return False
|
|
||||||
except IqTimeout:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _handle_iq_confirm(self, iq):
|
def _handle_iq_confirm(self, iq):
|
||||||
emitter = iq['from']
|
self.xmpp.event('http_confirm_iq', iq)
|
||||||
id = iq['confirm']['id']
|
self.xmpp.event('http_confirm', iq)
|
||||||
url = iq['confirm']['url']
|
|
||||||
method = iq['confirm']['method']
|
|
||||||
accept = self.api['get_confirm'](emitter, id, url, method)
|
|
||||||
if not accept:
|
|
||||||
raise XMPPError(etype='auth', condition='not-authorized')
|
|
||||||
|
|
||||||
iq.reply().send()
|
|
||||||
|
|
||||||
def _handle_message_confirm(self, message):
|
def _handle_message_confirm(self, message):
|
||||||
emitter = message['from']
|
self.xmpp.event('http_confirm_message', message)
|
||||||
id = message['confirm']['id']
|
self.xmpp.event('http_confirm', message)
|
||||||
url = message['confirm']['url']
|
|
||||||
method = message['confirm']['method']
|
|
||||||
accept = self.api['get_confirm'](emitter, id, url, method)
|
|
||||||
if not accept:
|
|
||||||
raise XMPPError(etype='auth', condition='not-authorized')
|
|
||||||
|
|
||||||
message.reply().send()
|
|
||||||
|
|
||||||
#def _default_get_confirm(self, jid, id, url, method):
|
|
||||||
# return False
|
|
||||||
|
|
Loading…
Reference in a new issue