Guest User

Untitled

a guest
May 26th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.01 KB | None | 0 0
  1. """
  2. Creating a SleekXMPP Plugin
  3.  
  4. This is a minimal implementation of XEP-0077 to serve
  5. as a tutorial for creating SleekXMPP plugins.
  6. """
  7.  
  8. from . import base
  9. from .. xmlstream.handler.callback import Callback
  10. from .. xmlstream.matcher.xpath import MatchXPath
  11. from .. xmlstream.stanzabase import ElementBase, ET, JID
  12. from .. stanza.iq import Iq
  13. import copy
  14.  
  15.  
  16. class Registration(ElementBase):
  17. namespace = 'jabber:iq:register'
  18. name = 'query'
  19. plugin_attrib = 'register'
  20. interfaces = set(('username', 'password', 'email', 'nick', 'name',
  21. 'first', 'last', 'address', 'city', 'state', 'zip',
  22. 'phone', 'url', 'date', 'misc', 'text', 'key',
  23. 'registered', 'remove', 'instructions'))
  24. sub_interfaces = interfaces
  25.  
  26. def getRegistered(self):
  27. present = self.xml.find('{%s}registered' % self.namespace)
  28. return True if present is not None else False
  29.  
  30. def getRemove(self):
  31. present = self.xml.find('{%s}remove' % self.namespace)
  32. return True if present is not None else False
  33.  
  34. def setRegistered(self, registered):
  35. if registered:
  36. self.addField('registered')
  37. else:
  38. del self['registered']
  39.  
  40. def setRemove(self, remove):
  41. if remove:
  42. self.addField('remove')
  43. else:
  44. del self['remove']
  45.  
  46. def addField(self, name):
  47. itemXML = ET.Element('{%s}%s' % (self.namespace, name))
  48. self.xml.append(itemXML)
  49.  
  50.  
  51. class UserStore(object):
  52. def __init__(self):
  53. self.users = {}
  54.  
  55. def __getitem__(self, jid):
  56. return self.users.get(jid, None)
  57.  
  58. def register(self, jid, registration):
  59. username = registration['username']
  60.  
  61. def filter_usernames(user):
  62. return user != jid and self.users[user]['username'] == username
  63.  
  64. conflicts = filter(filter_usernames, self.users.keys())
  65. if conflicts:
  66. return False
  67.  
  68. self.users[jid] = registration
  69. return True
  70.  
  71. def unregister(self, jid):
  72. del self.users[jid]
  73.  
  74. class xep_0077(base.base_plugin):
  75. """
  76. XEP-0077 In-Band Registration
  77. """
  78.  
  79. def plugin_init(self):
  80. self.description = "In-Band Registration"
  81. self.xep = "0077"
  82. self.form_fields = ('username', 'password')
  83. self.form_instructions = ""
  84. self.backend = UserStore()
  85.  
  86. self.xmpp.registerHandler(
  87. Callback('In-Band Registration',
  88. MatchXPath('{%s}iq/{jabber:iq:register}query' % self.xmpp.default_ns),
  89. self.__handleRegistration))
  90. self.xmpp.stanzaPlugin(Iq, Registration)
  91.  
  92. def post_init(self):
  93. base.base_plugin.post_init(self)
  94. self.xmpp.plugin['xep-0030'].add_feature("jabber:iq:register")
  95.  
  96. def __handleRegistration(self, iq):
  97. if iq['type'] == 'get':
  98. # Registration form requested
  99. userData = self.backend[iq['from'].bare]
  100. self.sendRegistrationForm(iq, userData)
  101. elif iq['type'] == 'set':
  102. if iq['register']['remove']:
  103. # Remove an account
  104. self.backend.unregister(iq['from'].bare)
  105. self.xmpp.event('unregistered_user', iq)
  106. iq.reply().send()
  107. return
  108.  
  109. for field in self.form_fields:
  110. if not iq['register'][field]:
  111. # Incomplete Registration
  112. self._sendError(iq, '406', 'modify', 'not-acceptable',
  113. "Please fill in all fields.")
  114. return
  115.  
  116. if self.backend.register(iq['from'].bare, iq['register']):
  117. # Successful registration
  118. self.xmpp.event('registered_user', iq)
  119. iq.reply().setPayload(iq['register'].xml)
  120. iq.send()
  121. else:
  122. # Conflicting registration
  123. self._sendError(iq, '409', 'cancel', 'conflict',
  124. "That username is already taken.")
  125.  
  126. def setForm(self, *fields):
  127. self.form_fields = fields
  128.  
  129. def setInstructions(self, instructions):
  130. self.form_instructions = instructions
  131.  
  132. def sendRegistrationForm(self, iq, userData=None):
  133. reg = iq['register']
  134. if userData is None:
  135. userData = {}
  136. else:
  137. reg['registered'] = True
  138.  
  139. if self.form_instructions:
  140. reg['instructions'] = self.form_instructions
  141.  
  142. for field in self.form_fields:
  143. data = userData.get(field, '')
  144. if data:
  145. # Add field with existing data
  146. reg[field] = data
  147. else:
  148. # Add a blank field
  149. reg.addField(field)
  150.  
  151. iq.reply().setPayload(reg.xml)
  152. iq.send()
  153.  
  154. def _sendError(self, iq, code, error_type, name, text=''):
  155. iq.reply().setPayload(iq['register'].xml)
  156. iq.error()
  157. iq['error']['code'] = code
  158. iq['error']['type'] = error_type
  159. iq['error']['condition'] = name
  160. iq['error']['text'] = text
  161. iq.send()
Add Comment
Please, Sign In to add comment