Merge lp:~anso/nova/authupdate into lp:~hudson-openstack/nova/trunk

Proposed by Todd Willey
Status: Merged
Approved by: Todd Willey
Approved revision: 296
Merged at revision: 305
Proposed branch: lp:~anso/nova/authupdate
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 509 lines (+303/-144)
4 files modified
bin/nova-manage (+13/-0)
nova/auth/ldapdriver.py (+14/-2)
nova/auth/manager.py (+6/-0)
nova/tests/auth_unittest.py (+270/-142)
To merge this branch: bzr merge lp:~anso/nova/authupdate
Reviewer Review Type Date Requested Status
Jesse Andrews (community) Approve
Vish Ishaya (community) Approve
Review via email: mp+36925@code.launchpad.net

Description of the change

* Create an AuthManager#update_user method to change keys and admin status.
* Refactor the auth_unittest to not care about test order
* Expose the update_user method via nova-manage

To post a comment you must log in.
Revision history for this message
Vish Ishaya (vishvananda) wrote :

Yay, finally auth_unittests that don't suck!

review: Approve
lp:~anso/nova/authupdate updated
296. By Todd Willey

Merge Trunk

Revision history for this message
Jesse Andrews (anotherjesse) wrote :

tests are good

review: Approve
Revision history for this message
Jay Pipes (jaypipes) wrote :

Probably best to print stuff via logging and not directly to stdout:

19 + print "is_admin: %r" % is_admin

:)

Revision history for this message
Todd Willey (xtoddx) wrote :

We actually print throughout bin/nova-manage, since the typical use case is for humans and scripts to use it. The question then is if we actually want to show is_admin or not. It is really just debugging, but since it has a nonstandard way of figuring out the setting ('' = leave intact, 'T', anything else = 'F') I thought it would be worth seeing.

I'm going to remove it though, since if we were going to display it, it should happen by loading the user object after the modification has been made, and showing the input value is relatively useless. I didn't think we needed to show the new keys since the 'exports' command puts those on stdout.

