~ahasenack/landscape-client/landscape-client-1.5.5-0ubuntu0.9.04.0

« back to all changes in this revision

Viewing changes to landscape/user/tests/test_management.py

  • Committer: Bazaar Package Importer
  • Author(s): Rick Clark
  • Date: 2008-09-08 16:35:57 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080908163557-l3ixzj5dxz37wnw2
Tags: 1.0.18-0ubuntu1
New upstream release 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from landscape.lib import md5crypt
 
2
from landscape.user.management import UserManagement, UserManagementError
 
3
from landscape.user.tests.helpers import FakeUserProvider
 
4
from landscape.user.provider import UserNotFoundError, GroupNotFoundError
 
5
from landscape.tests.helpers import LandscapeTest, MakePathHelper, MockPopen
 
6
 
 
7
 
 
8
def guess_password(generated_password, plaintext_password):
 
9
    salt = generated_password[len("$1$"):generated_password.rfind("$")]
 
10
    crypted = md5crypt.md5crypt(plaintext_password, salt)
 
11
    return crypted
 
12
 
 
13
 
 
14
class UserWriteTest(LandscapeTest):
 
15
 
 
16
    helpers = [MakePathHelper]
 
17
 
 
18
    def setUp(self):
 
19
        LandscapeTest.setUp(self)
 
20
        self.shadow_file = self.make_path("""\
 
21
jdoe:$1$xFlQvTqe$cBtrNEDOIKMy/BuJoUdeG0:13348:0:99999:7:::
 
22
psmith:!:13348:0:99999:7:::
 
23
sbarnes:$1$q7sz09uw$q.A3526M/SHu8vUb.Jo1A/:13349:0:99999:7:::
 
24
""")
 
25
 
 
26
    def test_add_user(self):
 
27
        """L{UserManagement.add_user} should use C{adduser} to add users."""
 
28
        groups = [("users", "x", 1001, [])]
 
29
        provider = FakeUserProvider(groups=groups, popen=MockPopen(""))
 
30
        management = UserManagement(provider=provider)
 
31
        management.add_user("jdoe", "John Doe", "password", False, "users",
 
32
                            "Room 101", "+123456", None)
 
33
        self.assertEquals(len(provider.popen.popen_inputs), 2)
 
34
        self.assertEquals(provider.popen.popen_inputs[0],
 
35
                          ["adduser", "jdoe", "--disabled-password",
 
36
                           "--gecos", "John Doe,Room 101,+123456,",
 
37
                           "--gid", "1001"])
 
38
 
 
39
        usermod = provider.popen.popen_inputs[1]
 
40
        self.assertEquals(len(usermod), 4, usermod)
 
41
        password = guess_password(usermod[2], "password")
 
42
        self.assertEquals(usermod, ["usermod", "-p", password, "jdoe"])
 
43
 
 
44
    def test_add_user_error(self):
 
45
        """
 
46
        L{UserManagement.add_user} should raise an L{UserManagementError} if
 
47
        C{adduser} fails.
 
48
        """
 
49
        provider = FakeUserProvider(popen=MockPopen("", return_codes=[1, 0]))
 
50
        management = UserManagement(provider=provider)
 
51
        self.assertRaises(UserManagementError, management.add_user,
 
52
                          "jdoe", u"John Doe", "password", False, None, None,
 
53
                          None, None)
 
54
 
 
55
    def test_change_password_error(self):
 
56
        """
 
57
        L{UserManagement.add_user} should raise an L{UserManagementError} if
 
58
        C{usermod} fails.
 
59
        """
 
60
        provider = FakeUserProvider(popen=MockPopen("", return_codes=[0, 1]))
 
61
        management = UserManagement(provider=provider)
 
62
        self.assertRaises(UserManagementError, management.add_user,
 
63
                          "jdoe", u"John Doe", "password", False, None, None,
 
64
                          None, None)
 
65
 
 
66
    def test_expire_password_error(self):
 
