1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 from caldavclientlibrary.admin.xmlaccounts.directory import XMLDirectory
18 from xml.etree.ElementTree import XML
19 from StringIO import StringIO
20 from caldavclientlibrary.protocol.utils.xmlhelpers import BetterElementTree
21 from caldavclientlibrary.admin.xmlaccounts import recordtypes
22 from getpass import getpass
23
24 import getopt
25
27
28 - def __init__(self, cmdname, description):
33
35 if self.allRecordsAllowed():
36 print """USAGE: %s [TYPE] [OPTIONS]
37
38 TYPE: One of "all", "users", "groups", "locations" or "resources". Also,
39 "a", "u", "g", "l" or "r" as shortcuts. Invalid or missing type is
40 treated as "all".
41
42 Options:
43 -f file path to accounts.xml
44 """ % (self.cmdname,)
45 else:
46 print """USAGE: %s TYPE [OPTIONS]
47
48 TYPE: One of "users", "groups", "locations" or "resources". Also,
49 "u", "g", "l" or "r" as shortcuts.
50
51 Options:
52 -f file path to accounts.xml
53 """ % (self.cmdname,)
54
56 """
57 Indicates whether a command is able to operate on all record types in addition to
58 individual record types. Sub-classes should override this if they can handle all
59 record in one go.
60 """
61 return False
62
64 """
65 Execute the command specified by the command line arguments.
66
67 @param argv: command line arguments.
68 @type argv: C{list}
69
70 @return: 1 for success, 0 for failure.
71 @rtype: C{int}
72 """
73
74
75 argv = self.getTypeArgument(argv)
76 if argv is None:
77 return 0
78
79 opts, args = getopt.getopt(argv, 'f:h', ["help", ])
80
81 for name, value in opts:
82 if name == "-f":
83 self.path = value
84 elif name in ("-h", "--help"):
85 self.usage()
86 return 1
87 else:
88 print "Unknown option: %s." % (name,)
89 self.usage()
90 return 0
91
92 if not self.path:
93 print "Must specify a path."
94 self.usage()
95 return 0
96 if args:
97 print "Arguments not allowed."
98 self.usage()
99 return 0
100
101 if not self.loadAccounts():
102 return 0
103 return self.doCommand()
104
106 """
107 Extract the user specified record type argument from the command line arguments.
108
109 @param argv: command line arguments.
110 @type argv: C{list}
111
112 @return: the modified arguments (if a record type is found the corresponding argument is
113 removed from the argv passed in).
114 @rtype: C{list}
115 """
116
117 if len(argv) == 0:
118 print "Must specify a record type."
119 self.usage()
120 return None
121 type = argv[0]
122 type = self.mapType(type)
123 if not type and not self.allRecordsAllowed():
124 print "Invalid type '%s'." % (argv[0],)
125 self.usage()
126 return None
127 self.recordType = type if type else recordtypes.recordType_all
128 if type:
129 return argv[1:]
130 else:
131 return argv
132
134 """
135 Map the specified user record type input to the actual record type identifier.
136
137 @param type: user input from the command line.
138 @type type: C{str}
139
140 @return: identifier matching the user input, or C{None} if no match.
141 @rtype: L{admin.xmlaccounts.recordtypes}
142 """
143 return {
144 "users" : recordtypes.recordType_users,
145 "u" : recordtypes.recordType_users,
146 "groups" : recordtypes.recordType_groups,
147 "g" : recordtypes.recordType_groups,
148 "locations": recordtypes.recordType_locations,
149 "l" : recordtypes.recordType_locations,
150 "resources": recordtypes.recordType_resources,
151 "r" : recordtypes.recordType_resources,
152 "all" : recordtypes.recordType_all,
153 "a" : recordtypes.recordType_all,
154 }.get(type, None)
155
157 """
158 Load the entire directory from the XML file.
159 """
160
161
162 f = open(self.path, "r")
163 if not f:
164 print "Could not open file: %s" % (self.path,)
165 return 0
166 xmldata = f.read()
167 f.close()
168 self.directory = XMLDirectory()
169 self.directory.parseXML(XML(xmldata))
170 return 1
171
173 """
174 Write the entire directory to the XML file.
175 """
176
177 node = self.directory.writeXML()
178 os = StringIO()
179 xmldoc = BetterElementTree(node)
180 xmldoc.writeUTF8(os)
181 f = open(self.path, "w")
182 if not f:
183 print "Could not open file: %s for writing" % (self.path,)
184 return 0
185 f.write(os.getvalue())
186 f.close()
187 return 1
188
190 """
191 Run the command. Sub-classes must implement this.
192 """
193 raise NotImplementedError
194
196 """
197 Prompt the user for a password.
198 """
199 while True:
200 password = getpass("Password: ")
201 temp = getpass("Password (again): ")
202 if temp != password:
203 print "Passwords do not match. Try again."
204 else:
205 return password
206
208 """
209 Prompt the user for a list of members.
210 """
211 results = []
212 print prompt
213 while True:
214 memberType = raw_input("%s type [u/g/l/r or leave empty to stop adding %s]: " % (title, type,))
215 if memberType in ("u", "g", "l", "r",):
216 memberUid = raw_input("%s uid [leave empty to stop adding %s]: " % (title, type,))
217 if memberUid:
218
219 recordType = self.mapType(memberType)
220 if self.directory.containsRecord(recordType, memberUid):
221 results.append((recordType, memberUid,))
222 else:
223 print "Record uid: '%s 'of type: '%s' does not exist in the directory." % (memberUid, recordType,)
224 else:
225 break
226 elif memberType:
227 print "Member type must be one of 'u' (users), 'g' (groups), 'l' (locations) or 'r' (resources)."
228 else:
229 break
230 return results
231