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