67
        """
 
68
        L{UserManagement.add_user} should raise an L{UserManagementError} if
 
69
        C{passwd} fails.
 
70
        """
 
71
        provider = FakeUserProvider(popen=MockPopen("",
 
72
                                                    return_codes=[0, 0,1]))
 
73
        management = UserManagement(provider=provider)
 
74
        self.assertRaises(UserManagementError, management.add_user,
 
75
                          "jdoe", u"John Doe", "password", True, None, None,
 
76
                          None, None)
 
77
 
 
78
    def test_set_password(self):
 
79
        """
 
80
        L{UserManagement.set_password} should use C{usermod} to change
 
81
        a user's password.
 
82
        """
 
83
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
84
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
85
                                    popen=MockPopen("no output"))
 
86
        management = UserManagement(provider=provider)
 
87
        management.set_user_details("jdoe", password="password")
 
88
 
 
89
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
90
        password = provider.popen.popen_inputs[0][2]
 
91
        password = guess_password(password, "password")
 
92
        self.assertEquals(provider.popen.popen_inputs,
 
93
                          [["usermod", "-p", password, "jdoe"]])
 
94
 
 
95
    def test_set_password_with_system_user(self):
 
96
        """
 
97
        L{UserManagement.set_password} should allow us to edit system
 
98
        users.
 
99
        """
 
100
        data = [("root", "x", 0, 0, ",,,,", "/home/root", "/bin/zsh")]
 
101
        provider = FakeUserProvider(users=data,
 
102
                                    shadow_file=self.shadow_file,
 
103
                                    popen=MockPopen("no output"))
 
104
        management = UserManagement(provider=provider)
 
105
        management.set_user_details("root", password="password")
 
106
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
107
        password = provider.popen.popen_inputs[0][2]
 
108
        password = guess_password(password, "password")
 
109
        self.assertEquals(provider.popen.popen_inputs,
 
110
                          [["usermod", "-p", password, "root"]])
 
111
 
 
112
    def test_set_password_unicode(self):
 
113
        """
 
114
        Make sure passing unicode as username and password doesn't
 
115
        change things much (note that using something that's
 
116
        non-ASCII-encodable still probably won't work).
 
117
        """
 
118
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
119
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
120
                                    popen=MockPopen("no output"))
 
121
        management = UserManagement(provider=provider)
 
122
        management.set_user_details("jdoe", password=u"password")
 
123
 
 
124
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
125
        password = provider.popen.popen_inputs[0][2]
 
126
        password = guess_password(password, "password")
 
127
        self.assertEquals(provider.popen.popen_inputs,
 
128
                          [["usermod", "-p", password, "jdoe"]])
 
129
 
 
130
    def test_set_name(self):
 
131
        """
 
132
        L{UserManagement.set_user_details} should use C{chfn} to
 
133
        change a user's name.
 
134
        """
 
135
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
136
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
137
                                    popen=MockPopen("no output"))
 
138
        management = UserManagement(provider=provider)
 
139
        management.set_user_details("jdoe", name="JD")
 
140
 
 
141
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
142
        self.assertEquals(provider.popen.popen_inputs,
 
143
                          [["chfn", "-f", "JD", "jdoe"]])
 
144
 
 
145
    def test_set_location(self):
 
146
        """
 
147
        L{UserManagement.set_user_details} should use C{chfn} to
 
148
        change a user's location.
 
149
        """
 
150
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
151
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
152
                                    popen=MockPopen("no output"))
 
153
        management = UserManagement(provider=provider)
 
154
        management.set_user_details("jdoe", location="Everywhere")
 
155
 
 
156
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
157
        self.assertEquals(provider.popen.popen_inputs,
 
158
                          [["chfn", "-r", "Everywhere", "jdoe"]])
 
159
 
 
160
    def test_clear_user_location(self):
 
161
        """
 
162
        L{UserManagement.set_user_details} should use C{chfn} to
 
163
        change a user's location.
 
164
        """
 