New branch is for review at: https://code.launchpad.net/~anso/nova/printremove/+merge/37039

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/nova-manage'
2--- bin/nova-manage 2010-09-29 03:23:09 +0000
3+++ bin/nova-manage 2010-09-29 03:25:57 +0000
4@@ -266,6 +266,19 @@
5 for user in self.manager.get_users():
6 print user.name
7
8+ def modify(self, name, access_key, secret_key, is_admin):
9+ """update a users keys & admin flag
10+ arguments: accesskey secretkey admin
11+ leave any field blank to ignore it, admin should be 'T', 'F', or blank
12+ """
13+ if not is_admin:
14+ is_admin = None
15+ elif is_admin.upper()[0] == 'T':
16+ is_admin = True
17+ else:
18+ is_admin = False
19+ print "is_admin: %r" % is_admin
20+ self.manager.modify_user(name, access_key, secret_key, is_admin)
21
22 class ProjectCommands(object):
23 """Class for managing projects."""
24
25=== modified file 'nova/auth/ldapdriver.py'
26--- nova/auth/ldapdriver.py 2010-09-21 05:08:31 +0000
27+++ nova/auth/ldapdriver.py 2010-09-29 03:25:57 +0000
28@@ -256,8 +256,7 @@
29 if not self.__user_exists(uid):
30 raise exception.NotFound("User %s doesn't exist" % uid)
31 self.__remove_from_all(uid)
32- self.conn.delete_s('uid=%s,%s' % (uid,
33- FLAGS.ldap_user_subtree))
34+ self.conn.delete_s(self.__uid_to_dn(uid))
35
36 def delete_project(self, project_id):
37 """Delete a project"""
38@@ -265,6 +264,19 @@
39 self.__delete_roles(project_dn)
40 self.__delete_group(project_dn)
41
42+ def modify_user(self, uid, access_key=None, secret_key=None, admin=None):
43+ """Modify an existing project"""
44+ if not access_key and not secret_key and admin is None:
45+ return
46+ attr = []
47+ if access_key:
48+ attr.append((self.ldap.MOD_REPLACE, 'accessKey', access_key))
49+ if secret_key:
50+ attr.append((self.ldap.MOD_REPLACE, 'secretKey', secret_key))
51+ if admin is not None:
52+ attr.append((self.ldap.MOD_REPLACE, 'isAdmin', str(admin).upper()))
53+ self.conn.modify_s(self.__uid_to_dn(uid), attr)
54+
55 def __user_exists(self, uid):
56 """Check if user exists"""
57 return self.get_user(uid) != None
58
59=== modified file 'nova/auth/manager.py'
60--- nova/auth/manager.py 2010-09-23 21:18:12 +0000
61+++ nova/auth/manager.py 2010-09-29 03:25:57 +0000
62@@ -630,6 +630,12 @@
63 with self.driver() as drv:
64 drv.delete_user(uid)
65
66+ def modify_user(self, user, access_key=None, secret_key=None, admin=None):
67+ """Modify credentials for a user"""
68+ uid = User.safe_id(user)
69+ with self.driver() as drv:
70+ drv.modify_user(uid, access_key, secret_key, admin)
71+
72 def get_credentials(self, user, project=None):
73 """Get credential zip for user in project"""
74 if not isinstance(user, User):
75
76=== modified file 'nova/tests/auth_unittest.py'
77--- nova/tests/auth_unittest.py 2010-09-25 02:25:12 +0000
78+++ nova/tests/auth_unittest.py 2010-09-29 03:25:57 +0000
79@@ -28,26 +28,71 @@
80
81 FLAGS = flags.FLAGS
82
83-
84-class AuthTestCase(test.TrialTestCase):
85- flush_db = False
86+class user_generator(object):
87+ def __init__(self, manager, **user_state):
88+ if 'name' not in user_state:
89+ user_state['name'] = 'test1'
90+ self.manager = manager
91+ self.user = manager.create_user(**user_state)
92+
93+ def __enter__(self):
94+ return self.user
95+
96+ def __exit__(self, value, type, trace):
97+ self.manager.delete_user(self.user)
98+
99+class project_generator(object):
100+ def __init__(self, manager, **project_state):
101+ if 'name' not in project_state:
102+ project_state['name'] = 'testproj'
103+ if 'manager_user' not in project_state:
104+ project_state['manager_user'] = 'test1'
105+ self.manager = manager
106+ self.project = manager.create_project(**project_state)
107+
108+ def __enter__(self):
109+ return self.project
110+
111+ def __exit__(self, value, type, trace):
112+ self.manager.delete_project(self.project)
113+
114+class user_and_project_generator(object):
115+ def __init__(self, manager, user_state={}, project_state={}):
116+ self.manager = manager
117+ if 'name' not in user_state:
118+ user_state['name'] = 'test1'
119+ if 'name' not in project_state:
120+ project_state['name'] = 'testproj'
121+ if 'manager_user' not in project_state:
122+ project_state['manager_user'] = 'test1'
123+ self.user = manager.create_user(**user_state)
124+ self.project = manager.create_project(**project_state)
125+
126+ def __enter__(self):
127+ return (self.user, self.project)
128+
129+ def __exit__(self, value, type, trace):
130+ self.manager.delete_user(self.user)
131+ self.manager.delete_project(self.project)
132+
133+class AuthManagerTestCase(test.TrialTestCase):
134 def setUp(self):
135- super(AuthTestCase, self).setUp()
136+ super(AuthManagerTestCase, self).setUp()
137 self.flags(connection_type='fake')
138 self.manager = manager.AuthManager()
139
140- def test_001_can_create_users(self):
141- self.manager.create_user('test1', 'access', 'secret')
142- self.manager.create_user('test2')
143-
144- def test_002_can_get_user(self):
145- user = self.manager.get_user('test1')
146-
147- def test_003_can_retreive_properties(self):
148- user = self.manager.get_user('test1')
149- self.assertEqual('test1', user.id)
150- self.assertEqual('access', user.access)
151- self.assertEqual('secret', user.secret)
152+ def test_create_and_find_user(self):
153+ with user_generator(self.manager):
154+ self.assert_(self.manager.get_user('test1'))
155+
156+ def test_create_and_find_with_properties(self):
157+ with user_generator(self.manager, name="herbert", secret="classified",
158+ access="private-party"):
159+ u = self.manager.get_user('herbert')
160+ self.assertEqual('herbert', u.id)
161+ self.assertEqual('herbert', u.name)
162+ self.assertEqual('classified', u.secret)
163+ self.assertEqual('private-party', u.access)
164
165 def test_004_signature_is_valid(self):
166 #self.assertTrue(self.manager.authenticate( **boto.generate_url ... ? ? ? ))
167@@ -64,133 +109,216 @@
168 'export S3_URL="http://127.0.0.1:3333/"\n' +
169 'export EC2_USER_ID="test1"\n')
170
171- def test_010_can_list_users(self):
172- users = self.manager.get_users()
173- logging.warn(users)
174- self.assertTrue(filter(lambda u: u.id == 'test1', users))
175-
176- def test_101_can_add_user_role(self):
177- self.assertFalse(self.manager.has_role('test1', 'itsec'))
178- self.manager.add_role('test1', 'itsec')
179- self.assertTrue(self.manager.has_role('test1', 'itsec'))
180-
181- def test_199_can_remove_user_role(self):
182- self.assertTrue(self.manager.has_role('test1', 'itsec'))
183- self.manager.remove_role('test1', 'itsec')
184- self.assertFalse(self.manager.has_role('test1', 'itsec'))
185-
186- def test_201_can_create_project(self):
187- project = self.manager.create_project('testproj', 'test1', 'A test project', ['test1'])
188- self.assertTrue(filter(lambda p: p.name == 'testproj', self.manager.get_projects()))
189- self.assertEqual(project.name, 'testproj')
190- self.assertEqual(project.description, 'A test project')
191- self.assertEqual(project.project_manager_id, 'test1')
192- self.assertTrue(project.has_member('test1'))
193-
194- def test_202_user1_is_project_member(self):
195- self.assertTrue(self.manager.get_user('test1').is_project_member('testproj'))
196-
197- def test_203_user2_is_not_project_member(self):
198- self.assertFalse(self.manager.get_user('test2').is_project_member('testproj'))
199-
200- def test_204_user1_is_project_manager(self):
201- self.assertTrue(self.manager.get_user('test1').is_project_manager('testproj'))
202-
203- def test_205_user2_is_not_project_manager(self):
204- self.assertFalse(self.manager.get_user('test2').is_project_manager('testproj'))
205-
206- def test_206_can_add_user_to_project(self):
207- self.manager.add_to_project('test2', 'testproj')
208- self.assertTrue(self.manager.get_project('testproj').has_member('test2'))
209-
210- def test_207_can_remove_user_from_project(self):
211- self.manager.remove_from_project('test2', 'testproj')
212- self.assertFalse(self.manager.get_project('testproj').has_member('test2'))
213-
214- def test_208_can_remove_add_user_with_role(self):
215- self.manager.add_to_project('test2', 'testproj')
216- self.manager.add_role('test2', 'developer', 'testproj')
217- self.manager.remove_from_project('test2', 'testproj')
218- self.assertFalse(self.manager.has_role('test2', 'developer', 'testproj'))
219- self.manager.add_to_project('test2', 'testproj')
220- self.manager.remove_from_project('test2', 'testproj')
221-
222- def test_209_can_generate_x509(self):
223- # MUST HAVE RUN CLOUD SETUP BY NOW
224- self.cloud = cloud.CloudController()
225- self.cloud.setup()
226- _key, cert_str = self.manager._generate_x509_cert('test1', 'testproj')
227- logging.debug(cert_str)
228-
229- # Need to verify that it's signed by the right intermediate CA
230- full_chain = crypto.fetch_ca(project_id='testproj', chain=True)
231- int_cert = crypto.fetch_ca(project_id='testproj', chain=False)
232- cloud_cert = crypto.fetch_ca()
233- logging.debug("CA chain:\n\n =====\n%s\n\n=====" % full_chain)
234- signed_cert = X509.load_cert_string(cert_str)
235- chain_cert = X509.load_cert_string(full_chain)
236- int_cert = X509.load_cert_string(int_cert)
237- cloud_cert = X509.load_cert_string(cloud_cert)
238- self.assertTrue(signed_cert.verify(chain_cert.get_pubkey()))
239- self.assertTrue(signed_cert.verify(int_cert.get_pubkey()))
240-
241- if not FLAGS.use_intermediate_ca:
242- self.assertTrue(signed_cert.verify(cloud_cert.get_pubkey()))
243- else:
244- self.assertFalse(signed_cert.verify(cloud_cert.get_pubkey()))
245-
246- def test_210_can_add_project_role(self):
247- project = self.manager.get_project('testproj')
248- self.assertFalse(project.has_role('test1', 'sysadmin'))
249- self.manager.add_role('test1', 'sysadmin')
250- self.assertFalse(project.has_role('test1', 'sysadmin'))
251- project.add_role('test1', 'sysadmin')
252- self.assertTrue(project.has_role('test1', 'sysadmin'))
253-
254- def test_211_can_list_project_roles(self):
255- project = self.manager.get_project('testproj')
256- user = self.manager.get_user('test1')
257- self.manager.add_role(user, 'netadmin', project)
258- roles = self.manager.get_user_roles(user)
259- self.assertTrue('sysadmin' in roles)
260- self.assertFalse('netadmin' in roles)
261- project_roles = self.manager.get_user_roles(user, project)
262- self.assertTrue('sysadmin' in project_roles)
263- self.assertTrue('netadmin' in project_roles)
264- # has role should be false because global role is missing
265- self.assertFalse(self.manager.has_role(user, 'netadmin', project))
266-
267-
268- def test_212_can_remove_project_role(self):
269- project = self.manager.get_project('testproj')
270- self.assertTrue(project.has_role('test1', 'sysadmin'))
271- project.remove_role('test1', 'sysadmin')
272- self.assertFalse(project.has_role('test1', 'sysadmin'))
273- self.manager.remove_role('test1', 'sysadmin')
274- self.assertFalse(project.has_role('test1', 'sysadmin'))
275-
276- def test_214_can_retrieve_project_by_user(self):
277- project = self.manager.create_project('testproj2', 'test2', 'Another test project', ['test2'])
278- self.assert_(len(self.manager.get_projects()) > 1)
279- self.assertEqual(len(self.manager.get_projects('test2')), 1)
280-
281- def test_220_can_modify_project(self):
282- self.manager.modify_project('testproj', 'test2', 'new description')
283- project = self.manager.get_project('testproj')
284- self.assertEqual(project.project_manager_id, 'test2')
285- self.assertEqual(project.description, 'new description')
286-
287- def test_299_can_delete_project(self):
288- self.manager.delete_project('testproj')
289- self.assertFalse(filter(lambda p: p.name == 'testproj', self.manager.get_projects()))
290- self.manager.delete_project('testproj2')
291-
292- def test_999_can_delete_users(self):
293+ def test_can_list_users(self):
294+ with user_generator(self.manager):
295+ with user_generator(self.manager, name="test2"):
296+ users = self.manager.get_users()
297+ self.assert_(filter(lambda u: u.id == 'test1', users))
298+ self.assert_(filter(lambda u: u.id == 'test2', users))
299+ self.assert_(not filter(lambda u: u.id == 'test3', users))
300+
301+ def test_can_add_and_remove_user_role(self):
302+ with user_generator(self.manager):
303+ self.assertFalse(self.manager.has_role('test1', 'itsec'))
304+ self.manager.add_role('test1', 'itsec')
305+ self.assertTrue(self.manager.has_role('test1', 'itsec'))
306+ self.manager.remove_role('test1', 'itsec')
307+ self.assertFalse(self.manager.has_role('test1', 'itsec'))
308+
309+ def test_can_create_and_get_project(self):
310+ with user_and_project_generator(self.manager) as (u,p):
311+ self.assert_(self.manager.get_user('test1'))
312+ self.assert_(self.manager.get_user('test1'))
313+ self.assert_(self.manager.get_project('testproj'))
314+
315+ def test_can_list_projects(self):
316+ with user_and_project_generator(self.manager):
317+ with project_generator(self.manager, name="testproj2"):
318+ projects = self.manager.get_projects()
319+ self.assert_(filter(lambda p: p.name == 'testproj', projects))
320+ self.assert_(filter(lambda p: p.name == 'testproj2', projects))
321+ self.assert_(not filter(lambda p: p.name == 'testproj3',
322+ projects))
323+
324+ def test_can_create_and_get_project_with_attributes(self):
325+ with user_generator(self.manager):
326+ with project_generator(self.manager, description='A test project'):
327+ project = self.manager.get_project('testproj')
328+ self.assertEqual('A test project', project.description)
329+
330+ def test_can_create_project_with_manager(self):
331+ with user_and_project_generator(self.manager) as (user, project):
332+ self.assertEqual('test1', project.project_manager_id)
333+ self.assertTrue(self.manager.is_project_manager(user, project))
334+
335+ def test_create_project_assigns_manager_to_members(self):
336+ with user_and_project_generator(self.manager) as (user, project):
337+ self.assertTrue(self.manager.is_project_member(user, project))
338+
339+ def test_no_extra_project_members(self):
340+ with user_generator(self.manager, name='test2') as baduser:
341+ with user_and_project_generator(self.manager) as (user, project):
342+ self.assertFalse(self.manager.is_project_member(baduser,
343+ project))
344+
345+ def test_no_extra_project_managers(self):
346+ with user_generator(self.manager, name='test2') as baduser:
347+ with user_and_project_generator(self.manager) as (user, project):
348+ self.assertFalse(self.manager.is_project_manager(baduser,
349+ project))
350+
351+ def test_can_add_user_to_project(self):
352+ with user_generator(self.manager, name='test2') as user:
353+ with user_and_project_generator(self.manager) as (_user, project):
354+ self.manager.add_to_project(user, project)
355+ project = self.manager.get_project('testproj')
356+ self.assertTrue(self.manager.is_project_member(user, project))
357+
358+ def test_can_remove_user_from_project(self):
359+ with user_generator(self.manager, name='test2') as user:
360+ with user_and_project_generator(self.manager) as (_user, project):
361+ self.manager.add_to_project(user, project)
362+ project = self.manager.get_project('testproj')
363+ self.assertTrue(self.manager.is_project_member(user, project))
364+ self.manager.remove_from_project(user, project)
365+ project = self.manager.get_project('testproj')
366+ self.assertFalse(self.manager.is_project_member(user, project))
367+
368+ def test_can_add_remove_user_with_role(self):
369+ with user_generator(self.manager, name='test2') as user:
370+ with user_and_project_generator(self.manager) as (_user, project):
371+ # NOTE(todd): after modifying users you must reload project
372+ self.manager.add_to_project(user, project)
373+ project = self.manager.get_project('testproj')
374+ self.manager.add_role(user, 'developer', project)
375+ self.assertTrue(self.manager.is_project_member(user, project))
376+ self.manager.remove_from_project(user, project)
377+ project = self.manager.get_project('testproj')
378+ self.assertFalse(self.manager.has_role(user, 'developer',
379+ project))
380+ self.assertFalse(self.manager.is_project_member(user, project))
381+
382+ def test_can_generate_x509(self):
383+ # NOTE(todd): this doesn't assert against the auth manager
384+ # so it probably belongs in crypto_unittest
385+ # but I'm leaving it where I found it.
386+ with user_and_project_generator(self.manager) as (user, project):
387+ # NOTE(todd): Should mention why we must setup controller first
388+ # (somebody please clue me in)
389+ cloud_controller = cloud.CloudController()
390+ cloud_controller.setup()
391+ _key, cert_str = self.manager._generate_x509_cert('test1',
392+ 'testproj')
393+ logging.debug(cert_str)
394+
395+ # Need to verify that it's signed by the right intermediate CA
396+ full_chain = crypto.fetch_ca(project_id='testproj', chain=True)
397+ int_cert = crypto.fetch_ca(project_id='testproj', chain=False)
398+ cloud_cert = crypto.fetch_ca()
399+ logging.debug("CA chain:\n\n =====\n%s\n\n=====" % full_chain)
400+ signed_cert = X509.load_cert_string(cert_str)
401+ chain_cert = X509.load_cert_string(full_chain)
402+ int_cert = X509.load_cert_string(int_cert)
403+ cloud_cert = X509.load_cert_string(cloud_cert)
404+ self.assertTrue(signed_cert.verify(chain_cert.get_pubkey()))
405+ self.assertTrue(signed_cert.verify(int_cert.get_pubkey()))
406+ if not FLAGS.use_intermediate_ca:
407+ self.assertTrue(signed_cert.verify(cloud_cert.get_pubkey()))
408+ else:
409+ self.assertFalse(signed_cert.verify(cloud_cert.get_pubkey()))
410+
411+ def test_adding_role_to_project_is_ignored_unless_added_to_user(self):
412+ with user_and_project_generator(self.manager) as (user, project):
413+ self.assertFalse(self.manager.has_role(user, 'sysadmin', project))
414+ self.manager.add_role(user, 'sysadmin', project)
415+ # NOTE(todd): it will still show up in get_user_roles(u, project)
416+ self.assertFalse(self.manager.has_role(user, 'sysadmin', project))
417+ self.manager.add_role(user, 'sysadmin')
418+ self.assertTrue(self.manager.has_role(user, 'sysadmin', project))
419+
420+ def test_add_user_role_doesnt_infect_project_roles(self):
421+ with user_and_project_generator(self.manager) as (user, project):
422+ self.assertFalse(self.manager.has_role(user, 'sysadmin', project))
423+ self.manager.add_role(user, 'sysadmin')
424+ self.assertFalse(self.manager.has_role(user, 'sysadmin', project))
425+
426+ def test_can_list_user_roles(self):
427+ with user_and_project_generator(self.manager) as (user, project):
428+ self.manager.add_role(user, 'sysadmin')
429+ roles = self.manager.get_user_roles(user)
430+ self.assertTrue('sysadmin' in roles)
431+ self.assertFalse('netadmin' in roles)
432+
433+ def test_can_list_project_roles(self):
434+ with user_and_project_generator(self.manager) as (user, project):
435+ self.manager.add_role(user, 'sysadmin')
436+ self.manager.add_role(user, 'sysadmin', project)
437+ self.manager.add_role(user, 'netadmin', project)
438+ project_roles = self.manager.get_user_roles(user, project)
439+ self.assertTrue('sysadmin' in project_roles)
440+ self.assertTrue('netadmin' in project_roles)
441+ # has role should be false user-level role is missing
442+ self.assertFalse(self.manager.has_role(user, 'netadmin', project))
443+
444+ def test_can_remove_user_roles(self):
445+ with user_and_project_generator(self.manager) as (user, project):
446+ self.manager.add_role(user, 'sysadmin')
447+ self.assertTrue(self.manager.has_role(user, 'sysadmin'))
448+ self.manager.remove_role(user, 'sysadmin')
449+ self.assertFalse(self.manager.has_role(user, 'sysadmin'))
450+
451+ def test_removing_user_role_hides_it_from_project(self):
452+ with user_and_project_generator(self.manager) as (user, project):
453+ self.manager.add_role(user, 'sysadmin')
454+ self.manager.add_role(user, 'sysadmin', project)
455+ self.assertTrue(self.manager.has_role(user, 'sysadmin', project))
456+ self.manager.remove_role(user, 'sysadmin')
457+ self.assertFalse(self.manager.has_role(user, 'sysadmin', project))
458+
459+ def test_can_remove_project_role_but_keep_user_role(self):
460+ with user_and_project_generator(self.manager) as (user, project):
461+ self.manager.add_role(user, 'sysadmin')
462+ self.manager.add_role(user, 'sysadmin', project)
463+ self.assertTrue(self.manager.has_role(user, 'sysadmin'))
464+ self.manager.remove_role(user, 'sysadmin', project)
465+ self.assertFalse(self.manager.has_role(user, 'sysadmin', project))
466+ self.assertTrue(self.manager.has_role(user, 'sysadmin'))
467+
468+ def test_can_retrieve_project_by_user(self):
469+ with user_and_project_generator(self.manager) as (user, project):
470+ self.assertEqual(1, len(self.manager.get_projects('test1')))
471+
472+ def test_can_modify_project(self):
473+ with user_and_project_generator(self.manager):
474+ with user_generator(self.manager, name='test2'):
475+ self.manager.modify_project('testproj', 'test2', 'new desc')
476+ project = self.manager.get_project('testproj')
477+ self.assertEqual('test2', project.project_manager_id)
478+ self.assertEqual('new desc', project.description)
479+
480+ def test_can_delete_project(self):
481+ with user_generator(self.manager):
482+ self.manager.create_project('testproj', 'test1')
483+ self.assert_(self.manager.get_project('testproj'))
484+ self.manager.delete_project('testproj')
485+ projectlist = self.manager.get_projects()
486+ self.assert_(not filter(lambda p: p.name == 'testproj',
487+ projectlist))
488+
489+ def test_can_delete_user(self):
490+ self.manager.create_user('test1')
491+ self.assert_(self.manager.get_user('test1'))
492 self.manager.delete_user('test1')
493- users = self.manager.get_users()
494- self.assertFalse(filter(lambda u: u.id == 'test1', users))
495- self.manager.delete_user('test2')
496- self.assertEqual(self.manager.get_user('test2'), None)
497+ userlist = self.manager.get_users()
498+ self.assert_(not filter(lambda u: u.id == 'test1', userlist))
499+
500+ def test_can_modify_users(self):
501+ with user_generator(self.manager):
502+ self.manager.modify_user('test1', 'access', 'secret', True)
503+ user = self.manager.get_user('test1')
504+ self.assertEqual('access', user.access)
505+ self.assertEqual('secret', user.secret)
506+ self.assertTrue(user.is_admin())
507
508
509 if __name__ == "__main__":