1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """recent connections"""
23
24 import datetime
25 import fnmatch
26 import os
27 from xml.dom import minidom, Node
28
29 from flumotion.common import log, common, xdg
30 from flumotion.common.connection import PBConnectionInfo, parsePBConnectionInfo
31 from flumotion.common.errors import OptionError
32 from flumotion.configure import configure
33 from flumotion.twisted.pb import Authenticator
34
35 __version__ = "$Rev$"
36
37
39 """
40 I wrap the information contained in a single connection file entry.
41
42 I can be used to construct L{PBConnectionInfo} object, but because some of
43 my variables can be shell globs, they are all strings.
44 """
45
46 - def __init__(self, host, port, use_insecure, user, passwd, manager):
53
55 """
56 Return a L{PBConnectionInfo} object constructed from my state. If my
57 state contains shell globs, I might throw a ValueError.
58 """
59 if ('*' in self.host) or (self.use_insecure not in ('0', '1')):
60 raise ValueError("Shell glob in connection info")
61 return PBConnectionInfo(self.host, int(self.port),
62 self.use_insecure == '0',
63 Authenticator(username=self.user,
64 password=self.passwd))
65
67 return '%s@%s:%s' % (self.user, self.host, self.port)
68
69
71 """
72 I am an object representing a recent connection.
73 You can access some of my state and update the timestamp
74 (eg, when I was last connected to) by calling L{updateTimestamp}.
75
76 @ivar name: name of the recent connection usually host:port
77 @type name: string
78 @ivar host: hostname
79 @type host: string
80 @ivar filename: filename of the connection
81 @type filename: string
82 @ivar info: connection info
83 @type info: L{PBConnectionInfo}
84 @ivar timestamp: timestamp
85 @type timestamp: datetime.datetime
86 """
87
88 - def __init__(self, host, filename, info):
96
99
109
110
119
120
122 """
123 Returns if we have at least one recent connection
124 @returns: if we have a recent connection
125 @rtype: bool
126 """
127 gen = _getRecentFilenames()
128 try:
129 gen.next()
130 except StopIteration:
131 return False
132
133 return True
134
135
137 state = {}
138 for childNode in element.childNodes:
139 if (childNode.nodeType != Node.TEXT_NODE and
140 childNode.nodeType != Node.COMMENT_NODE):
141 state[childNode.nodeName] = childNode.childNodes[0].wholeText
142 return ConnectionInfo(state['host'], state['port'], state['use_insecure'],
143 state['user'], state['passwd'], state['manager'])
144
145
149
150
154
155
175
176
194
195
197 """
198 Updates the info object with the username and password taken from the list
199 of connections.
200
201 @param info: connection info
202 @type info: L{PBConnectionInfo}
203 @param connections: recent or default connections
204 @type: a list of L{ConnectionInfo}
205 @param match_glob: if values of host, port, etc. to be matched between
206 info and the recent or default connections should be
207 treated as shell globs
208 @type: boolean
209 @returns: None
210 """
211
212 def match(v1, v2):
213 if match_glob:
214
215 return fnmatch.fnmatch(v1, v2)
216 else:
217 return v1 == v2
218
219 def compatible(info, c_info):
220 if not match(info.host, c_info.host):
221 return False
222 port = str(info.port)
223 if not match(port, c_info.port):
224 return False
225 use_insecure = info.use_ssl and '0' or '1'
226 if not match(use_insecure, c_info.use_insecure):
227 return False
228 auth = info.authenticator
229 if auth.username and not match(auth.username, c_info.user):
230 return False
231
232
233 return True
234
235 for candidate in connections:
236 if compatible(info, candidate):
237
238 if not info.authenticator.username:
239 info.authenticator.username = candidate.user
240 if not info.authenticator.password:
241 info.authenticator.password = candidate.passwd
242 break
243 return info
244
245
248 """The same as L{flumotion.common.connection.parsePBConnectionInfo},
249 but fills in missing information from the recent connections cache or
250 from the default user and password definitions file if possible.
251 @param managerString: manager string we should connect to
252 @type managerString: string
253 @param use_ssl: True if we should use ssl
254 @type use_ssl: bool
255 @param defaultPort: default port to use
256 @type defaultPort: int
257 @returns: connection info
258 @rtype: a L{PBConnectionInfo}
259 """
260 recent = getRecentConnections()
261 if not managerString:
262 if recent:
263 return recent[0].info
264 else:
265 raise OptionError('No string given and no recent '
266 'connections to use')
267
268 info = parsePBConnectionInfo(managerString, username=None,
269 password=None,
270 port=defaultPort,
271 use_ssl=use_ssl)
272
273 if not (info.authenticator.username and info.authenticator.password):
274 recent_infos = [r.asConnectionInfo() for r in recent]
275 updateFromConnectionList(info, recent_infos, match_glob=False)
276 if not (info.authenticator.username and info.authenticator.password):
277 defaults = getDefaultConnections()
278 updateFromConnectionList(info, defaults, match_glob=True)
279 if not (info.authenticator.username and info.authenticator.password):
280 raise OptionError('You are connecting to %s for the '
281 'first time; please specify a user and '
282 'password (e.g. user:test@%s).'
283 % (managerString, managerString))
284 else:
285 return info
286