165
        data = [("jdoe", "x", 1000, 1000, "JD,Room 101,,,", "/home/jdoe",
 
166
                 "/bin/zsh")]
 
167
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
168
                                    popen=MockPopen("no output"))
 
169
        management = UserManagement(provider=provider)
 
170
        management.set_user_details("jdoe", location="")
 
171
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
172
        self.assertEquals(provider.popen.popen_inputs,
 
173
                          [["chfn", "-r", "", "jdoe"]])
 
174
 
 
175
    def test_clear_telephone_numbers(self):
 
176
        """
 
177
        L{UserManagement.set_user_details} should use C{chfn} to
 
178
        change a user's telephone numbers.
 
179
        """
 
180
        data = [("jdoe", "x", 1000, 1000, "JD,,+123456,+123456", "/home/jdoe",
 
181
                 "/bin/zsh")]
 
182
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
183
                                    popen=MockPopen("no output"))
 
184
        management = UserManagement(provider=provider)
 
185
        management.set_user_details("jdoe", home_number="", work_number="")
 
186
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
187
        self.assertEquals(provider.popen.popen_inputs,
 
188
                          [["chfn", "-w", "", "-h", "", "jdoe"]])
 
189
 
 
190
    def test_set_user_details_fails(self):
 
191
        """
 
192
        L{UserManagement.set_user_details} should raise an
 
193
        L{EditUserError} if C{chfn} fails.
 
194
        """
 
195
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
196
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
197
                                    popen=MockPopen("", return_codes=[1]))
 
198
        management = UserManagement(provider=provider)
 
199
        self.assertRaises(UserNotFoundError, management.set_user_details, 1000,
 
200
                          name="John Doe")
 
201
 
 
202
    def test_contact_details_in_general(self):
 
203
        """
 
204
        L{UserManagement.set_user_details} should use C{chfn} to
 
205
        change a user's contact details.
 
206
        """
 
207
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
208
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
209
                                    popen=MockPopen("no output"))
 
210
        management = UserManagement(provider=provider)
 
211
        location = u"Everywhere"
 
212
        work_number = u"1-800-123-4567"
 
213
        home_number = u"764-4321"
 
214
        management.set_user_details("jdoe", location=location,
 
215
                                    work_number=work_number,
 
216
                                    home_number=home_number)
 
217
 
 
218
        self.assertEquals(len(provider.popen.popen_inputs), 1)
 
219
        self.assertEquals(provider.popen.popen_inputs,
 
220
                          [["chfn", "-r", location, "-w", work_number,
 
221
                            "-h", home_number, "jdoe"]])
 
222
 
 
223
    def test_set_user_details_with_unknown_username(self):
 
224
        """
 
225
        L{UserManagement.set_user_details} should raise a
 
226
        L{UserManagementError} if the user being edited doesn't exist.
 
227
        """
 
228
        provider = FakeUserProvider(popen=MockPopen(""))
 
229
        management = UserManagement(provider=provider)
 
230
        self.assertRaises(UserNotFoundError, management.set_user_details,
 
231
                          "kevin", name=u"John Doe")
 
232
 
 
233
    def test_set_primary_group(self):
 
234
        """
 
235
        L{UserManagement.set_set_user_details} should use C{usermod} to change
 
236
        the user's primary group.
 
237
        """
 
238
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
239
        groups = [("users", "x", 1001, [])]
 
240
        provider = FakeUserProvider(users=data, groups=groups,
 
241
                                    shadow_file=self.shadow_file,
 
242
                                    popen=MockPopen("no output"))
 
243
 
 
244
        management = UserManagement(provider=provider)
 
245
        management.set_user_details("jdoe", primary_group_name="users")
 
246
 
 
247
        self.assertEquals(provider.popen.popen_inputs,
 
248
                          [["usermod", "-g", "1001", "jdoe"]])
 
249
 
 
250
    def test_set_primary_group_unknown_group(self):
 
251
        """
 
252
        L{UserManagement.set_user_details should use C{usermod} to change the
 
253
        user's primary group, in the event that we have an invalid group, we
 
254
        should raise a UserManagement error.
 
255
        """
 
