aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2011-04-27 01:04:03 -0400
committerGuillaume Horel <guillaume.horel@gmail.com>2011-04-27 01:04:03 -0400
commitb38e784e1aeb0b3f3db4a8a33799c4bd94a5d10a (patch)
tree6df5fa411b7db980869d259de4319f762baa705d /server
parentd045912cb5b4e49140514b7dbf2ca4bc5ca5098f (diff)
downloadalias-b38e784e1aeb0b3f3db4a8a33799c4bd94a5d10a.tar.gz
Preliminary work for in-band registration.
Diffstat (limited to 'server')
-rw-r--r--server/alias_plugin.py (renamed from server/plugin.py)0
-rw-r--r--server/object.py5
-rw-r--r--server/server.py4
-rw-r--r--server/user.py29
-rw-r--r--server/xep_0077.py158
5 files changed, 185 insertions, 11 deletions
diff --git a/server/plugin.py b/server/alias_plugin.py
index 2001b1b..2001b1b 100644
--- a/server/plugin.py
+++ b/server/alias_plugin.py
diff --git a/server/object.py b/server/object.py
index 6a5e45c..7a2e46f 100644
--- a/server/object.py
+++ b/server/object.py
@@ -8,6 +8,7 @@ import zlib
import datetime
import fileinput
import logging
+import pickle
logger = logging.getLogger(__name__)
from permission import *
@@ -93,11 +94,11 @@ class ObjectReader(Object):
file.close()
return content, key
- def get_private_key(self):
+ def get_registration_data(self):
pass
class ObjectWriter(Object):
- def __init__(self, owner, hash = None):
+ def __init__(self, owner, hash = None, content):
Object.__init__(self, owner, hash)
if not os.path.exists(self.owner_path):
logger.error("User {} is not registered".format(self.owner))
diff --git a/server/server.py b/server/server.py
index 0404ca6..3bd953e 100644
--- a/server/server.py
+++ b/server/server.py
@@ -10,7 +10,9 @@ class ObjectComponent(ComponentXMPP):
def __init__(self, jid, secret, server, port, root):
ComponentXMPP.__init__(self, jid, secret, server, port)
self.register_plugin('xep_0030')
- self.register_plugin("AliasPlugin", module = "plugin", pconfig = {'root': root})
+ self.register_plugin('xep_0077', pconfig = {'root': root})
+ self.plugin['xep_0077'].setForm('pubkey','privkey','salt')
+ self.register_plugin("AliasPlugin", module = "alias_plugin", pconfig = {'root': root})
self.add_event_handler("session_start", self.start)
self.add_event_handler("presence_probe", self.presence_probe)
self.add_event_handler("message", self.message)
diff --git a/server/user.py b/server/user.py
index 2491164..3fbf55c 100644
--- a/server/user.py
+++ b/server/user.py
@@ -11,22 +11,35 @@ class UserHandler:
def __init__(self, root):
self.root = root
- def register(self, name):
- userDir = self.root + '/' + name
+ def register(self, jid, registration):
+ userDir = self.root + '/' + jid
if os.path.exists(userDir):
- logger.error("User {} path already exists".format(name))
+ logger.error("User {} path already exists".format(jid))
os.mkdir(userDir)
- ObjectWriter(name)
+ ObjectWriter(jid)
+ return True
- def registered(self, name):
- return os.path.exists(self.root + '/' + name)
+ def registered(self, jid):
+ return os.path.exists(self.root + '/' + jid)
- def unregister(self, name):
- shutil.rmtree(self.root + '/' + name)
+ def unregister(self, jid):
+ shutil.rmtree(self.root + '/' + jid)
def get_user_list(self):
return os.listdir(self.root)
+def register(self, jid, registration):
+ username = registration['username']
+
+ def filter_usernames(user):
+ return user != jid and self.users[user]['username'] == username
+
+ conflicts = filter(filter_usernames, self.users.keys())
+ if conflicts:
+ return False
+
+ self.users[jid] = registration
+ return True
class User:
def __init__(self, name):
diff --git a/server/xep_0077.py b/server/xep_0077.py
new file mode 100644
index 0000000..b07105b
--- /dev/null
+++ b/server/xep_0077.py
@@ -0,0 +1,158 @@
+"""
+Creating a SleekXMPP Plugin
+
+This is a minimal implementation of XEP-0077 to serve
+as a tutorial for creating SleekXMPP plugins.
+"""
+
+from sleekxmpp.plugins.base import base_plugin
+from sleekxmpp.xmlstream.handler.callback import Callback
+from sleekxmpp.xmlstream.matcher.xpath import MatchXPath
+from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
+from sleekxmpp import Iq
+from user import UserHandler
+from config import config
+
+class Registration(ElementBase):
+ namespace = 'jabber:iq:register'
+ name = 'query'
+ plugin_attrib = 'register'
+ interfaces = set(('pubkey', 'privkey', 'salt'
+ 'registered', 'remove', 'instructions'))
+ sub_interfaces = interfaces
+
+ def getRegistered(self):
+ present = self.xml.find('{%s}registered' % self.namespace)
+ return present is not None
+
+ def getRemove(self):
+ present = self.xml.find('{%s}remove' % self.namespace)
+ return present is not None
+
+ def setRegistered(self, registered):
+ if registered:
+ self.addField('registered')
+ else:
+ del self['registered']
+
+ def setRemove(self, remove):
+ if remove:
+ self.addField('remove')
+ else:
+ del self['remove']
+
+ def addField(self, name):
+ itemXML = ET.Element('{%s}%s' % (self.namespace, name))
+ self.xml.append(itemXML)
+
+
+class UserStore(object):
+ def __init__(self):
+ self.users = {}
+
+ def __getitem__(self, jid):
+ return self.users.get(jid, None)
+
+ def register(self, jid, registration):
+ username = registration['username']
+
+ def filter_usernames(user):
+ return user != jid and self.users[user]['username'] == username
+
+ conflicts = filter(filter_usernames, self.users.keys())
+ if conflicts:
+ return False
+
+ self.users[jid] = registration
+ return True
+
+ def unregister(self, jid):
+ del self.users[jid]
+
+class xep_0077(base_plugin):
+ """
+ XEP-0077 In-Band Registration
+ """
+
+ def plugin_init(self):
+ self.description = "In-Band Registration"
+ self.xep = "0077"
+ self.form_fields = ()
+ self.form_instructions = ""
+ self.backend = UserHandler(config.root)
+
+ self.xmpp.registerHandler(
+ Callback('In-Band Registration',
+ MatchXPath('{%s}iq/{jabber:iq:register}query' % self.xmpp.default_ns),
+ self.__handleRegistration))
+ register_stanza_plugin(Iq, Registration)
+
+ def post_init(self):
+ base_plugin.post_init(self)
+ self.xmpp['xep_0030'].add_feature("jabber:iq:register")
+
+ def __handleRegistration(self, iq):
+ if iq['type'] == 'get':
+ # Registration form requested
+ self.sendRegistrationForm(iq, self.backend)
+ elif iq['type'] == 'set':
+ if iq['register']['remove']:
+ # Remove an account
+ self.backend.unregister(iq['from'].bare)
+ #self.xmpp.event('unregistered_user', iq)
+ iq.reply().send()
+ return
+
+ for field in self.form_fields:
+ if not iq['register'][field]:
+ # Incomplete Registration
+ self._sendError(iq, '406', 'modify', 'not-acceptable',
+ "Please fill in all fields.")
+ return
+
+ if self.backend.register(iq['from'].bare, iq['register']):
+ # Successful registration
+ #self.xmpp.event('registered_user', iq)
+ iq.reply().setPayload(iq['register'].xml)
+ iq.send()
+ else:
+ # Conflicting registration
+ self._sendError(iq, '409', 'cancel', 'conflict',
+ "That username is already taken.")
+
+ def setForm(self, *fields):
+ self.form_fields = fields
+
+ def setInstructions(self, instructions):
+ self.form_instructions = instructions
+
+ def sendRegistrationForm(self, iq, userHandler):
+ reg = iq['register']
+ if user
+ userData = {}
+ else:
+ reg['registered'] = True
+
+ if self.form_instructions:
+ reg['instructions'] = self.form_instructions
+
+ for field in self.form_fields:
+ data = userData.get(field, '')
+ if data:
+ # Add field with existing data
+ reg[field] = data
+ else:
+ # Add a blank field
+ reg.addField(field)
+
+ iq.reply().setPayload(reg.xml)
+ iq.send()
+
+ def _sendError(self, iq, code, error_type, name, text=''):
+ iq.reply().setPayload(iq['register'].xml)
+ iq.error()
+ iq['error']['code'] = code
+ iq['error']['type'] = error_type
+ iq['error']['condition'] = name
+ iq['error']['text'] = text
+ iq.send() \ No newline at end of file