Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(368)

Side by Side Diff: third_party/twisted_8_1/twisted/words/protocols/jabber/component.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.words.test.test_jabbercomponent -*-
2 #
3 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
4 # See LICENSE for details.
5
6 """
7 External server-side components.
8
9 Most Jabber server implementations allow for add-on components that act as a
10 seperate entity on the Jabber network, but use the server-to-server
11 functionality of a regular Jabber IM server. These so-called 'external
12 components' are connected to the Jabber server using the Jabber Component
13 Protocol as defined in U{JEP-0114<http://www.jabber.org/jeps/jep-0114.html>}.
14
15 This module allows for writing external server-side component by assigning one
16 or more services implementing L{ijabber.IService} up to L{ServiceManager}. The
17 ServiceManager connects to the Jabber server and is responsible for the
18 corresponding XML stream.
19 """
20
21 from zope.interface import implements
22
23 from twisted.application import service
24 from twisted.internet import defer
25 from twisted.words.xish import domish
26 from twisted.words.protocols.jabber import ijabber, jstrports, xmlstream
27
28 def componentFactory(componentid, password):
29 """
30 XML stream factory for external server-side components.
31
32 @param componentid: JID of the component.
33 @type componentid: L{unicode}
34 @param password: password used to authenticate to the server.
35 @type password: L{str}
36 """
37 a = ConnectComponentAuthenticator(componentid, password)
38 return xmlstream.XmlStreamFactory(a)
39
40 class ComponentInitiatingInitializer(object):
41 """
42 External server-side component authentication initializer for the
43 initiating entity.
44
45 @ivar xmlstream: XML stream between server and component.
46 @type xmlstream: L{xmlstream.XmlStream}
47 """
48
49 def __init__(self, xs):
50 self.xmlstream = xs
51 self._deferred = None
52
53 def initialize(self):
54 xs = self.xmlstream
55 hs = domish.Element((self.xmlstream.namespace, "handshake"))
56 hs.addContent(xmlstream.hashPassword(xs.sid,
57 xs.authenticator.password))
58
59 # Setup observer to watch for handshake result
60 xs.addOnetimeObserver("/handshake", self._cbHandshake)
61 xs.send(hs)
62 self._deferred = defer.Deferred()
63 return self._deferred
64
65 def _cbHandshake(self, _):
66 # we have successfully shaken hands and can now consider this
67 # entity to represent the component JID.
68 self.xmlstream.thisEntity = self.xmlstream.otherEntity
69 self._deferred.callback(None)
70
71 class ConnectComponentAuthenticator(xmlstream.ConnectAuthenticator):
72 """
73 Authenticator to permit an XmlStream to authenticate against a Jabber
74 server as an external component (where the Authenticator is initiating the
75 stream).
76 """
77 namespace = 'jabber:component:accept'
78
79 def __init__(self, componentjid, password):
80 """
81 @type componentjid: L{str}
82 @param componentjid: Jabber ID that this component wishes to bind to.
83
84 @type password: L{str}
85 @param password: Password/secret this component uses to authenticate.
86 """
87 # Note that we are sending 'to' our desired component JID.
88 xmlstream.ConnectAuthenticator.__init__(self, componentjid)
89 self.password = password
90
91 def associateWithStream(self, xs):
92 xs.version = (0, 0)
93 xmlstream.ConnectAuthenticator.associateWithStream(self, xs)
94
95 xs.initializers = [ComponentInitiatingInitializer(xs)]
96
97 class ListenComponentAuthenticator(xmlstream.Authenticator):
98 """
99 Placeholder for listening components.
100 """
101
102 class Service(service.Service):
103 """
104 External server-side component service.
105 """
106
107 implements(ijabber.IService)
108
109 def componentConnected(self, xs):
110 pass
111
112 def componentDisconnected(self):
113 pass
114
115 def transportConnected(self, xs):
116 pass
117
118 def send(self, obj):
119 """
120 Send data over service parent's XML stream.
121
122 @note: L{ServiceManager} maintains a queue for data sent using this
123 method when there is no current established XML stream. This data is
124 then sent as soon as a new stream has been established and initialized.
125 Subsequently, L{componentConnected} will be called again. If this
126 queueing is not desired, use C{send} on the XmlStream object (passed to
127 L{componentConnected}) directly.
128
129 @param obj: data to be sent over the XML stream. This is usually an
130 object providing L{domish.IElement}, or serialized XML. See
131 L{xmlstream.XmlStream} for details.
132 """
133
134 self.parent.send(obj)
135
136 class ServiceManager(service.MultiService):
137 """
138 Business logic representing a managed component connection to a Jabber
139 router.
140
141 This service maintains a single connection to a Jabber router and provides
142 facilities for packet routing and transmission. Business logic modules are
143 services implementing L{ijabber.IService} (like subclasses of L{Service}), a nd
144 added as sub-service.
145 """
146
147 def __init__(self, jid, password):
148 service.MultiService.__init__(self)
149
150 # Setup defaults
151 self.jabberId = jid
152 self.xmlstream = None
153
154 # Internal buffer of packets
155 self._packetQueue = []
156
157 # Setup the xmlstream factory
158 self._xsFactory = componentFactory(self.jabberId, password)
159
160 # Register some lambda functions to keep the self.xmlstream var up to
161 # date
162 self._xsFactory.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
163 self._connected)
164 self._xsFactory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, self._authd)
165 self._xsFactory.addBootstrap(xmlstream.STREAM_END_EVENT,
166 self._disconnected)
167
168 # Map addBootstrap and removeBootstrap to the underlying factory -- is
169 # this right? I have no clue...but it'll work for now, until i can
170 # think about it more.
171 self.addBootstrap = self._xsFactory.addBootstrap
172 self.removeBootstrap = self._xsFactory.removeBootstrap
173
174 def getFactory(self):
175 return self._xsFactory
176
177 def _connected(self, xs):
178 self.xmlstream = xs
179 for c in self:
180 if ijabber.IService.providedBy(c):
181 c.transportConnected(xs)
182
183 def _authd(self, xs):
184 # Flush all pending packets
185 for p in self._packetQueue:
186 self.xmlstream.send(p)
187 self._packetQueue = []
188
189 # Notify all child services which implement the IService interface
190 for c in self:
191 if ijabber.IService.providedBy(c):
192 c.componentConnected(xs)
193
194 def _disconnected(self, _):
195 self.xmlstream = None
196
197 # Notify all child services which implement
198 # the IService interface
199 for c in self:
200 if ijabber.IService.providedBy(c):
201 c.componentDisconnected()
202
203 def send(self, obj):
204 """
205 Send data over the XML stream.
206
207 When there is no established XML stream, the data is queued and sent
208 out when a new XML stream has been established and initialized.
209
210 @param obj: data to be sent over the XML stream. This is usually an
211 object providing L{domish.IElement}, or serialized XML. See
212 L{xmlstream.XmlStream} for details.
213 """
214
215 if self.xmlstream != None:
216 self.xmlstream.send(obj)
217 else:
218 self._packetQueue.append(obj)
219
220 def buildServiceManager(jid, password, strport):
221 """
222 Constructs a pre-built L{ServiceManager}, using the specified strport
223 string.
224 """
225
226 svc = ServiceManager(jid, password)
227 client_svc = jstrports.client(strport, svc.getFactory())
228 client_svc.setServiceParent(svc)
229 return svc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698