256
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
257
        groups = [("staff", "x", 1001, [])]
 
258
        provider = FakeUserProvider(users=data, groups=groups,
 
259
                                    shadow_file=self.shadow_file,
 
260
                                    popen=MockPopen("group id 1002 unknown",
 
261
                                    return_codes=[1]))
 
262
        management = UserManagement(provider=provider)
 
263
        self.assertRaises(GroupNotFoundError, management.set_user_details,
 
264
                          "jdoe", primary_group_name="unknown")
 
265
 
 
266
    def test_lock_user(self):
 
267
        """L{UserManagement.lock_user} should use C{usermod} to lock users."""
 
268
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
269
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
270
                                    popen=MockPopen("no output"))
 
271
        management = UserManagement(provider=provider)
 
272
        management.lock_user("jdoe")
 
273
        self.assertEquals(provider.popen.popen_inputs,
 
274
                          [["usermod", "-L", "jdoe"]])
 
275
 
 
276
    def test_lock_user_fails(self):
 
277
        """
 
278
        L{UserManagement.lock_user} should raise a L{UserManagementError} if
 
279
        a C{usermod} fails.
 
280
        """
 
281
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
282
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
283
                                    popen=MockPopen("", [1]))
 
284
        management = UserManagement(provider=provider)
 
285
        self.assertRaises(UserNotFoundError, management.lock_user, 1000)
 
286
 
 
287
    def test_lock_user_with_unknown_uid(self):
 
288
        """
 
289
        L{UserManagement.lock_user} should raise a L{UserManagementError}
 
290
        if the user being removed doesn't exist.
 
291
        """
 
292
        provider = FakeUserProvider(popen=MockPopen(""))
 
293
        management = UserManagement(provider=provider)
 
294
        self.assertRaises(UserNotFoundError, management.lock_user, 1000)
 
295
 
 
296
    def test_unlock_user(self):
 
297
        """
 
298
        L{UserManagement.unlock_user} should use C{usermod} to unlock
 
299
        users.
 
300
        """
 
301
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
302
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
303
                                    popen=MockPopen("no output"))
 
304
        management = UserManagement(provider=provider)
 
305
        result = management.unlock_user("jdoe")
 
306
        self.assertEquals(provider.popen.popen_inputs,
 
307
                          [["usermod", "-U", "jdoe"]])
 
308
 
 
309
    def test_unlock_user_fails(self):
 
310
        """
 
311
        L{UserManagement.unlock_user} should raise an
 
312
        L{UserManagementError} if a C{usermod} fails.
 
313
        """
 
314
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
315
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
316
                                    popen=MockPopen("", [1]))
 
317
        management = UserManagement(provider=provider)
 
318
        self.assertRaises(UserNotFoundError, management.unlock_user, 1000)
 
319
 
 
320
    def test_unlock_user_with_unknown_uid(self):
 
321
        """
 
322
        L{UserManagement.unlock_user} should raise a
 
323
        L{UserManagementError} if the user being removed doesn't exist.
 
324
        """
 
325
        provider = FakeUserProvider(popen=MockPopen(""))
 
326
        management = UserManagement(provider=provider)
 
327
        self.assertRaises(UserNotFoundError, management.unlock_user, 1000)
 
328
 
 
329
    def test_remove_user(self):
 
330
        """
 
331
        L{UserManagement.remove_user} should use C{deluser} to remove
 
332
        users.
 
333
        """
 
334
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
335
        popen = MockPopen("Removing user `jdoe'...\r\ndone.")
 
336
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
337
                                    popen=popen)
 
338
        management = UserManagement(provider=provider)
 
339
        management.remove_user("jdoe")
 
340
        self.assertEquals(popen.popen_inputs, [["deluser", "jdoe"]])
 
341
 
 
342
    def test_remove_user_with_unknown_username(self):
 
