Add support for XEP-0235: OAuth over XMPP
This commit is contained in:
parent
357406d801
commit
a88b9737ff
1
setup.py
1
setup.py
@ -97,6 +97,7 @@ packages = [ 'sleekxmpp',
|
|||||||
'sleekxmpp/plugins/xep_0221',
|
'sleekxmpp/plugins/xep_0221',
|
||||||
'sleekxmpp/plugins/xep_0224',
|
'sleekxmpp/plugins/xep_0224',
|
||||||
'sleekxmpp/plugins/xep_0231',
|
'sleekxmpp/plugins/xep_0231',
|
||||||
|
'sleekxmpp/plugins/xep_0235',
|
||||||
'sleekxmpp/plugins/xep_0249',
|
'sleekxmpp/plugins/xep_0249',
|
||||||
'sleekxmpp/plugins/xep_0258',
|
'sleekxmpp/plugins/xep_0258',
|
||||||
'sleekxmpp/features',
|
'sleekxmpp/features',
|
||||||
|
@ -60,6 +60,7 @@ __all__ = [
|
|||||||
'xep_0223', # Persistent Storage of Private Data via Pubsub
|
'xep_0223', # Persistent Storage of Private Data via Pubsub
|
||||||
'xep_0224', # Attention
|
'xep_0224', # Attention
|
||||||
'xep_0231', # Bits of Binary
|
'xep_0231', # Bits of Binary
|
||||||
|
'xep_0235', # OAuth Over XMPP
|
||||||
'xep_0242', # XMPP Client Compliance 2009
|
'xep_0242', # XMPP Client Compliance 2009
|
||||||
'xep_0249', # Direct MUC Invitations
|
'xep_0249', # Direct MUC Invitations
|
||||||
'xep_0256', # Last Activity in Presence
|
'xep_0256', # Last Activity in Presence
|
||||||
|
16
sleekxmpp/plugins/xep_0235/__init__.py
Normal file
16
sleekxmpp/plugins/xep_0235/__init__.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
SleekXMPP: The Sleek XMPP Library
|
||||||
|
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
|
||||||
|
This file is part of SleekXMPP.
|
||||||
|
|
||||||
|
See the file LICENSE for copying permission.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sleekxmpp.plugins.base import register_plugin
|
||||||
|
|
||||||
|
from sleekxmpp.plugins.xep_0235 import stanza
|
||||||
|
from sleekxmpp.plugins.xep_0235.stanza import OAuth
|
||||||
|
from sleekxmpp.plugins.xep_0235.oauth import XEP_0235
|
||||||
|
|
||||||
|
|
||||||
|
register_plugin(XEP_0235)
|
32
sleekxmpp/plugins/xep_0235/oauth.py
Normal file
32
sleekxmpp/plugins/xep_0235/oauth.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"""
|
||||||
|
SleekXMPP: The Sleek XMPP Library
|
||||||
|
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
|
||||||
|
This file is part of SleekXMPP.
|
||||||
|
|
||||||
|
See the file LICENSE for copying permission.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from sleekxmpp import Message
|
||||||
|
from sleekxmpp.plugins import BasePlugin
|
||||||
|
from sleekxmpp.xmlstream import register_stanza_plugin
|
||||||
|
from sleekxmpp.plugins.xep_0235 import stanza, OAuth
|
||||||
|
|
||||||
|
|
||||||
|
class XEP_0235(BasePlugin):
|
||||||
|
|
||||||
|
name = 'xep_0235'
|
||||||
|
description = 'XEP-0235: OAuth Over XMPP'
|
||||||
|
dependencies = set(['xep_0030'])
|
||||||
|
stanza = stanza
|
||||||
|
|
||||||
|
def plugin_init(self):
|
||||||
|
register_stanza_plugin(Message, OAuth)
|
||||||
|
|
||||||
|
def session_bind(self, jid):
|
||||||
|
self.xmpp['xep_0030'].add_feature('urn:xmpp:oauth:0')
|
||||||
|
|
||||||
|
def plugin_end(self):
|
||||||
|
self.xmpp['xep_0030'].del_feature(feature='urn:xmpp:oauth:0')
|
80
sleekxmpp/plugins/xep_0235/stanza.py
Normal file
80
sleekxmpp/plugins/xep_0235/stanza.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
"""
|
||||||
|
SleekXMPP: The Sleek XMPP Library
|
||||||
|
Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
|
||||||
|
This file is part of SleekXMPP.
|
||||||
|
|
||||||
|
See the file LICENSE for copying permission.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
import urllib
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from sleekxmpp.xmlstream import ET, ElementBase, JID
|
||||||
|
|
||||||
|
|
||||||
|
class OAuth(ElementBase):
|
||||||
|
|
||||||
|
name = 'oauth'
|
||||||
|
namespace = 'urn:xmpp:oauth:0'
|
||||||
|
plugin_attrib = 'oauth'
|
||||||
|
interfaces = set(['oauth_consumer_key', 'oauth_nonce', 'oauth_signature',
|
||||||
|
'oauth_signature_method', 'oauth_timestamp',
|
||||||
|
'oauth_token', 'oauth_version'])
|
||||||
|
sub_interfaces = interfaces
|
||||||
|
|
||||||
|
def generate_signature(self, stanza, sfrom, sto, consumer_secret,
|
||||||
|
token_secret, method='HMAC-SHA1'):
|
||||||
|
self['oauth_signature_method'] = method
|
||||||
|
|
||||||
|
request = urllib.quote('%s&%s' % (sfrom, sto), '')
|
||||||
|
parameters = urllib.quote('&'.join([
|
||||||
|
'oauth_consumer_key=%s' % self['oauth_consumer_key'],
|
||||||
|
'oauth_nonce=%s' % self['oauth_nonce'],
|
||||||
|
'oauth_signature_method=%s' % self['oauth_signature_method'],
|
||||||
|
'oauth_timestamp=%s' % self['oauth_timestamp'],
|
||||||
|
'oauth_token=%s' % self['oauth_token'],
|
||||||
|
'oauth_version=%s' % self['oauth_version']
|
||||||
|
]), '')
|
||||||
|
|
||||||
|
sigbase = '%s&%s&%s' % (stanza, request, parameters)
|
||||||
|
|
||||||
|
consumer_secret = urllib.quote(consumer_secret, '')
|
||||||
|
token_secret = urllib.quote(token_secret, '')
|
||||||
|
key = '%s&%s' % (consumer_secret, token_secret)
|
||||||
|
|
||||||
|
if method == 'HMAC-SHA1':
|
||||||
|
sig = base64.b64encode(hmac.new(key, sigbase, hashlib.sha1).digest())
|
||||||
|
elif method == 'PLAINTEXT':
|
||||||
|
sig = key
|
||||||
|
|
||||||
|
self['oauth_signature'] = sig
|
||||||
|
return sig
|
||||||
|
|
||||||
|
def verify_signature(self, stanza, sfrom, sto, consumer_secret,
|
||||||
|
token_secret):
|
||||||
|
method = self['oauth_signature_method']
|
||||||
|
|
||||||
|
request = urllib.quote('%s&%s' % (sfrom, sto), '')
|
||||||
|
parameters = urllib.quote('&'.join([
|
||||||
|
'oauth_consumer_key=%s' % self['oauth_consumer_key'],
|
||||||
|
'oauth_nonce=%s' % self['oauth_nonce'],
|
||||||
|
'oauth_signature_method=%s' % self['oauth_signature_method'],
|
||||||
|
'oauth_timestamp=%s' % self['oauth_timestamp'],
|
||||||
|
'oauth_token=%s' % self['oauth_token'],
|
||||||
|
'oauth_version=%s' % self['oauth_version']
|
||||||
|
]), '')
|
||||||
|
|
||||||
|
sigbase = '%s&%s&%s' % (stanza, request, parameters)
|
||||||
|
|
||||||
|
consumer_secret = urllib.quote(consumer_secret, '')
|
||||||
|
token_secret = urllib.quote(token_secret, '')
|
||||||
|
key = '%s&%s' % (consumer_secret, token_secret)
|
||||||
|
|
||||||
|
if method == 'HMAC-SHA1':
|
||||||
|
sig = base64.b64encode(hmac.new(key, sigbase, hashlib.sha1).digest())
|
||||||
|
elif method == 'PLAINTEXT':
|
||||||
|
sig = key
|
||||||
|
|
||||||
|
return self['oauth_signature'] == sig
|
Loading…
Reference in New Issue
Block a user