]> code.delx.au - pymsnt/blob - src/register.py
* PyMSNt now supports Twisted 2.5
[pymsnt] / src / register.py
1 # Copyright 2004-2006 James Bunton <james@delx.cjb.net>
2 # Licensed for distribution under the GPL version 2, check COPYING for details
3
4 import utils
5 from twisted.words.xish.domish import Element
6 from twisted.words.protocols.jabber.jid import internJID
7 from debug import LogEvent, INFO, WARN, ERROR
8 import disco
9 import session
10 import config
11 import lang
12 import jabw
13 import legacy
14
15
16 class RegisterManager:
17 def __init__(self, pytrans):
18 self.pytrans = pytrans
19 if config.allowRegister:
20 self.pytrans.discovery.addFeature(disco.IQREGISTER, self.incomingRegisterIq, config.jid)
21 LogEvent(INFO)
22
23 def removeRegInfo(self, jabberID):
24 LogEvent(INFO)
25 try:
26 # If the session is active then send offline presences
27 session = self.pytrans.sessions[jabberID]
28 session.removeMe()
29 except KeyError:
30 pass
31
32 self.pytrans.xdb.remove(jabberID)
33 LogEvent(INFO, "", "done")
34
35
36 def setRegInfo(self, jabberID, username, password):
37 LogEvent(INFO)
38 if(len(password) == 0):
39 (blah1, password, blah3) = self.getRegInfo(jabberID)
40
41 reginfo = legacy.formRegEntry(username, password)
42 self.pytrans.xdb.set(internJID(jabberID).userhost(), legacy.namespace, reginfo)
43
44 def getRegInfo(self, jabberID):
45 LogEvent(INFO)
46 result = self.pytrans.xdb.request(internJID(jabberID).userhost(), legacy.namespace)
47 if(result == None):
48 LogEvent(INFO, "", "Not registered!")
49 return None
50
51 username, password = legacy.getAttributes(result)
52
53 if(username and password and len(username) > 0 and len(password) > 0):
54 LogEvent(INFO, "", "Returning reg info.")
55 return (username, password)
56 else:
57 LogEvent(WARN, "", "Registration data corrupted!")
58 return None
59
60 def incomingRegisterIq(self, incoming):
61 # Check what type the Iq is..
62 itype = incoming.getAttribute("type")
63 LogEvent(INFO)
64 if(itype == "get"):
65 self.sendRegistrationFields(incoming)
66 elif(itype == "set"):
67 self.updateRegistration(incoming)
68
69 def sendRegistrationFields(self, incoming):
70 # Construct a reply with the fields they must fill out
71 ID = incoming.getAttribute("id")
72 fro = incoming.getAttribute("from")
73 LogEvent(INFO)
74 reply = Element((None, "iq"))
75 reply.attributes["from"] = config.jid
76 reply.attributes["to"] = fro
77 if ID:
78 reply.attributes["id"] = ID
79 reply.attributes["type"] = "result"
80 query = reply.addElement("query")
81 query.attributes["xmlns"] = "jabber:iq:register"
82 instructions = query.addElement("instructions")
83 ulang = utils.getLang(incoming)
84 instructions.addContent(lang.get(ulang).registerText)
85 userEl = query.addElement("username")
86 passEl = query.addElement("password")
87
88 # Check to see if they're registered
89 result = self.getRegInfo(incoming.getAttribute("from"))
90 if(result):
91 username, password = result
92 userEl.addContent(username)
93 query.addElement("registered")
94
95 self.pytrans.send(reply)
96
97 def updateRegistration(self, incoming):
98 # Grab the username, password
99 ID = incoming.getAttribute("id")
100 fro = incoming.getAttribute("from")
101 LogEvent(INFO)
102 source = internJID(fro).userhost()
103 ulang = utils.getLang(incoming)
104 username = None
105 password = None
106
107 for queryFind in incoming.elements():
108 if(queryFind.name == "query"):
109 for child in queryFind.elements():
110 try:
111 if(child.name == "username"):
112 username = child.__str__()
113 elif(child.name == "password"):
114 password = child.__str__()
115 elif(child.name == "remove"):
116 # The user wants to unregister the transport! Gasp!
117 LogEvent(INFO, "", "Unregistering.")
118 try:
119 self.removeRegInfo(source)
120 self.successReply(incoming)
121 except:
122 self.xdbErrorReply(incoming)
123 return
124 LogEvent(INFO, "", "Unregistered!")
125 return
126 except AttributeError, TypeError:
127 continue # Ignore any errors, we'll check everything below
128
129 if(username and password and len(username) > 0 and len(password) > 0):
130 # Valid registration data
131 LogEvent(INFO, "", "Updating XDB")
132 try:
133 self.setRegInfo(source, username, password)
134 LogEvent(INFO, "", "Updated XDB")
135 self.successReply(incoming)
136 LogEvent(INFO, "", "Sent a result Iq")
137 to = internJID(incoming.getAttribute("from")).userhost()
138 jabw.sendPresence(self.pytrans, to=to, fro=config.jid, ptype="subscribe")
139 if(config.registerMessage):
140 jabw.sendMessage(self.pytrans, to=incoming.getAttribute("from"), fro=config.jid, body=config.registerMessage)
141 except:
142 self.xdbErrorReply(incoming)
143 raise
144
145 else:
146 self.badRequestReply(incoming)
147
148 def badRequestReply(self, incoming):
149 LogEvent(INFO)
150 # Invalid registration data was sent to us. Or the removal failed
151 # Send an error Iq
152 reply = incoming
153 reply.swapAttributeValues("to", "from")
154 reply.attributes["type"] = "error"
155 error = reply.addElement("error")
156 error.attributes["type"] = "modify"
157 interror = error.addElement("bad-request")
158 interror["xmlns"] = disco.XMPP_STANZAS
159 self.pytrans.send(reply)
160
161 def xdbErrorReply(self, incoming):
162 LogEvent(INFO)
163 # Failure in updating XDB or sending result Iq
164 # send an error Iq
165 reply = incoming
166 reply.swapAttributeValues("to", "from")
167 reply.attributes["type"] = "error"
168 error = reply.addElement("error")
169 error.attributes["type"] = "wait"
170 interror = error.addElement("internal-server-error")
171 interror["xmlns"] = disco.XMPP_STANZAS
172 self.pytrans.send(reply)
173
174 def successReply(self, incoming):
175 reply = Element((None, "iq"))
176 reply.attributes["type"] = "result"
177 ID = incoming.getAttribute("id")
178 if(ID): reply.attributes["id"] = ID
179 reply.attributes["from"] = config.jid
180 reply.attributes["to"] = incoming.getAttribute("from")
181 self.pytrans.send(reply)
182