343
        """
 
344
        L{UserManagement.remove_user} should raise a
 
345
        L{UserManagementError} if the user being removed doesn't exist.
 
346
        """
 
347
        provider = FakeUserProvider(popen=MockPopen(""))
 
348
        management = UserManagement(provider=provider)
 
349
        self.assertRaises(UserNotFoundError, management.remove_user, "smith")
 
350
 
 
351
    def test_remove_user_fails(self):
 
352
        """
 
353
        L{UserManagement.remove_user} should raise a
 
354
        L{UserManagementError} if the user can't be removed.
 
355
        """
 
356
        self.log_helper.ignore_errors(UserNotFoundError)
 
357
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
358
        popen = MockPopen("/usr/sbin/deluser: Only root may remove a user or "
 
359
                          "group from the system.", [1])
 
360
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
361
                                    popen=popen)
 
362
        management = UserManagement(provider=provider)
 
363
        self.assertRaises(UserNotFoundError, management.remove_user, "smith")
 
364
 
 
365
    def test_remove_user_and_home(self):
 
366
        """
 
367
        L{UserManagement.remove_user} should use C{deluser} to remove
 
368
        the contents of a user's home directory.
 
369
        """
 
370
        data = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
371
        popen = MockPopen("Removing user `jdoe`...\r\ndone.", [0])
 
372
        provider = FakeUserProvider(users=data, shadow_file=self.shadow_file,
 
373
                                    popen=popen)
 
374
        management = UserManagement(provider=provider)
 
375
        management.remove_user("jdoe", delete_home=True)
 
376
        self.assertEquals(popen.popen_inputs,
 
377
                          [["deluser", "jdoe", "--remove-home"]])
 
378
 
 
379
 
 
380
 
 
381
class GroupWriteTest(LandscapeTest):
 
382
 
 
383
    helpers = [MakePathHelper]
 
384
 
 
385
    def setUp(self):
 
386
        LandscapeTest.setUp(self)
 
387
        self.shadow_file = self.make_path("""\
 
388
jdoe:$1$xFlQvTqe$cBtrNEDOIKMy/BuJoUdeG0:13348:0:99999:7:::
 
389
psmith:!:13348:0:99999:7:::
 
390
sbarnes:$1$q7sz09uw$q.A3526M/SHu8vUb.Jo1A/:13349:0:99999:7:::
 
391
""")
 
392
 
 
393
    def test_add_group(self):
 
394
        """
 
395
        L{UserManagement.add_group} should use the system tool
 
396
        C{addgroup} to create groups.
 
397
        """
 
398
        provider = FakeUserProvider(popen=MockPopen("Result"))
 
399
        management = UserManagement(provider=provider)
 
400
        result = management.add_group("webdev")
 
401
        self.assertEquals(provider.popen.popen_inputs, [["addgroup", "webdev"]])
 
402
        self.assertEquals(result, "Result")
 
403
 
 
404
    def test_add_group_handles_errors(self):
 
405
        """
 
406
        If the system tool C{addgroup} returns a non-0 exit code,
 
407
        L{UserManagement.add_group} should raise an L{UserManagementError}.
 
408
        """
 
409
        provider = FakeUserProvider(popen=MockPopen("Error Result", [1]))
 
410
        management = UserManagement(provider=provider)
 
411
        self.assertRaises(UserManagementError, management.add_group, "kaboom")
 
412
 
 
413
    def test_set_group_details(self):
 
414
        """
 
415
        L{UserManagement.set_group_details} should use C{groupmode} to
 
416
        change a group's name.
 
417
        """
 
418
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
419
        groups = [("bizdev", "x", 1001, [])]
 
420
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
421
                                    groups=groups, popen=MockPopen("no output"))
 
422
        management = UserManagement(provider=provider)
 
423
        management.set_group_details("bizdev", "sales")
 
424
 
 
425
        self.assertEquals(provider.popen.popen_inputs,
 
426
                          [["groupmod", "-n", "sales", "bizdev"]])
 
427
 
 
428
    def test_set_group_details_with_unknown_groupname(self):
 
