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