429
        """
 
430
        L{UserManagement.set_group_details} should raise a
 
431
        L{UserManagementError} if the group being updated doesn't exist.
 
432
        """
 
433
        provider = FakeUserProvider(popen=MockPopen(""))
 
434
        management = UserManagement(provider=provider)
 
435
        self.assertRaises(GroupNotFoundError, management.set_group_details,
 
436
                          "sales", u"newsales")
 
437
 
 
438
    def test_set_group_details_fails(self):
 
439
        """
 
440
        L{UserManagement.set_group_details} should raise a
 
441
        L{UserManagementError} if the group can't be renamed.
 
442
        """
 
443
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
444
        groups = [("bizdev", "x", 1001, [])]
 
445
        popen = MockPopen("groupmod: sales is not a unique name", [1])
 
446
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
447
                                    groups=groups, popen=popen)
 
448
        management = UserManagement(provider=provider)
 
449
        self.assertRaises(UserManagementError, management.set_group_details,
 
450
                          "bizdev", u"sales")
 
451
 
 
452
    def test_add_member(self):
 
453
        """
 
454
        L{UserManagement.add_group_member} should use the system tool
 
455
        C{gpasswd} via the process factory to add a member to a group.
 
456
        """
 
457
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
458
        groups = [("bizdev", "x", 1001, [])]
 
459
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
460
                                    groups=groups,
 
461
                                    popen=MockPopen(
 
462
                                    "Removing user jdoe from group bizdev"))
 
463
        management = UserManagement(provider=provider)
 
464
 
 
465
        output = management.add_group_member("jdoe", "bizdev")
 
466
        self.assertEquals(provider.popen.popen_inputs,
 
467
                          [["gpasswd", "-a", "jdoe", "bizdev"]])
 
468
        self.assertEquals(output, "Removing user jdoe from group bizdev")
 
469
 
 
470
    def test_add_member_with_unknown_groupname(self):
 
471
        """
 
472
        L{UserManagement.add_group_member} should raise a
 
473
        L{UserManagementError} if the group to add the member to doesn't
 
474
        exist.
 
475
        """
 
476
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
477
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
478
                                    popen=MockPopen(""))
 
479
        management = UserManagement(provider=provider)
 
480
        self.assertRaises(GroupNotFoundError, management.add_group_member,
 
481
                          "jdoe", "bizdev")
 
482
 
 
483
    def test_add_member_with_unknown_username(self):
 
484
        """
 
485
        L{UserManagement.add_group_member} should raise a
 
486
        L{UserManagementError} if the user being associated doesn't
 
487
        exist.
 
488
        """
 
489
        groups = [("bizdev", "x", 1001, [])]
 
490
        provider = FakeUserProvider(groups=groups, popen=MockPopen(""))
 
491
        management = UserManagement(provider=provider)
 
492
        self.assertRaises(UserNotFoundError, management.add_group_member,
 
493
                          "bizdev", "smith")
 
494
 
 
495
    def test_add_member_failure(self):
 
496
        """
 
497
        If adding a member to a group fails,
 
498
        L{UserManagement.add_group_member} should raise an
 
499
        L{UserManagementError}.
 
500
        """
 
501
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
502
        groups = [("bizdev", "x", 1001, [])]
 
503
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
504
                                    groups=groups,
 
505
                                    popen=MockPopen("no output", [1]))
 
506
        management = UserManagement(provider=provider)
 
507
        self.assertRaises(UserNotFoundError, management.add_group_member,
 
508
                          1000, 1001)
 
509
 
 
510
    def test_remove_member(self):
 
511
        """
 
512
        L{UserManagement.remove_group_member} should use the system
 
513
        tool C{gpasswd} via the process factory to remove a member
 
514
        from a group.
 
515
        """
 
516
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
517
        groups = [("bizdev", "x", 1001, [])]
 
518
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
519
                                    groups=groups,
 
520
                                    popen=MockPopen(
 
521
                                    "Removing user jdoe from group bizdev"))
 
522
        management = UserManagement(provider=provider)
 
523
        output = management.remove_group_member("jdoe", "bizdev")
 
524
        self.assertEquals(provider.popen.popen_inputs,
 
525
                          [["gpasswd", "-d", "jdoe", "bizdev"]])
 
526
        self.assertEquals(output, "Removing user jdoe from group bizdev")
 
527
 
 
528
    def test_remove_member_with_unknown_groupname(self):
 
529
        """
 
530
        L{UserManagement.remove_group_member} should raise a
 
531
        L{UserManagementError} if the group to remove the member to
 
532
        doesn't exist.
 
533
        """
 
534
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
535
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
536
                                    popen=MockPopen("", return_codes=[2]))
 
537
        management = UserManagement(provider=provider)
 
538
        self.assertRaises(GroupNotFoundError, management.remove_group_member,
 
539
                          "jdoe", "bizdev")
 
540
 
 
541
    def test_remove_member_with_unknown_username(self):
 
542
        """
 
543
        L{UserManagement.remove_group_member} should raise a
 
544
        L{UserManagementError} if the user being associated doesn't
 
545
        exist.
 
546
        """
 
547
        groups = [("bizdev", "x", 1001, [])]
 
548
        provider = FakeUserProvider(groups=groups,
 
549
                                    popen=MockPopen("", return_codes=[4]))
 
550
        management = UserManagement(provider=provider)
 
551
        self.assertRaises(UserNotFoundError, management.remove_group_member,
 
552
                          "jdoe", "bizdev")
 
553
 
 
554
    def test_remove_member_failure(self):
 
555
        """
 
556
        If removing a member from a group fails,
 
557
        L{UserManagement.remove_group_member} should raise a
 
558
        L{UserManagementError}.
 
559
        """
 
560
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
561
        groups = [("bizdev", "x", 1001, [])]
 
562
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
563
                                    groups=groups,
 
564
                                    popen=MockPopen("no output", [1]))
 
565
        management = UserManagement(provider=provider)
 
566
        self.assertRaises(UserManagementError,
 
567
                          management.remove_group_member, "jdoe", "bizdev")
 
568
 
 
569
    def test_remove_group(self):
 
570
        """
 
571
        L{UserManagement.remove_group} should use C{groupdel} to
 
572
        remove groups.
 
573
        """
 
574
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
575
        groups = [("bizdev", "x", 50, [])]
 
576
        popen = MockPopen("Removing group `bizdev'...\r\ndone.")
 
577
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
578
                                    groups=groups, popen=popen)
 
579
        management = UserManagement(provider=provider)
 
580
        output = management.remove_group("bizdev")
 
581
        self.assertEquals(provider.popen.popen_inputs, [["groupdel", "bizdev"]])
 
582
 
 
583
    def test_remove_group_with_unknown_groupname(self):
 
584
        """
 
585
        L{UserManagement.remove_group} should raise a
 
586
        L{GroupMissingError} if the group being removed doesn't exist.
 
587
        """
 
588
        provider = FakeUserProvider(popen=MockPopen(""))
 
589
        management = UserManagement(provider=provider)
 
590
        self.assertRaises(GroupNotFoundError, management.remove_group, "ubuntu")
 
591
 
 
592
    def test_remove_group_fails(self):
 
593
        """
 
594
        L{UserManagement.remove_user} should raise a
 
595
        L{RemoveUserError} if the user can't be removed.
 
596
        """
 
597
        users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/zsh")]
 
598
        groups = [("bizdev", "x", 50, [])]
 
599
        popen = MockPopen("/usr/sbin/deluser: Only root may remove a user or "
 
600
                          "group from the system.", [1])
 
601
        provider = FakeUserProvider(users=users, shadow_file=self.shadow_file,
 
602
                                    groups=groups, popen=popen)
 
603
        management = UserManagement(provider=provider)
 
604
        self.assertRaises(GroupNotFoundError, management.remove_group,
 
605
                          "ubuntu")