Update IdentityManger and FakeManager

* Add support for project description and inherited roles
* refactors the testing framework around identity
  and makes the mock data model more closely resemble
  Keystone data models

Change-Id: I13f37e53877de0bf78aca455b84dcac29aaf50e5
This commit is contained in:
Adrian Turjak 2017-10-27 20:25:44 +13:00
parent e957f1ee38
commit 1e891daf21
16 changed files with 1753 additions and 1620 deletions

View File

@ -272,14 +272,17 @@ class UserMixin(ResourceMixin):
return id_manager.find_user(self.username, self.domain_id) return id_manager.find_user(self.username, self.domain_id)
# Mutators # Mutators
def grant_roles(self, user, roles, project_id): def grant_roles(self, user, roles, project_id, inherited=False):
return self._user_roles_edit(user, roles, project_id, remove=False) return self._user_roles_edit(
user, roles, project_id, remove=False, inherited=inherited)
def remove_roles(self, user, roles, project_id): def remove_roles(self, user, roles, project_id, inherited=False):
return self._user_roles_edit(user, roles, project_id, remove=True) return self._user_roles_edit(
user, roles, project_id, remove=True, inherited=inherited)
# Helper function to add or remove roles # Helper function to add or remove roles
def _user_roles_edit(self, user, roles, project_id, remove=False): def _user_roles_edit(self, user, roles, project_id, remove=False,
inherited=False):
id_manager = user_store.IdentityManager() id_manager = user_store.IdentityManager()
if not remove: if not remove:
action_fn = id_manager.add_user_role action_fn = id_manager.add_user_role
@ -297,7 +300,7 @@ class UserMixin(ResourceMixin):
raise TypeError("Keystone missing role: %s" % role) raise TypeError("Keystone missing role: %s" % role)
for role in ks_roles: for role in ks_roles:
action_fn(user, role, project_id) action_fn(user, role, project_id, inherited=inherited)
except Exception as e: except Exception as e:
self.add_note( self.add_note(
"Error: '%s' while %s the roles: %s on user: %s " % "Error: '%s' while %s the roles: %s on user: %s " %
@ -398,10 +401,12 @@ class ProjectMixin(ResourceMixin):
def _create_project(self): def _create_project(self):
id_manager = user_store.IdentityManager() id_manager = user_store.IdentityManager()
description = getattr(self, "description", "")
try: try:
project = id_manager.create_project( project = id_manager.create_project(
self.project_name, created_on=str(timezone.now()), self.project_name, created_on=str(timezone.now()),
parent=self.parent_id, domain=self.domain_id) parent=self.parent_id, domain=self.domain_id,
description=description)
except Exception as e: except Exception as e:
self.add_note( self.add_note(
"Error: '%s' while creating project: %s" % "Error: '%s' while creating project: %s" %

View File

@ -16,7 +16,8 @@ from django.conf import settings
from adjutant.actions.v1 import serializers from adjutant.actions.v1 import serializers
from adjutant.actions.v1.projects import ( from adjutant.actions.v1.projects import (
NewProjectWithUserAction, AddDefaultUsersToProjectAction) NewProjectWithUserAction, NewProjectAction,
AddDefaultUsersToProjectAction)
from adjutant.actions.v1.users import ( from adjutant.actions.v1.users import (
EditUserRolesAction, NewUserAction, ResetUserPasswordAction, EditUserRolesAction, NewUserAction, ResetUserPasswordAction,
UpdateUserEmailAction) UpdateUserEmailAction)
@ -37,6 +38,7 @@ def register_action_class(action_class, serializer_class):
# Register Project actions: # Register Project actions:
register_action_class( register_action_class(
NewProjectWithUserAction, serializers.NewProjectWithUserSerializer) NewProjectWithUserAction, serializers.NewProjectWithUserSerializer)
register_action_class(NewProjectAction, serializers.NewProjectSerializer)
register_action_class( register_action_class(
AddDefaultUsersToProjectAction, AddDefaultUsersToProjectAction,
serializers.AddDefaultUsersToProjectSerializer) serializers.AddDefaultUsersToProjectSerializer)

View File

@ -32,6 +32,7 @@ class NewProjectAction(BaseAction, ProjectMixin, UserMixin):
'domain_id', 'domain_id',
'parent_id', 'parent_id',
'project_name', 'project_name',
'description',
] ]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -46,15 +46,26 @@ class BaseUserIdSerializer(serializers.Serializer):
class NewUserSerializer(BaseUserNameSerializer): class NewUserSerializer(BaseUserNameSerializer):
roles = serializers.MultipleChoiceField(choices=role_options) roles = serializers.MultipleChoiceField(
choices=role_options, default=set)
inherited_roles = serializers.MultipleChoiceField(
choices=role_options, default=set)
project_id = serializers.CharField(max_length=64) project_id = serializers.CharField(max_length=64)
def validate(self, data):
if not data['roles'] and not data['inherited_roles']:
raise serializers.ValidationError(
"Must supply either 'roles' or 'inherited_roles', or both.")
return data
class NewProjectSerializer(serializers.Serializer): class NewProjectSerializer(serializers.Serializer):
parent_id = serializers.CharField( parent_id = serializers.CharField(
max_length=64, default=None, allow_null=True) max_length=64, default=None, allow_null=True)
project_name = serializers.CharField(max_length=64) project_name = serializers.CharField(max_length=64)
domain_id = serializers.CharField(max_length=64, default='default') domain_id = serializers.CharField(max_length=64, default='default')
description = serializers.CharField(default="", allow_blank=True)
class NewProjectWithUserSerializer(BaseUserNameSerializer): class NewProjectWithUserSerializer(BaseUserNameSerializer):
@ -70,11 +81,21 @@ class ResetUserSerializer(BaseUserNameSerializer):
class EditUserRolesSerializer(BaseUserIdSerializer): class EditUserRolesSerializer(BaseUserIdSerializer):
roles = serializers.MultipleChoiceField(choices=role_options) roles = serializers.MultipleChoiceField(
choices=role_options, default=set)
inherited_roles = serializers.MultipleChoiceField(
choices=role_options, default=set)
remove = serializers.BooleanField(default=False) remove = serializers.BooleanField(default=False)
project_id = serializers.CharField(max_length=64) project_id = serializers.CharField(max_length=64)
domain_id = serializers.CharField(max_length=64, default='default') domain_id = serializers.CharField(max_length=64, default='default')
def validate(self, data):
if not data['roles'] and not data['inherited_roles']:
raise serializers.ValidationError(
"Must supply either 'roles' or 'inherited_roles', or both.")
return data
class NewDefaultNetworkSerializer(serializers.Serializer): class NewDefaultNetworkSerializer(serializers.Serializer):
setup_network = serializers.BooleanField(default=True) setup_network = serializers.BooleanField(default=True)

View File

@ -22,7 +22,8 @@ from adjutant.actions.v1.projects import (
NewProjectAction) NewProjectAction)
from adjutant.api.models import Task from adjutant.api.models import Task
from adjutant.common.tests import fake_clients from adjutant.common.tests import fake_clients
from adjutant.common.tests.fake_clients import FakeManager, setup_temp_cache from adjutant.common.tests.fake_clients import (
FakeManager, setup_identity_cache)
from adjutant.common.tests.utils import modify_dict_settings from adjutant.common.tests.utils import modify_dict_settings
@ -38,7 +39,7 @@ class ProjectActionTests(TestCase):
user password at submit step. user password at submit step.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -59,29 +60,29 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_project = fake_clients.identity_temp_cache['new_projects'][0]
'test_project') self.assertEquals(new_project.name, 'test_project')
new_user = fake_clients.identity_temp_cache['new_users'][0]
self.assertEquals(new_user.name, 'test@example.com')
self.assertEquals(new_user.email, 'test@example.com')
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1', {'project_id': new_project.id, 'user_id': new_user.id,
'user_state': 'default'}) 'user_state': 'default'})
action.post_approve()
self.assertEquals(action.valid, True)
token_data = {'password': '123456'} token_data = {'password': '123456'}
action.submit(token_data) action.submit(token_data)
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(new_user.password, '123456')
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(new_user, new_project)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].name, sorted(roles),
'test@example.com')
self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].email,
'test@example.com')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(
sorted(project.roles["user_id_1"]),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -91,7 +92,7 @@ class ProjectActionTests(TestCase):
ensure reapprove does nothing. ensure reapprove does nothing.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -112,34 +113,40 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_project = fake_clients.identity_temp_cache['new_projects'][0]
'test_project') self.assertEquals(new_project.name, 'test_project')
new_user = fake_clients.identity_temp_cache['new_users'][0]
self.assertEquals(new_user.name, 'test@example.com')
self.assertEquals(new_user.email, 'test@example.com')
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1', {'project_id': new_project.id, 'user_id': new_user.id,
'user_state': 'default'}) 'user_state': 'default'})
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals( self.assertEqual(
fake_clients.identity_temp_cache['projects']['test_project'].name, len(fake_clients.identity_temp_cache['new_projects']), 1)
'test_project') self.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 1)
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1', {'project_id': new_project.id, 'user_id': new_user.id,
'user_state': 'default'}) 'user_state': 'default'})
token_data = {'password': '123456'} token_data = {'password': '123456'}
action.submit(token_data) action.submit(token_data)
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(new_user.password, '123456')
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(new_user, new_project)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].email, sorted(roles),
'test@example.com')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(
sorted(project.roles["user_id_1"]),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -150,7 +157,7 @@ class ProjectActionTests(TestCase):
Ensure reapprove correctly finishes. Ensure reapprove correctly finishes.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -187,11 +194,14 @@ class ProjectActionTests(TestCase):
# No roles_granted yet, but user created # No roles_granted yet, but user created
self.assertTrue("user_id" in action.action.cache) self.assertTrue("user_id" in action.action.cache)
self.assertFalse("roles_granted" in action.action.cache) self.assertFalse("roles_granted" in action.action.cache)
new_project = fake_clients.identity_temp_cache['new_projects'][0]
self.assertEquals(new_project.name, 'test_project')
new_user = fake_clients.identity_temp_cache['new_users'][0]
self.assertEquals(new_user.name, 'test@example.com')
self.assertEquals(new_user.email, 'test@example.com')
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].email, len(fake_clients.identity_temp_cache['role_assignments']), 0)
'test@example.com')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertFalse("user_id_1" in project.roles)
# And then swap back the correct function # And then swap back the correct function
action.grant_roles = old_grant_function action.grant_roles = old_grant_function
@ -205,9 +215,12 @@ class ProjectActionTests(TestCase):
action.submit(token_data) action.submit(token_data)
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project'] self.assertEquals(new_user.password, '123456')
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(new_user, new_project)
self.assertEquals( self.assertEquals(
sorted(project.roles["user_id_1"]), sorted(roles),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -216,13 +229,10 @@ class ProjectActionTests(TestCase):
Create a project for a user that already exists. Create a project for a user that already exists.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id_1' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -243,24 +253,28 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_project = fake_clients.identity_temp_cache['new_projects'][0]
'test_project') self.assertEquals(new_project.name, 'test_project')
self.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 0)
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'user_id': 'user_id_1', 'project_id': 'project_id_1', {'project_id': new_project.id, 'user_id': user.id,
'user_state': 'existing'}) 'user_state': 'existing'})
token_data = {'password': '123456'} # submit does nothing for existing
action.submit(token_data) action.submit({})
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(user.password, '123')
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users'][user.id].email, sorted(roles),
'test@example.com')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(
sorted(project.roles[user.id]),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -271,13 +285,10 @@ class ProjectActionTests(TestCase):
a user with the same name but different email address a user with the same name but different email address
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = "test_id" name="test_user", password="123", email="different@example.com")
user.name = "test_user"
user.email = "different@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -313,7 +324,7 @@ class ProjectActionTests(TestCase):
Tests when the project is removed after the post approve step. Tests when the project is removed after the post approve step.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -334,13 +345,9 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_project = fake_clients.identity_temp_cache['new_projects'][0]
'test_project') self.assertEquals(new_project.name, 'test_project')
self.assertEquals(
task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1',
'user_state': 'default'})
fake_clients.identity_temp_cache['projects'] = {} fake_clients.identity_temp_cache['projects'] = {}
@ -353,7 +360,7 @@ class ProjectActionTests(TestCase):
Tests when the user is removed after the post approve step. Tests when the user is removed after the post approve step.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -374,13 +381,10 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_user = fake_clients.identity_temp_cache['new_users'][0]
'test_project') self.assertEquals(new_user.name, 'test@example.com')
self.assertEquals( self.assertEquals(new_user.email, 'test@example.com')
task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1',
'user_state': 'default'})
fake_clients.identity_temp_cache['users'] = {} fake_clients.identity_temp_cache['users'] = {}
@ -393,15 +397,11 @@ class ProjectActionTests(TestCase):
Create a project for a user that is disabled. Create a project for a user that is disabled.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id_1' name="test@example.com", password="123", email="test@example.com",
user.name = "test@example.com" enabled=False)
user.email = "test@example.com"
user.domain = 'default'
user.enabled = False
# create disabled user setup_identity_cache(users=[user])
setup_temp_cache({}, {user.id: user})
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -423,13 +423,17 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_project = fake_clients.identity_temp_cache['new_projects'][0]
'test_project') self.assertEquals(new_project.name, 'test_project')
self.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 0)
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'user_id': 'user_id_1', {'user_id': user.id,
'project_id': 'project_id_1', 'project_id': new_project.id,
'user_state': 'disabled'}) 'user_state': 'disabled'})
self.assertEquals( self.assertEquals(
action.action.cache["token_fields"], action.action.cache["token_fields"],
@ -440,18 +444,17 @@ class ProjectActionTests(TestCase):
action.submit(token_data) action.submit(token_data)
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
# check that user has been created correctly self.assertEquals(user.password, '123456')
self.assertEquals(
fake_clients.identity_temp_cache['users'][user.id].email, # check that user has been enabled correctly
'test@example.com') self.assertEquals(user.email, 'test@example.com')
self.assertEquals( self.assertEquals(user.enabled, True)
fake_clients.identity_temp_cache['users'][user.id].enabled,
True)
# Check user has correct roles in new project # Check user has correct roles in new project
project = fake_clients.identity_temp_cache['projects']['test_project'] fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals( self.assertEquals(
sorted(project.roles[user.id]), sorted(roles),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -464,7 +467,7 @@ class ProjectActionTests(TestCase):
""" """
# Start with nothing created # Start with nothing created
setup_temp_cache({}, {}) setup_identity_cache()
# Sign up for the project+user, validate. # Sign up for the project+user, validate.
task = Task.objects.create( task = Task.objects.create(
@ -485,8 +488,8 @@ class ProjectActionTests(TestCase):
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
# Create the disabled user directly with the Identity Manager. # Create the disabled user directly with the Identity Manager.
fm = FakeManager() fake_client = fake_clients.FakeManager()
user = fm.create_user( user = fake_client.create_user(
name="test@example.com", name="test@example.com",
password='origpass', password='origpass',
email="test@example.com", email="test@example.com",
@ -494,19 +497,22 @@ class ProjectActionTests(TestCase):
domain='default', domain='default',
default_project=None default_project=None
) )
fm.disable_user(user.id) fake_client.disable_user(user.id)
# approve previous signup # approve previous signup
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals( new_project = fake_clients.identity_temp_cache['new_projects'][0]
project.name, self.assertEquals(new_project.name, 'test_project')
'test_project')
self.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 1)
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'user_id': user.id, {'user_id': user.id,
'project_id': project.id, 'project_id': new_project.id,
'user_state': 'disabled'}) 'user_state': 'disabled'})
# check that user has been re-enabled with a generated password. # check that user has been re-enabled with a generated password.
@ -521,18 +527,21 @@ class ProjectActionTests(TestCase):
# Ensure user has new password: # Ensure user has new password:
self.assertEquals(user.password, '123456') self.assertEquals(user.password, '123456')
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals(
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
def test_new_project_existing_project(self): def test_new_project_existing_project(self):
""" """
Create a project that already exists. Create a project that already exists.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({project.name: project}, {}) setup_identity_cache(projects=[project])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -560,7 +569,7 @@ class ProjectActionTests(TestCase):
def test_new_project_invalid_domain_id(self): def test_new_project_invalid_domain_id(self):
""" Create a project using an invalid domain """ """ Create a project using an invalid domain """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -594,7 +603,7 @@ class ProjectActionTests(TestCase):
user password at submit step. user password at submit step.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
@ -616,26 +625,29 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name, new_project = fake_clients.identity_temp_cache['new_projects'][0]
'test_project') self.assertEquals(new_project.name, 'test_project')
new_user = fake_clients.identity_temp_cache['new_users'][0]
self.assertEquals(new_user.name, 'test_user')
self.assertEquals(new_user.email, 'test@example.com')
self.assertEquals( self.assertEquals(
task.cache, task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1', {'project_id': new_project.id, 'user_id': new_user.id,
'user_state': 'default'}) 'user_state': 'default'})
token_data = {'password': '123456'} token_data = {'password': '123456'}
action.submit(token_data) action.submit(token_data)
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(new_user.password, '123456')
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(new_user, new_project)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].email, sorted(roles),
'test@example.com')
self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].name,
'test_user')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(
sorted(project.roles["user_id_1"]),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -653,18 +665,14 @@ class ProjectActionTests(TestCase):
default_users = ['admin'] default_users = ['admin']
default_roles = ['admin'] default_roles = ['admin']
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", keystone_user={'roles': ['admin']}) ip_address="0.0.0.0", keystone_user={'roles': ['admin']})
task.cache = {'project_id': "test_project_id"} task.cache = {'project_id': project.id}
action = AddDefaultUsersToProjectAction( action = AddDefaultUsersToProjectAction(
{'domain_id': 'default'}, task=task, order=1) {'domain_id': 'default'}, task=task, order=1)
@ -675,8 +683,10 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project'] fake_client = fake_clients.FakeManager()
self.assertEquals(project.roles['user_id_0'], ['admin']) user = fake_client.find_user('admin', 'default')
roles = fake_client._get_roles_as_names(user, project)
self.assertEquals(roles, ['admin'])
def test_add_default_users_invalid_project(self): def test_add_default_users_invalid_project(self):
"""Add default users to a project that doesn't exist. """Add default users to a project that doesn't exist.
@ -684,13 +694,7 @@ class ProjectActionTests(TestCase):
Action should become invalid at the post_approve state, it's ok if Action should become invalid at the post_approve state, it's ok if
the project isn't created yet during pre_approve. the project isn't created yet during pre_approve.
""" """
project = mock.Mock() setup_identity_cache()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", keystone_user={'roles': ['admin']}) ip_address="0.0.0.0", keystone_user={'roles': ['admin']})
@ -716,18 +720,14 @@ class ProjectActionTests(TestCase):
""" """
Ensure nothing happens or changes during rerun of approve. Ensure nothing happens or changes during rerun of approve.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", keystone_user={'roles': ['admin']}) ip_address="0.0.0.0", keystone_user={'roles': ['admin']})
task.cache = {'project_id': "test_project_id"} task.cache = {'project_id': project.id}
action = AddDefaultUsersToProjectAction( action = AddDefaultUsersToProjectAction(
{'domain_id': 'default'}, task=task, order=1) {'domain_id': 'default'}, task=task, order=1)
@ -738,41 +738,40 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project'] fake_client = fake_clients.FakeManager()
self.assertEquals(project.roles['user_id_0'], ['admin']) user = fake_client.find_user('admin', 'default')
roles = fake_client._get_roles_as_names(user, project)
self.assertEquals(roles, ['admin'])
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project'] roles = fake_client._get_roles_as_names(user, project)
self.assertEquals(project.roles['user_id_0'], ['admin']) self.assertEquals(roles, ['admin'])
def test_new_project_action(self): def test_new_project_action(self):
""" """
Tests the new project action for an existing user. Tests the new project action for an existing user.
""" """
user = mock.Mock() project = fake_clients.FakeProject(name="parent_project")
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = mock.Mock() user = fake_clients.FakeUser(
project.id = "parent_project" name="test@example.com", password="123", email="test@example.com")
project.domain = "default"
setup_temp_cache({project.id: project}, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id", keystone_user={"user_id": user.id,
"project_id": "parent_project", "project_id": project.id,
"project_domain_id": 'default'}) "project_domain_id": 'default'})
data = { data = {
'domain_id': 'default', 'domain_id': 'default',
'parent_id': "parent_project", 'parent_id': project.id,
'project_name': 'test_project', 'project_name': 'test_project',
'description': '',
} }
action = NewProjectAction(data, task=task, order=1) action = NewProjectAction(data, task=task, order=1)
@ -782,17 +781,15 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEquals( new_project = fake_clients.identity_temp_cache['new_projects'][0]
fake_clients.identity_temp_cache['projects'][ self.assertEquals(new_project.name, 'test_project')
'test_project'].parent, 'parent_project') self.assertEquals(new_project.parent_id, project.id)
project = fake_clients.identity_temp_cache['projects']['test_project'] fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals( self.assertEquals(
sorted(project.roles["test_user_id"]), sorted(roles),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -801,30 +798,28 @@ class ProjectActionTests(TestCase):
def test_new_project_action_rerun_post_approve(self): def test_new_project_action_rerun_post_approve(self):
""" """
Tests the new project action for an existing user. Tests the new project action for an existing user does
nothing on reapproval.
""" """
user = mock.Mock() project = fake_clients.FakeProject(name="parent_project")
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = mock.Mock() user = fake_clients.FakeUser(
project.id = "parent_project" name="test@example.com", password="123", email="test@example.com")
project.domain = "default"
setup_temp_cache({project.id: project}, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id", keystone_user={"user_id": user.id,
"project_id": "parent_project", "project_id": project.id,
"project_domain_id": 'default'}) "project_domain_id": 'default'})
data = { data = {
'domain_id': 'default', 'domain_id': 'default',
'parent_id': "parent_project", 'parent_id': project.id,
'project_name': 'test_project', 'project_name': 'test_project',
'description': '',
} }
action = NewProjectAction(data, task=task, order=1) action = NewProjectAction(data, task=task, order=1)
@ -834,28 +829,28 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
new_project = fake_clients.identity_temp_cache['new_projects'][0]
self.assertEquals(new_project.name, 'test_project')
self.assertEquals(new_project.parent_id, project.id)
fake_client = fake_clients.FakeManager()
roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache[ sorted(roles),
'projects']['test_project'].parent, 'parent_project') sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
action.post_approve() action.post_approve()
# Nothing should change # Nothing should change
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEquals( self.assertEquals(new_project.name, 'test_project')
fake_clients.identity_temp_cache[ self.assertEquals(new_project.parent_id, project.id)
'projects']['test_project'].parent, 'parent_project')
project = fake_clients.identity_temp_cache['projects']['test_project'] roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals( self.assertEquals(
sorted(project.roles["test_user_id"]), sorted(roles),
sorted(['_member_', 'project_admin', sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner'])) 'project_mod', 'heat_stack_owner']))
@ -868,27 +863,24 @@ class ProjectActionTests(TestCase):
as the current user's project id as the current user's project id
""" """
user = mock.Mock() project = fake_clients.FakeProject(name="parent_project")
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = mock.Mock() user = fake_clients.FakeUser(
project.id = "parent_project" name="test@example.com", password="123", email="test@example.com")
project.domain = "default"
setup_temp_cache({project.id: project}, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id", keystone_user={"user_id": user.id,
"project_id": "not_parent_project", "project_id": project.id,
"project_domain_id": 'default'}) "project_domain_id": 'default'})
data = { data = {
'domain_id': 'default', 'domain_id': 'default',
'parent_id': "parent_project", 'parent_id': "not_parent_project_id",
'project_name': 'test_project', 'project_name': 'test_project',
'description': '',
} }
action = NewProjectAction(data, task=task, order=1) action = NewProjectAction(data, task=task, order=1)
@ -908,27 +900,24 @@ class ProjectActionTests(TestCase):
as the current user's domain id as the current user's domain id
""" """
user = mock.Mock() project = fake_clients.FakeProject(name="parent_project")
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = mock.Mock() user = fake_clients.FakeUser(
project.id = "parent_project" name="test@example.com", password="123", email="test@example.com")
project.domain = "default"
setup_temp_cache({project.id: project}, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id", keystone_user={"user_id": user.id,
"project_id": "parent_project", "project_id": project.id,
"project_domain_id": 'default'}) "project_domain_id": 'default'})
data = { data = {
'domain_id': 'notdefault', 'domain_id': 'notdefault',
'parent_id': "parent_project", 'parent_id': project.id,
'project_name': 'test_project', 'project_name': 'test_project',
'description': '',
} }
action = NewProjectAction(data, task=task, order=1) action = NewProjectAction(data, task=task, order=1)
@ -947,27 +936,24 @@ class ProjectActionTests(TestCase):
New project action where there is no specified parent id New project action where there is no specified parent id
""" """
user = mock.Mock() project = fake_clients.FakeProject(name="parent_project")
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = mock.Mock() user = fake_clients.FakeUser(
project.id = "parent_project" name="test@example.com", password="123", email="test@example.com")
project.domain = "default"
setup_temp_cache({project.id: project}, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create( task = Task.objects.create(
ip_address="0.0.0.0", ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id", keystone_user={"user_id": user.id,
"project_id": "parent_project", "project_id": project.id,
"project_domain_id": 'default'}) "project_domain_id": 'default'})
data = { data = {
'domain_id': 'default', 'domain_id': 'default',
'parent_id': None, 'parent_id': None,
'project_name': 'test_project', 'project_name': 'test_project',
'description': '',
} }
action = NewProjectAction(data, task=task, order=1) action = NewProjectAction(data, task=task, order=1)
@ -978,9 +964,9 @@ class ProjectActionTests(TestCase):
action.post_approve() action.post_approve()
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)
self.assertEquals( new_project = fake_clients.identity_temp_cache['new_projects'][0]
fake_clients.identity_temp_cache[ self.assertEquals(new_project.name, 'test_project')
'projects']['test_project'].parent, 'default') self.assertEquals(new_project.parent_id, None)
action.submit({}) action.submit({})
self.assertEquals(action.valid, True) self.assertEquals(action.valid, True)

View File

@ -23,7 +23,7 @@ from adjutant.actions.v1.resources import (
from adjutant.api.models import Task from adjutant.api.models import Task
from adjutant.common.tests.utils import modify_dict_settings from adjutant.common.tests.utils import modify_dict_settings
from adjutant.common.tests.fake_clients import ( from adjutant.common.tests.fake_clients import (
FakeManager, setup_temp_cache, get_fake_neutron, get_fake_novaclient, FakeManager, setup_identity_cache, get_fake_neutron, get_fake_novaclient,
get_fake_cinderclient, setup_neutron_cache, neutron_cache, cinder_cache, get_fake_cinderclient, setup_neutron_cache, neutron_cache, cinder_cache,
nova_cache, setup_mock_caches) nova_cache, setup_mock_caches)
@ -61,7 +61,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
data = { data = {
'setup_network': True, 'setup_network': True,
@ -111,7 +111,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
data = { data = {
'setup_network': False, 'setup_network': False,
@ -156,7 +156,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
data = { data = {
'setup_network': True, 'setup_network': True,
@ -248,7 +248,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
task.cache = {'project_id': "test_project_id"} task.cache = {'project_id': "test_project_id"}
@ -330,7 +330,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
task.cache = {'project_id': "test_project_id"} task.cache = {'project_id': "test_project_id"}
@ -377,7 +377,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
task.cache = {'project_id': "test_project_id"} task.cache = {'project_id': "test_project_id"}
@ -429,7 +429,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default' project.domain = 'default'
project.roles = {} project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
setup_mock_caches('RegionOne', 'test_project_id') setup_mock_caches('RegionOne', 'test_project_id')
task = Task.objects.create( task = Task.objects.create(
@ -489,11 +489,6 @@ class ProjectSetupActionTests(TestCase):
get_fake_cinderclient) get_fake_cinderclient)
class QuotaActionTests(TestCase): class QuotaActionTests(TestCase):
def tearDown(self):
cinder_cache.clear()
nova_cache.clear()
neutron_cache.clear()
def test_update_quota(self): def test_update_quota(self):
""" """
Sets a new quota on all services of a project in a single region Sets a new quota on all services of a project in a single region
@ -511,7 +506,7 @@ class QuotaActionTests(TestCase):
user.domain = 'default' user.domain = 'default'
user.password = "test_password" user.password = "test_password"
setup_temp_cache({'test_project': project, }, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
setup_neutron_cache('RegionOne', 'test_project_id') setup_neutron_cache('RegionOne', 'test_project_id')
# Test sending to only a single region # Test sending to only a single region
@ -559,7 +554,7 @@ class QuotaActionTests(TestCase):
user.domain = 'default' user.domain = 'default'
user.password = "test_password" user.password = "test_password"
setup_temp_cache({'test_project': project, }, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
setup_mock_caches('RegionOne', project.id) setup_mock_caches('RegionOne', project.id)
setup_mock_caches('RegionTwo', project.id) setup_mock_caches('RegionTwo', project.id)
@ -618,7 +613,7 @@ class QuotaActionTests(TestCase):
user.domain = 'default' user.domain = 'default'
user.password = "test_password" user.password = "test_password"
setup_temp_cache({'test_project': project, }, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
setup_mock_caches('RegionOne', project.id) setup_mock_caches('RegionOne', project.id)
setup_mock_caches('RegionTwo', project.id) setup_mock_caches('RegionTwo', project.id)

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
'email', 'email',
'project_id', 'project_id',
'roles', 'roles',
'inherited_roles',
'domain_id', 'domain_id',
] ]
@ -116,6 +117,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
# default action: Create a new user in the tenant and add roles # default action: Create a new user in the tenant and add roles
user = self.create_user(token_data['password']) user = self.create_user(token_data['password'])
self.grant_roles(user, self.roles, self.project_id) self.grant_roles(user, self.roles, self.project_id)
self.grant_roles(user, self.inherited_roles, self.project_id, True)
self.add_note( self.add_note(
'User %s has been created, with roles %s in project %s.' 'User %s has been created, with roles %s in project %s.'
@ -126,6 +128,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
user = self.find_user() user = self.find_user()
self.enable_user(user) self.enable_user(user)
self.grant_roles(user, self.roles, self.project_id) self.grant_roles(user, self.roles, self.project_id)
self.grant_roles(user, self.inherited_roles, self.project_id, True)
self.update_password(token_data['password']) self.update_password(token_data['password'])
self.add_note('User %s password has been changed.' % self.username) self.add_note('User %s password has been changed.' % self.username)
@ -139,6 +142,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
# Existing action: only add roles. # Existing action: only add roles.
user = self.find_user() user = self.find_user()
self.grant_roles(user, self.roles, self.project_id) self.grant_roles(user, self.roles, self.project_id)
self.grant_roles(user, self.inherited_roles, self.project_id, True)
self.add_note( self.add_note(
'Existing user %s has been given roles %s in project %s.' 'Existing user %s has been given roles %s in project %s.'
@ -187,7 +191,7 @@ class ResetUserPasswordAction(UserNameAction, UserMixin):
# NOTE(adriant): We only need to check the USERNAME_IS_EMAIL=False # NOTE(adriant): We only need to check the USERNAME_IS_EMAIL=False
# case since '_validate_username_exists' will ensure the True case # case since '_validate_username_exists' will ensure the True case
if not settings.USERNAME_IS_EMAIL: if not settings.USERNAME_IS_EMAIL:
if self.user.email.lower() != self.email.lower(): if self.user and self.user.email.lower() != self.email.lower():
self.add_note('Existing user with non-matching email.') self.add_note('Existing user with non-matching email.')
return False return False
@ -234,6 +238,7 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
'project_id', 'project_id',
'user_id', 'user_id',
'roles', 'roles',
'inherited_roles',
'remove' 'remove'
] ]
@ -251,35 +256,35 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
project = id_manager.get_project(self.project_id) project = id_manager.get_project(self.project_id)
# user roles # user roles
current_roles = id_manager.get_roles(user, project) current_roles = id_manager.get_roles(user, project)
current_role_names = {role.name for role in current_roles} current_inherited_roles = id_manager.get_roles(
user, project, inherited=True)
# NOTE(adriant): Only allow someone to edit roles if all roles from current_roles = {role.name for role in current_roles}
# the target user can be managed by editor. current_inherited_roles = {
can_manage_roles = user_store.get_managable_roles( role.name for role in current_inherited_roles}
self.action.task.keystone_user['roles'])
if not set(can_manage_roles).issuperset(current_role_names):
self.add_note(
'Not all target user roles are manageable.')
return False
if self.remove: if self.remove:
remaining = set(current_role_names) & set(self.roles) remaining = set(current_roles) & set(self.roles)
if not remaining: remaining_inherited = (
set(current_inherited_roles) & set(self.inherited_roles))
if not remaining and not remaining_inherited:
self.action.state = "complete" self.action.state = "complete"
self.add_note( self.add_note(
"User doesn't have roles to remove.") "User doesn't have roles to remove.")
else: else:
self.roles = list(remaining) self.roles = list(remaining)
self.inherited_roles = list(remaining_inherited)
self.add_note( self.add_note(
'User has roles to remove.') 'User has roles to remove.')
else: else:
missing = set(self.roles) - set(current_role_names) missing = set(self.roles) - set(current_roles)
if not missing: missing_inherited = (
set(self.inherited_roles) - set(current_inherited_roles))
if not missing and not missing_inherited:
self.action.state = "complete" self.action.state = "complete"
self.add_note( self.add_note(
'User already has roles.') 'User already has roles.')
else: else:
self.roles = list(missing) self.roles = list(missing)
self.inherited_roles = list(missing_inherited)
self.add_note( self.add_note(
'User user missing roles.') 'User user missing roles.')
# All paths are valid here # All paths are valid here
@ -314,23 +319,34 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
user = self._get_target_user() user = self._get_target_user()
self._user_roles_edit(user, self.roles, self.project_id, self._user_roles_edit(user, self.roles, self.project_id,
remove=self.remove) remove=self.remove)
self._user_roles_edit(user, self.inherited_roles, self.project_id,
remove=self.remove, inherited=True)
if self.remove: if self.remove and self.roles:
self.add_note( self.add_note(
'User %s has had roles %s removed from project %s.' 'User %s has had roles %s removed from project %s.'
% (self.user_id, self.roles, self.project_id)) % (self.user_id, self.roles, self.project_id))
else: if self.remove and self.inherited_roles:
self.add_note(
'User %s has had inherited roles %s '
'removed from project %s.'
% (self.user_id, self.inherited_roles, self.project_id))
if self.roles:
self.add_note( self.add_note(
'User %s has been given roles %s in project %s.' 'User %s has been given roles %s in project %s.'
% (self.user_id, self.roles, self.project_id)) % (self.user_id, self.roles, self.project_id))
if self.inherited_roles:
self.add_note(
'User %s has been given inherited roles %s in project %s.'
% (self.user_id, self.inherited_roles, self.project_id))
elif self.action.state == "complete": elif self.action.state == "complete":
if self.remove: if self.remove:
self.add_note( self.add_note(
'User %s already had roles %s in project %s.' "User %s didn't have roles %s in project %s."
% (self.user_id, self.roles, self.project_id)) % (self.user_id, self.roles, self.project_id))
else: else:
self.add_note( self.add_note(
"User %s didn't have roles %s in project %s." 'User %s already had roles %s in project %s.'
% (self.user_id, self.roles, self.project_id)) % (self.user_id, self.roles, self.project_id))
@ -357,6 +373,7 @@ class UpdateUserEmailAction(UserIdAction, UserMixin):
self.user = self._get_target_user() self.user = self._get_target_user()
if self.user: if self.user:
return True return True
self.add_note("Unable to find target user.")
return False return False
def _validate_email_not_in_use(self): def _validate_email_not_in_use(self):

View File

@ -53,6 +53,14 @@ class UserList(tasks.InviteUser):
roles.append(role.name) roles.append(role.name)
if skip: if skip:
continue continue
inherited_roles = []
for role in user.inherited_roles:
if role.name in role_blacklist:
skip = True
continue
inherited_roles.append(role.name)
if skip:
continue
email = getattr(user, 'email', '') email = getattr(user, 'email', '')
enabled = getattr(user, 'enabled') enabled = getattr(user, 'enabled')
@ -63,11 +71,36 @@ class UserList(tasks.InviteUser):
'name': user.name, 'name': user.name,
'email': email, 'email': email,
'roles': roles, 'roles': roles,
'inherited_roles': inherited_roles,
'cohort': 'Member', 'cohort': 'Member',
'status': user_status, 'status': user_status,
'manageable': set(can_manage_roles).issuperset(roles), 'manageable': set(can_manage_roles).issuperset(roles),
}) })
for user in id_manager.list_inherited_users(project):
skip = False
roles = []
for role in user.roles:
if role.name in role_blacklist:
skip = True
continue
roles.append(role.name)
if skip:
continue
email = getattr(user, 'email', '')
enabled = getattr(user, 'enabled')
user_status = 'Active' if enabled else 'Account Disabled'
user_list.append({'id': user.id,
'name': user.name,
'email': email,
'roles': roles,
'inherited_roles': [],
'cohort': 'Inherited',
'status': user_status,
'manageable': False,
})
# Get my active tasks for this project: # Get my active tasks for this project:
project_tasks = models.Task.objects.filter( project_tasks = models.Task.objects.filter(
project_id=project_id, project_id=project_id,
@ -98,12 +131,16 @@ class UserList(tasks.InviteUser):
# than it helps. May uncomment once different duplication checking # than it helps. May uncomment once different duplication checking
# measures are in place. # measures are in place.
# if task['task_data']['email'] not in active_emails: # if task['task_data']['email'] not in active_emails:
user = {'id': task['uuid'], user = {
'name': task['task_data']['email'], 'id': task['uuid'],
'email': task['task_data']['email'], 'name': task['task_data']['email'],
'roles': task['task_data']['roles'], 'email': task['task_data']['email'],
'cohort': 'Invited', 'roles': task['task_data']['roles'],
'status': task['status']} 'inherited_roles':
task['task_data']['inherited_roles'],
'cohort': 'Invited',
'status': task['status']
}
if not settings.USERNAME_IS_EMAIL: if not settings.USERNAME_IS_EMAIL:
user['name'] = task['task_data']['username'] user['name'] = task['task_data']['username']
@ -137,13 +174,18 @@ class UserDetail(tasks.TaskView):
roles = [role.name for role in id_manager.get_roles(user, project)] roles = [role.name for role in id_manager.get_roles(user, project)]
roles_blacklisted = set(role_blacklist) & set(roles) roles_blacklisted = set(role_blacklist) & set(roles)
inherited_roles = [
role.name for role in id_manager.get_roles(user, project, True)]
inherited_roles_blacklisted = (
set(role_blacklist) & set(inherited_roles))
if not roles or roles_blacklisted: if not roles or roles_blacklisted or inherited_roles_blacklisted:
return Response(no_user, status=404) return Response(no_user, status=404)
return Response({'id': user.id, return Response({'id': user.id,
"username": user.name, "username": user.name,
"email": getattr(user, 'email', ''), "email": getattr(user, 'email', ''),
'roles': roles}) 'roles': roles,
'inherited_roles': inherited_roles})
@utils.mod_or_admin @utils.mod_or_admin
def delete(self, request, user_id): def delete(self, request, user_id):
@ -185,12 +227,29 @@ class UserRoles(tasks.TaskView):
""" Get role info based on the user id. """ """ Get role info based on the user id. """
id_manager = user_store.IdentityManager() id_manager = user_store.IdentityManager()
user = id_manager.get_user(user_id) user = id_manager.get_user(user_id)
no_user = {'errors': ['No user with this id.']}
if not user:
return Response(no_user, status=404)
project_id = request.keystone_user['project_id'] project_id = request.keystone_user['project_id']
project = id_manager.get_project(project_id) project = id_manager.get_project(project_id)
roles = []
for role in id_manager.get_roles(user, project): class_conf = settings.TASK_SETTINGS.get(
roles.append(role.to_dict()) self.task_type, settings.DEFAULT_TASK_SETTINGS)
return Response({"roles": roles}) role_blacklist = class_conf.get('role_blacklist', [])
roles = [role.name for role in id_manager.get_roles(user, project)]
roles_blacklisted = set(role_blacklist) & set(roles)
inherited_roles = [
role.name for role in id_manager.get_roles(user, project, True)]
inherited_roles_blacklisted = (
set(role_blacklist) & set(inherited_roles))
if not roles or roles_blacklisted or inherited_roles_blacklisted:
return Response(no_user, status=404)
return Response({'roles': roles,
'inherited_roles': inherited_roles})
@utils.mod_or_admin @utils.mod_or_admin
def put(self, args, **kwargs): def put(self, args, **kwargs):

View File

@ -27,7 +27,9 @@ from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from adjutant.api.models import Task, Token, Notification from adjutant.api.models import Task, Token, Notification
from adjutant.common.tests.fake_clients import FakeManager, setup_temp_cache from adjutant.common.tests import fake_clients
from adjutant.common.tests.fake_clients import (
FakeManager, setup_identity_cache)
from adjutant.common.tests.utils import modify_dict_settings from adjutant.common.tests.utils import modify_dict_settings
@ -65,7 +67,7 @@ class AdminAPITests(APITestCase):
""" """
Test the basic task detail view. Test the basic task detail view.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -126,14 +128,10 @@ class AdminAPITests(APITestCase):
Expired token should do nothing, then delete itself. Expired token should do nothing, then delete itself.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -160,14 +158,10 @@ class AdminAPITests(APITestCase):
Expired token should do nothing, then delete itself. Expired token should do nothing, then delete itself.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -193,14 +187,10 @@ class AdminAPITests(APITestCase):
Token should contain actions, task_type, required fields. Token should contain actions, task_type, required fields.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -222,28 +212,27 @@ class AdminAPITests(APITestCase):
self.assertEqual(1, Token.objects.count()) self.assertEqual(1, Token.objects.count())
def test_token_list_get(self): def test_token_list_get(self):
user = mock.Mock() """
user.id = 'user_id' Create two password resets, then confirm we can list tokens.
user.name = "test@example.com" """
user.email = "test@example.com" user = fake_clients.FakeUser(
user.domain = 'default' name="test@example.com", password="123", email="test@example.com")
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) user2 = fake_clients.FakeUser(
name="test2@example.com", password="123",
email="test2@example.com")
setup_identity_cache(users=[user, user2])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
response = self.client.post(url, data, format='json') response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
response.data['notes'],
['If user with email exists, reset token will be issued.'])
data = {'email': "test2@example.com"}
response = self.client.post(url, data, format='json') response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
first_task_id = Task.objects.all()[0].uuid
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': "test_project_id",
@ -256,16 +245,19 @@ class AdminAPITests(APITestCase):
response = self.client.get(url, headers=headers) response = self.client.get(url, headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual( self.assertEqual(len(response.json()['tokens']), 2)
len(response.json()['tokens']), 2)
self.assertEqual(response.json()['tokens'][1]['task'], task_ids = [t.uuid for t in Task.objects.all()]
first_task_id)
token_task_ids = [t['task'] for t in response.json()['tokens']]
self.assertEqual(sorted(task_ids), sorted(token_task_ids))
def test_task_complete(self): def test_task_complete(self):
""" """
Can't approve a completed task. Can't approve a completed task.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -297,7 +289,7 @@ class AdminAPITests(APITestCase):
and error notifcations and error notifcations
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -358,13 +350,9 @@ class AdminAPITests(APITestCase):
Updates it and attempts to reapprove. Updates it and attempts to reapprove.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -409,7 +397,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you can get details of an induvidual notfication. Test that you can get details of an induvidual notfication.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -444,7 +432,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you get a 404 trying to access a non-existent notification. Test that you get a 404 trying to access a non-existent notification.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
@ -466,7 +454,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you can acknowledge a notification. Test that you can acknowledge a notification.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -513,7 +501,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you cant acknowledge a non-existent notification. Test that you cant acknowledge a non-existent notification.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
@ -535,7 +523,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you cant reacknowledge a notification. Test that you cant reacknowledge a notification.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -568,7 +556,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you have to include 'acknowledged': True to the request. Test that you have to include 'acknowledged': True to the request.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -596,7 +584,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you can acknowledge a list of notifications. Test that you can acknowledge a list of notifications.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -641,7 +629,7 @@ class AdminAPITests(APITestCase):
""" """
Test that you cannot acknowledge an empty list of notifications. Test that you cannot acknowledge an empty list of notifications.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
@ -693,7 +681,7 @@ class AdminAPITests(APITestCase):
""" """
Tests the email notification engine Tests the email notification engine
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -727,21 +715,14 @@ class AdminAPITests(APITestCase):
test deleting of expired tokens. test deleting of expired tokens.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user2 = mock.Mock() user2 = fake_clients.FakeUser(
user2.id = 'user_id2' name="test2@example.com", password="123",
user2.name = "test2@example.com" email="test2@example.com")
user2.email = "test2@example.com"
user2.domain = 'default'
user2.password = "test_password"
setup_temp_cache({}, {user.id: user, user2.name: user2}) setup_identity_cache(users=[user, user2])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -787,14 +768,10 @@ class AdminAPITests(APITestCase):
test for reissue of tokens test for reissue of tokens
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -833,25 +810,21 @@ class AdminAPITests(APITestCase):
test for reissue of tokens for non-admin test for reissue of tokens for non-admin
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -885,14 +858,10 @@ class AdminAPITests(APITestCase):
Tests that a cancelled task cannot have a token reissued Tests that a cancelled task cannot have a token reissued
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -928,14 +897,10 @@ class AdminAPITests(APITestCase):
Tests that a completed task cannot have a token reissued Tests that a completed task cannot have a token reissued
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -971,7 +936,7 @@ class AdminAPITests(APITestCase):
Tests that an unapproved task cannot have a token reissued Tests that an unapproved task cannot have a token reissued
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'email': "test@example.com", "project_name": "test_project"} data = {'email': "test@example.com", "project_name": "test_project"}
@ -1003,7 +968,7 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel a task. Ensure the ability to cancel a task.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -1037,7 +1002,7 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel a task after the token is sent. Ensure the ability to cancel a task after the token is sent.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -1073,7 +1038,7 @@ class AdminAPITests(APITestCase):
Tests that a reapproved task will delete all of it's previous tokens. Tests that a reapproved task will delete all of it's previous tokens.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -1118,13 +1083,7 @@ class AdminAPITests(APITestCase):
Ensure task update doesn't work for approved actions. Ensure task update doesn't work for approved actions.
""" """
project = mock.Mock() setup_identity_cache()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({}, {})
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -1158,25 +1117,21 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel your own task. Ensure the ability to cancel your own task.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -1201,25 +1156,21 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel ONLY your own task. Ensure the ability to cancel ONLY your own task.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -1233,34 +1184,31 @@ class AdminAPITests(APITestCase):
def test_task_list(self): def test_task_list(self):
""" """
Create some user invite tasks, then make sure we can list them.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
data = {'email': "test2@example.com", 'roles': ["_member_"], data = {'email': "test2@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
data = {'email': "test3@example.com", 'roles': ["_member_"], data = {'email': "test3@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
@ -1282,33 +1230,29 @@ class AdminAPITests(APITestCase):
Test that tasks returns in the default sort. Test that tasks returns in the default sort.
The default sort is by created_on descending. The default sort is by created_on descending.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
data = {'email': "test2@example.com", 'roles': ["_member_"], data = {'email': "test2@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
data = {'email': "test3@example.com", 'roles': ["_member_"], data = {'email': "test3@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
@ -1334,29 +1278,25 @@ class AdminAPITests(APITestCase):
def test_task_list_filter(self): def test_task_list_filter(self):
""" """
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
data = {'email': "test2@example.com", 'roles': ["_member_"], data = {'email': "test2@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
@ -1418,13 +1358,13 @@ class AdminAPITests(APITestCase):
project2.domain = 'default' project2.domain = 'default'
project2.roles = {} project2.roles = {}
setup_temp_cache( setup_identity_cache(
{'test_project': project, 'test_project_2': project2}, {}) {'test_project': project, 'test_project_2': project2}, {})
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': project.name,
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "owner@example.com", 'username': "owner@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
@ -1436,8 +1376,8 @@ class AdminAPITests(APITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
headers = { headers = {
'project_name': "test_project", 'project_name': project2.name,
'project_id': "test_project_id_2", 'project_id': project2.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
@ -1459,28 +1399,8 @@ class AdminAPITests(APITestCase):
def test_task_list_filter_formating(self): def test_task_list_filter_formating(self):
""" """
Test error states for badly formatted filters.
""" """
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
'authenticated': True
}
data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
@ -1557,20 +1477,19 @@ class AdminAPITests(APITestCase):
admin user. admin user.
""" """
user = mock.Mock() project = fake_clients.FakeProject(name="test_project")
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
project = mock.Mock() user = fake_clients.FakeUser(
project.id = 'test_project_id' name="test@example.com", password="123", email="test@example.com")
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['admin']}
setup_temp_cache({'test_project': project}, {user.id: user}) assignment = fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="admin",
user={'id': user.id}
)
setup_identity_cache(
projects=[project], users=[user], role_assignments=[assignment])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,8 @@ from django.core import mail
from rest_framework import status from rest_framework import status
from adjutant.api.models import Task, Token from adjutant.api.models import Task, Token
from adjutant.common.tests.fake_clients import FakeManager, setup_temp_cache from adjutant.common.tests.fake_clients import (
FakeManager, setup_identity_cache)
from adjutant.common.tests import fake_clients from adjutant.common.tests import fake_clients
from adjutant.common.tests.utils import (AdjutantAPITestCase, from adjutant.common.tests.utils import (AdjutantAPITestCase,
modify_dict_settings) modify_dict_settings)
@ -41,31 +42,28 @@ class TaskViewTests(AdjutantAPITestCase):
Simple test to confirm the serializers are correctly processing Simple test to confirm the serializers are correctly processing
wrong data or missing fields. wrong data or missing fields.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'wrong_email_field': "test@example.com", 'roles': ["_member_"], data = {'wrong_email_field': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json(), self.assertEqual(response.json(),
{'email': ['This field is required.']}) {'email': ['This field is required.']})
data = {'email': "not_a_valid_email", 'roles': ["not_a_valid_role"], data = {'email': "not_a_valid_email", 'roles': ["not_a_valid_role"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual( self.assertEqual(
@ -78,25 +76,21 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure the new user workflow goes as expected. Ensure the new user workflow goes as expected.
Create task, create token, submit token. Create task, create token, submit token.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -111,14 +105,14 @@ class TaskViewTests(AdjutantAPITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(mail.outbox), 2) self.assertEqual(len(mail.outbox), 2)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].name, fake_clients.identity_temp_cache['new_users'][0].name,
'test@example.com') 'test@example.com')
def test_new_user_no_project(self): def test_new_user_no_project(self):
""" """
Can't create a user for a non-existent project. Can't create a user for a non-existent project.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
@ -137,9 +131,10 @@ class TaskViewTests(AdjutantAPITestCase):
def test_new_user_not_my_project(self): def test_new_user_not_my_project(self):
""" """
Can't create a user for project that isn't mine. Can't create a user for project that user isn't'
project admin or mod on.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
@ -160,7 +155,7 @@ class TaskViewTests(AdjutantAPITestCase):
Can't create a user if unauthenticated. Can't create a user if unauthenticated.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = {} headers = {}
@ -177,31 +172,24 @@ class TaskViewTests(AdjutantAPITestCase):
""" """
Adding existing user to project. Adding existing user to project.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="parent_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({'test_project': project}, {user.id: user}) setup_identity_cache(projects=[project], users=[user])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -218,31 +206,32 @@ class TaskViewTests(AdjutantAPITestCase):
Already has role. Already has role.
Should 'complete' anyway but do nothing. Should 'complete' anyway but do nothing.
""" """
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['_member_']}
setup_temp_cache({'test_project': project}, {user.id: user}) user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
assignment = fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="_member_",
user={'id': user.id}
)
setup_identity_cache(
projects=[project], users=[user], role_assignments=[assignment])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual( self.assertEqual(
@ -254,7 +243,7 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure the new project workflow goes as expected. Ensure the new project workflow goes as expected.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -279,6 +268,9 @@ class TaskViewTests(AdjutantAPITestCase):
{'notes': ['created token']} {'notes': ['created token']}
) )
new_project = fake_clients.identity_temp_cache['new_projects'][0]
self.assertEquals(new_project.name, 'test_project')
new_token = Token.objects.all()[0] new_token = Token.objects.all()[0]
url = "/v1/tokens/" + new_token.token url = "/v1/tokens/" + new_token.token
data = {'password': 'testpassword'} data = {'password': 'testpassword'}
@ -291,7 +283,7 @@ class TaskViewTests(AdjutantAPITestCase):
that the a 400 is recieved and no final emails are sent. that the a 400 is recieved and no final emails are sent.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -315,6 +307,8 @@ class TaskViewTests(AdjutantAPITestCase):
response.data, response.data,
{'notes': ['created token']} {'notes': ['created token']}
) )
self.assertEqual(len(mail.outbox), 3)
fake_clients.identity_temp_cache['projects'] = {} fake_clients.identity_temp_cache['projects'] = {}
new_token = Token.objects.all()[0] new_token = Token.objects.all()[0]
@ -322,6 +316,7 @@ class TaskViewTests(AdjutantAPITestCase):
data = {'password': 'testpassword'} data = {'password': 'testpassword'}
response = self.client.post(url, data, format='json') response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(len(mail.outbox), 3)
def test_new_project_existing(self): def test_new_project_existing(self):
""" """
@ -329,13 +324,9 @@ class TaskViewTests(AdjutantAPITestCase):
if project is already present. if project is already present.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -366,16 +357,10 @@ class TaskViewTests(AdjutantAPITestCase):
No token should be needed. No token should be needed.
""" """
# pre-create user user = fake_clients.FakeUser(
user = mock.Mock() name="test@example.com", password="123", email="test@example.com")
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache( setup_identity_cache(users=[user])
projects={},
users={user.id: user})
# unauthenticated sign up as existing user # unauthenticated sign up as existing user
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
@ -406,7 +391,7 @@ class TaskViewTests(AdjutantAPITestCase):
""" """
Project already exists but new user attempting to create it. Project already exists but new user attempting to create it.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
# create signup#1 - project1 with user 1 # create signup#1 - project1 with user 1
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
@ -455,14 +440,10 @@ class TaskViewTests(AdjutantAPITestCase):
Create task + create token, submit token. Create task + create token, submit token.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -486,14 +467,10 @@ class TaskViewTests(AdjutantAPITestCase):
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
# Submit password reset # Submit password reset
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
@ -517,7 +494,7 @@ class TaskViewTests(AdjutantAPITestCase):
data = {'password': 'new_test_password1'} data = {'password': 'new_test_password1'}
response = self.client.post(url, data, format='json') response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
self.assertEqual(user.password, 'test_password') self.assertEqual(user.password, '123')
# Now reset with the second token # Now reset with the second token
second_token = Token.objects.all()[1] second_token = Token.objects.all()[1]
@ -532,7 +509,7 @@ class TaskViewTests(AdjutantAPITestCase):
Actions should be successful, so usernames are not exposed. Actions should be successful, so usernames are not exposed.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@exampleinvalid.com"} data = {'email': "test@exampleinvalid.com"}
@ -547,7 +524,7 @@ class TaskViewTests(AdjutantAPITestCase):
CreateProject should create a notification. CreateProject should create a notification.
We should be able to grab it. We should be able to grab it.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -577,13 +554,7 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure we can't submit duplicate tasks Ensure we can't submit duplicate tasks
""" """
project = mock.Mock() setup_identity_cache()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({}, {})
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"} data = {'project_name': "test_project", 'email': "test@example.com"}
@ -600,25 +571,21 @@ class TaskViewTests(AdjutantAPITestCase):
""" """
Ensure we can't submit duplicate tasks Ensure we can't submit duplicate tasks
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'email': "test@example.com", 'roles': ["_member_"], data = {'email': "test@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -626,7 +593,7 @@ class TaskViewTests(AdjutantAPITestCase):
self.assertEqual(response.status_code, status.HTTP_409_CONFLICT) self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
data = {'email': "test2@example.com", 'roles': ["_member_"], data = {'email': "test2@example.com", 'roles': ["_member_"],
'project_id': 'test_project_id'} 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -638,14 +605,10 @@ class TaskViewTests(AdjutantAPITestCase):
Confirm that the task id is returned when admin. Confirm that the task id is returned when admin.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
@ -660,7 +623,10 @@ class TaskViewTests(AdjutantAPITestCase):
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
# make sure the task is actually valid
new_task = Task.objects.all()[0] new_task = Task.objects.all()[0]
self.assertTrue(all([a.valid for a in new_task.actions]))
self.assertEqual( self.assertEqual(
response.json()['task'], response.json()['task'],
new_task.uuid) new_task.uuid)
@ -670,14 +636,10 @@ class TaskViewTests(AdjutantAPITestCase):
Confirm that the task id is not returned unless admin. Confirm that the task id is not returned unless admin.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
@ -692,6 +654,10 @@ class TaskViewTests(AdjutantAPITestCase):
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
# make sure the task is actually valid
new_task = Task.objects.all()[0]
self.assertTrue(all([a.valid for a in new_task.actions]))
self.assertFalse(response.json().get('task')) self.assertFalse(response.json().get('task'))
def test_update_email_task(self): def test_update_email_task(self):
@ -700,13 +666,10 @@ class TaskViewTests(AdjutantAPITestCase):
Create task, create token, submit token. Create task, create token, submit token.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -714,7 +677,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id", 'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': user.id,
'authenticated': True 'authenticated': True
} }
@ -753,13 +716,10 @@ class TaskViewTests(AdjutantAPITestCase):
to send a confirmation email to the old email address it does. to send a confirmation email to the old email address it does.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -767,7 +727,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id", 'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': user.id,
'authenticated': True 'authenticated': True
} }
@ -816,13 +776,10 @@ class TaskViewTests(AdjutantAPITestCase):
email address it does. email address it does.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="nkdfslnkls", password="123", email="test@example.com")
user.name = "nkdfslnkls"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -830,7 +787,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id", 'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "nkdfslnkls", 'username': "nkdfslnkls",
'user_id': "test_user_id", 'user_id': user.id,
'authenticated': True, 'authenticated': True,
'email': 'test@example.com', 'email': 'test@example.com',
} }
@ -859,13 +816,10 @@ class TaskViewTests(AdjutantAPITestCase):
def test_update_email_task_invalid_email(self): def test_update_email_task_invalid_email(self):
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -873,7 +827,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id", 'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': user.id,
'authenticated': True 'authenticated': True
} }
@ -887,19 +841,14 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=True) @override_settings(USERNAME_IS_EMAIL=True)
def test_update_email_pre_existing_user_with_email(self): def test_update_email_pre_existing_user_with_email(self):
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user2 = mock.Mock() user2 = fake_clients.FakeUser(
user2.id = 'new_user_id' name="new_test@example.com", password="123",
user2.name = "new_test@example.com" email="new_test@example.com")
user2.email = "new_test@example.com"
user2.domain = 'default'
setup_temp_cache({}, {user.id: user, user2.id: user2}) setup_identity_cache(users=[user, user2])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -924,19 +873,14 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=False) @override_settings(USERNAME_IS_EMAIL=False)
def test_update_email_user_with_email_username_not_email(self): def test_update_email_user_with_email_username_not_email(self):
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test", password="123", email="test@example.com")
user.name = "test"
user.email = "test@example.com"
user.domain = 'Default'
user2 = mock.Mock() user2 = fake_clients.FakeUser(
user2.id = 'new_user_id' name="new_test", password="123",
user2.name = "new_test" email="new_test@example.com")
user2.email = "new_test@example.com"
user2.domain = 'Default'
setup_temp_cache({}, {user.id: user, user2.id: user}) setup_identity_cache(users=[user, user2])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -944,7 +888,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id", 'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': user.id,
'authenticated': True 'authenticated': True
} }
@ -969,13 +913,10 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure that an unauthenticated user cant access the endpoint. Ensure that an unauthenticated user cant access the endpoint.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -989,13 +930,10 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=False) @override_settings(USERNAME_IS_EMAIL=False)
def test_update_email_task_username_not_email(self): def test_update_email_task_username_not_email(self):
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test_user", password="123", email="test@example.com")
user.name = "test_user"
user.email = "test@example.com"
user.domain = 'default'
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
headers = { headers = {
@ -1003,7 +941,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id", 'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test_user", 'username': "test_user",
'user_id': "test_user_id", 'user_id': user.id,
'authenticated': True 'authenticated': True
} }
@ -1028,25 +966,21 @@ class TaskViewTests(AdjutantAPITestCase):
""" """
Invites a user where the email is different to the username. Invites a user where the email is different to the username.
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {}) setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "user", 'username': "user",
'user_id': "test_user_id", 'user_id': "test_user_id",
'authenticated': True 'authenticated': True
} }
data = {'username': 'new_user', 'email': "new@example.com", data = {'username': 'new_user', 'email': "new@example.com",
'roles': ["_member_"], 'project_id': 'test_project_id'} 'roles': ["_member_"], 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -1063,7 +997,7 @@ class TaskViewTests(AdjutantAPITestCase):
self.assertEqual(len(mail.outbox), 2) self.assertEqual(len(mail.outbox), 2)
self.assertEquals( self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].name, fake_clients.identity_temp_cache['new_users'][0].name,
'new_user') 'new_user')
@override_settings(USERNAME_IS_EMAIL=False) @override_settings(USERNAME_IS_EMAIL=False)
@ -1073,14 +1007,10 @@ class TaskViewTests(AdjutantAPITestCase):
Create task + create token, submit token. Create task + create token, submit token.
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test_user", password="123", email="test@example.com")
user.name = "test_user"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
setup_temp_cache({}, {user.id: user}) setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
# NOTE(amelia): Requiring both username and email here may be # NOTE(amelia): Requiring both username and email here may be
@ -1112,7 +1042,7 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=False) @override_settings(USERNAME_IS_EMAIL=False)
def test_new_project_username_not_email(self): def test_new_project_username_not_email(self):
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/CreateProject" url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com", data = {'project_name': "test_project", 'email': "test@example.com",
@ -1175,40 +1105,60 @@ class TaskViewTests(AdjutantAPITestCase):
# child project being created that all the project admins should be # child project being created that all the project admins should be
# notified of # notified of
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user2 = mock.Mock() user2 = fake_clients.FakeUser(
user2.id = 'test_user_id_2' name="test2@example.com", password="123",
user2.name = "test2@example.com" email="test2@example.com")
user2.email = "test2@example.com"
user2.domain = 'default'
user3 = mock.Mock() user3 = fake_clients.FakeUser(
user3.id = 'test_user_id_3' name="test3@example.com", password="123",
user3.name = "test3@example.com" email="test2@example.com")
user3.email = "test3@example.com"
user3.domain = 'default'
project.roles = {user.id: ['project_admin', '_member_'], assignments = [
user2.id: ['project_admin', '_member_'], fake_clients.FakeRoleAssignment(
user3.id: ['project_mod', '_member_']} scope={'project': {'id': project.id}},
role_name="_member_",
user={'id': user.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="project_admin",
user={'id': user.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="_member_",
user={'id': user2.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="project_admin",
user={'id': user2.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="_member_",
user={'id': user3.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="project_mod",
user={'id': user3.id}
),
]
setup_temp_cache({'test_project': project}, setup_identity_cache(
{user.id: user, user2.id: user2, user3.id: user3}) projects=[project], users=[user, user2, user3],
role_assignments=assignments)
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
@ -1216,7 +1166,7 @@ class TaskViewTests(AdjutantAPITestCase):
} }
data = {'email': "new_test@example.com", data = {'email': "new_test@example.com",
'roles': ['_member_']} 'roles': ['_member_'], 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers) response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']}) self.assertEqual(response.json(), {'notes': ['created token']})
@ -1260,25 +1210,24 @@ class TaskViewTests(AdjutantAPITestCase):
send to that the update action doesn't fall over send to that the update action doesn't fall over
""" """
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'test_user_id' name="test@example.com", password="123", email="test@example.com")
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
project.roles = {user.id: ['_member_']} assignment = fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="_member_",
user={'id': user.id}
)
setup_temp_cache({'test_project': project}, {user.id: user}) setup_identity_cache(
projects=[project], users=[user], role_assignments=[assignment])
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
@ -1324,25 +1273,31 @@ class TaskViewTests(AdjutantAPITestCase):
Tests the sending of additional emails an admin email set in Tests the sending of additional emails an admin email set in
the conf the conf
""" """
project = fake_clients.FakeProject(name="test_project")
project = mock.Mock() user = fake_clients.FakeUser(
project.id = 'test_project_id' name="test@example.com", password="123", email="test@example.com")
project.name = 'test_project'
project.domain = 'default'
user = mock.Mock() assignments = [
user.id = 'test_user_id' fake_clients.FakeRoleAssignment(
user.name = "test@example.com" scope={'project': {'id': project.id}},
user.email = "test@example.com" role_name="_member_",
user.domain = 'default' user={'id': user.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="project_admin",
user={'id': user.id}
),
]
project.roles = {user.id: ['project_admin', '_member_']} setup_identity_cache(
setup_temp_cache({'test_project': project}, {user.id: user, }) projects=[project], users=[user], role_assignments=assignments)
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "test_user_id", 'user_id': "test_user_id",
@ -1392,7 +1347,7 @@ class TaskViewTests(AdjutantAPITestCase):
action is invalid. action is invalid.
""" """
setup_temp_cache({}, {}) setup_identity_cache()
url = "/v1/actions/InviteUser" url = "/v1/actions/InviteUser"
headers = { headers = {

View File

@ -12,53 +12,125 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from uuid import uuid4
from django.conf import settings from django.conf import settings
import mock import mock
identity_temp_cache = {} identity_temp_cache = {}
neutron_cache = {} neutron_cache = {}
nova_cache = {} nova_cache = {}
cinder_cache = {} cinder_cache = {}
def setup_temp_cache(projects, users): class FakeProject(object):
default_domain = mock.Mock()
def __init__(self, name, description="",
domain_id='default', parent_id=None,
enabled=True, is_domain=False, **kwargs):
self.id = uuid4().hex
self.name = name
self.description = description
self.domain_id = domain_id
self.parent_id = parent_id
self.enabled = enabled
self.is_domain = is_domain
# handle extra values
for key, value in kwargs.items():
setattr(self, key, value)
class FakeUser(object):
def __init__(self, name, password, domain_id='default',
enabled=True, default_project_id=None, **kwargs):
self.id = uuid4().hex
self.name = name
self.password = password
self.domain_id = domain_id
self.enabled = enabled
self.default_project_id = default_project_id
# handle extra values
for key, value in kwargs.items():
setattr(self, key, value)
class FakeRole(object):
def __init__(self, name):
self.id = uuid4().hex
self.name = name
class FakeRoleAssignment(object):
def __init__(self, scope, role=None, role_name=None, user=None,
group=None, inherited=False):
if role:
self.role = role
elif role_name:
self.role = {'name': role_name}
else:
raise AttributeError("must supply 'role' or 'role_name'.")
self.scope = scope
self.user = user
self.group = group
if inherited:
self.scope['OS-INHERIT:inherited_to'] = "projects"
def __eq__(self, other):
return self.__dict__ == other.__dict__
def setup_identity_cache(projects=None, users=None, role_assignments=None,
extra_roles=[]):
if not projects:
projects = []
if not users:
users = []
if not role_assignments:
role_assignments = []
default_domain = FakeProject(
name="Default", is_domain=True)
default_domain.id = 'default' default_domain.id = 'default'
default_domain.name = 'Default'
admin_user = mock.Mock() projects.append(default_domain)
admin_user.id = 'user_id_0'
admin_user.name = 'admin'
admin_user.password = 'password'
admin_user.email = 'admin@example.com'
admin_user.domain = default_domain.id
users.update({admin_user.id: admin_user}) admin_user = FakeUser(
name="admin", password="password", email="admin@example.com",
domain_id=default_domain.id)
users.append(admin_user)
roles = [
FakeRole(name="_member_"),
FakeRole(name="admin"),
FakeRole(name="project_admin"),
FakeRole(name="project_mod"),
FakeRole(name="heat_stack_owner"),
] + extra_roles
region_one = mock.Mock() region_one = mock.Mock()
region_one.id = 'RegionOne' region_one.id = 'RegionOne'
region_one.name = 'RegionOne'
region_two = mock.Mock() region_two = mock.Mock()
region_two.id = 'RegionTwo' region_two.id = 'RegionTwo'
global identity_temp_cache global identity_temp_cache
# TODO(adriant): region and project keys are name, should be ID.
identity_temp_cache = { identity_temp_cache = {
'i': 1, 'users': {u.id: u for u in users},
'users': users, 'new_users': [],
'projects': projects, 'projects': {p.id: p for p in projects},
'roles': { 'new_projects': [],
'_member_': '_member_', 'role_assignments': role_assignments,
'admin': 'admin', 'new_role_assignments': [],
'project_admin': 'project_admin', 'roles': {r.id: r for r in roles},
'project_mod': 'project_mod',
'heat_stack_owner': 'heat_stack_owner'
},
'regions': { 'regions': {
'RegionOne': region_one, 'RegionOne': region_one,
'RegionTwo': region_two 'RegionTwo': region_two
@ -72,25 +144,25 @@ def setup_temp_cache(projects, users):
class FakeManager(object): class FakeManager(object):
def _project_from_id(self, project): def _project_from_id(self, project):
if isinstance(project, mock.Mock): if isinstance(project, FakeProject):
return project return project
else: else:
return self.get_project(project) return self.get_project(project)
def _role_from_id(self, role): def _role_from_id(self, role):
if isinstance(role, mock.Mock): if isinstance(role, FakeRole):
return role return role
else: else:
return self.get_role(role) return self.get_role(role)
def _user_from_id(self, user): def _user_from_id(self, user):
if isinstance(user, mock.Mock): if isinstance(user, FakeUser):
return user return user
else: else:
return self.get_user(user) return self.get_user(user)
def _domain_from_id(self, domain): def _domain_from_id(self, domain):
if isinstance(domain, mock.Mock): if isinstance(domain, FakeProject) and domain.is_domain:
return domain return domain
else: else:
return self.get_domain(domain) return self.get_domain(domain)
@ -99,7 +171,8 @@ class FakeManager(object):
domain = self._domain_from_id(domain) domain = self._domain_from_id(domain)
global identity_temp_cache global identity_temp_cache
for user in identity_temp_cache['users'].values(): for user in identity_temp_cache['users'].values():
if user.name.lower() == name.lower() and user.domain == domain.id: if (user.name.lower() == name.lower() and
user.domain_id == domain.id):
return user return user
return None return None
@ -110,36 +183,62 @@ class FakeManager(object):
def list_users(self, project): def list_users(self, project):
project = self._project_from_id(project) project = self._project_from_id(project)
global identity_temp_cache global identity_temp_cache
roles = identity_temp_cache['projects'][project.name].roles users = {}
users = []
for user_id, user_roles in roles.items(): for assignment in identity_temp_cache['role_assignments']:
user = self.get_user(user_id) if assignment.scope['project']['id'] == project.id:
user.roles = []
for role in user_roles: user = users.get(assignment.user['id'])
r = mock.Mock() if not user:
r.name = role user = self.get_user(assignment.user['id'])
user.roles.append(r) user.roles = []
user.inherited_roles = []
users[user.id] = user
users.append(user) r = self.find_role(assignment.role['name'])
return users
if assignment.scope.get('OS-INHERIT:inherited_to'):
user.inherited_roles.append(r)
else:
user.roles.append(r)
return users.values()
def list_inherited_users(self, project):
project = self._project_from_id(project)
global identity_temp_cache
users = {}
while project.parent_id:
project = self._project_from_id(project.parent_id)
for assignment in identity_temp_cache['role_assignments']:
if assignment.scope['project']['id'] == project.id:
if not assignment.scope.get('OS-INHERIT:inherited_to'):
continue
user = users.get(assignment.user['id'])
if not user:
user = self.get_user(assignment.user['id'])
user.roles = []
user.inherited_roles = []
users[user.id] = user
r = self.find_role(assignment.role['name'])
user.roles.append(r)
return users.values()
def create_user(self, name, password, email, created_on, def create_user(self, name, password, email, created_on,
domain='default', default_project=None): domain='default', default_project=None):
domain = self._domain_from_id(domain) domain = self._domain_from_id(domain)
default_project = self._project_from_id(default_project) default_project = self._project_from_id(default_project)
global identity_temp_cache global identity_temp_cache
user = mock.Mock() user = FakeUser(
user.id = "user_id_%s" % int(identity_temp_cache['i']) name=name, password=password, email=email,
user.name = name domain_id=domain.id, default_project=default_project)
user.password = password
user.email = email
user.domain = domain.id
user.default_project = default_project
identity_temp_cache['users'][user.id] = user identity_temp_cache['users'][user.id] = user
identity_temp_cache['new_users'].append(user)
identity_temp_cache['i'] += 0.5
return user return user
def update_user_password(self, user, password): def update_user_password(self, user, password):
@ -164,90 +263,115 @@ class FakeManager(object):
def find_role(self, name): def find_role(self, name):
global identity_temp_cache global identity_temp_cache
if identity_temp_cache['roles'].get(name, None): for role in identity_temp_cache['roles'].values():
role = mock.Mock() if role.name == name:
role.name = name return role
return role
return None return None
def get_roles(self, user, project): def get_roles(self, user, project, inherited=False):
user = self._user_from_id(user) user = self._user_from_id(user)
project = self._project_from_id(project) project = self._project_from_id(project)
try: global identity_temp_cache
roles = []
for role in project.roles[user.id]: roles = []
r = mock.Mock()
r.name = role for assignment in identity_temp_cache['role_assignments']:
if (assignment.user['id'] == user.id and
assignment.scope['project']['id'] == project.id):
if (assignment.scope.get('OS-INHERIT:inherited_to') and not
inherited) or (
inherited and not
assignment.scope.get('OS-INHERIT:inherited_to')):
continue
r = self.find_role(assignment.role['name'])
roles.append(r) roles.append(r)
return roles
except KeyError: return roles
return []
def _get_roles_as_names(self, user, project, inherited=False):
return [r.name for r in self.get_roles(user, project, inherited)]
def get_all_roles(self, user): def get_all_roles(self, user):
user = self._user_from_id(user) user = self._user_from_id(user)
global identity_temp_cache global identity_temp_cache
projects = {} projects = {}
for project in identity_temp_cache['projects'].values(): for assignment in identity_temp_cache['role_assignments']:
projects[project.id] = [] if assignment.user['id'] == user.id:
for role in project.roles[user.id]: r = self.find_role(assignment.role['name'])
r = mock.Mock() try:
r.name = role projects[assignment.scope['project']['id']].append(r)
projects[project.id].append(r) except KeyError:
projects[assignment.scope['project']['id']] = [r]
return projects return projects
def add_user_role(self, user, role, project): def _make_role_assignment(self, user, role, project, inherited=False):
user = self._user_from_id(user) scope = {
role = self._role_from_id(role) 'project': {
project = self._project_from_id(project) 'id': project.id}}
try: if inherited:
project.roles[user.id].append(role.name) scope['OS-INHERIT:inherited_to'] = "projects"
except KeyError: role_assignment = FakeRoleAssignment(
project.roles[user.id] = [role.name] scope=scope,
role={"name": role.name},
user={'id': user.id},
)
return role_assignment
def remove_user_role(self, user, role, project): def add_user_role(self, user, role, project, inherited=False):
user = self._user_from_id(user) user = self._user_from_id(user)
role = self._role_from_id(role) role = self._role_from_id(role)
project = self._project_from_id(project) project = self._project_from_id(project)
try:
project.roles[user.id].remove(role.name) role_assignment = self._make_role_assignment(user, role, project)
except KeyError:
pass global identity_temp_cache
if role_assignment not in identity_temp_cache['role_assignments']:
identity_temp_cache['role_assignments'].append(role_assignment)
identity_temp_cache['new_role_assignments'].append(role_assignment)
def remove_user_role(self, user, role, project, inherited=False):
user = self._user_from_id(user)
role = self._role_from_id(role)
project = self._project_from_id(project)
role_assignment = self._make_role_assignment(user, role, project)
global identity_temp_cache
if role_assignment in identity_temp_cache['role_assignments']:
identity_temp_cache['role_assignments'].remove(role_assignment)
def find_project(self, project_name, domain): def find_project(self, project_name, domain):
domain = self._domain_from_id(domain) domain = self._domain_from_id(domain)
global identity_temp_cache global identity_temp_cache
for project in identity_temp_cache['projects'].values(): for project in identity_temp_cache['projects'].values():
if (project.name.lower() == project_name.lower() and if (project.name.lower() == project_name.lower() and
project.domain == domain.id): project.domain_id == domain.id):
return project return project
return None return None
def get_project(self, project_id): def get_project(self, project_id, subtree_as_ids=False,
parents_as_ids=False):
global identity_temp_cache global identity_temp_cache
for project in identity_temp_cache['projects'].values(): return identity_temp_cache['projects'].get(project_id, None)
if project.id == project_id:
return project
def create_project(self, project_name, created_on, parent=None, def create_project(self, project_name, created_on, parent=None,
domain='default', p_id=None): domain='default', description=""):
parent = self._project_from_id(parent) parent = self._project_from_id(parent)
domain = self._domain_from_id(domain) domain = self._domain_from_id(domain)
global identity_temp_cache global identity_temp_cache
project = mock.Mock()
if p_id: project = FakeProject(
project.id = p_id name=project_name, created_on=created_on, description=description,
else: domain_id=domain.id
identity_temp_cache['i'] += 0.5 )
project.id = "project_id_%s" % int(identity_temp_cache['i'])
project.name = project_name
if parent: if parent:
project.parent = parent.id project.parent_id = parent.id
else: identity_temp_cache['projects'][project.id] = project
project.parent = domain.id identity_temp_cache['new_projects'].append(project)
project.domain = domain.id
project.roles = {}
identity_temp_cache['projects'][project_name] = project
return project return project
def update_project(self, project, **kwargs): def update_project(self, project, **kwargs):

View File

@ -17,7 +17,9 @@ import mock
from rest_framework import status from rest_framework import status
from adjutant.api.models import Token from adjutant.api.models import Token
from adjutant.common.tests.fake_clients import FakeManager, setup_temp_cache from adjutant.common.tests import fake_clients
from adjutant.common.tests.fake_clients import (
FakeManager, setup_identity_cache)
from adjutant.common.tests.utils import (AdjutantAPITestCase, from adjutant.common.tests.utils import (AdjutantAPITestCase,
modify_dict_settings) modify_dict_settings)
@ -42,28 +44,34 @@ class ModifySettingsTests(AdjutantAPITestCase):
Test override reset, by changing the reset password blacklisted roles Test override reset, by changing the reset password blacklisted roles
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="test_password",
user.name = "test@example.com" email="test@example.com")
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user2 = mock.Mock() user2 = fake_clients.FakeUser(
user2.id = 'user_2' name="admin@example.com", password="admin_password",
user2.name = "admin@example.com" email="admin@example.com")
user2.email = "admin@example.com"
user2.domain = "default"
user2.password = "admin_password"
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['test_role'], user2.id: ['admin']}
setup_temp_cache({'test_project': project}, test_role = fake_clients.FakeRole("test_role")
{user.id: user, user2.id: user2})
assignments = [
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="test_role",
user={'id': user.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="admin",
user={'id': user2.id}
),
]
setup_identity_cache(
projects=[project], users=[user, user2],
role_assignments=assignments, extra_roles=[test_role])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -103,21 +111,20 @@ class ModifySettingsTests(AdjutantAPITestCase):
Test override reset, by changing the reset password blacklisted roles Test override reset, by changing the reset password blacklisted roles
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="admin@example.com", password="admin_password",
user.name = "admin@example.com" email="admin@example.com")
user.email = "admin@example.com"
user.domain = 'default'
user.password = "test_password"
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['admin']}
setup_temp_cache({'test_project': project}, assignment = fake_clients.FakeRoleAssignment(
{user.id: user}) scope={'project': {'id': project.id}},
role_name="admin",
user={'id': user.id}
)
setup_identity_cache(
projects=[project], users=[user], role_assignments=[assignment])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': 'admin@example.com'} data = {'email': 'admin@example.com'}
@ -151,28 +158,34 @@ class ModifySettingsTests(AdjutantAPITestCase):
Test override reset, by changing the reset password blacklisted roles Test override reset, by changing the reset password blacklisted roles
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="test_password",
user.name = "test@example.com" email="test@example.com")
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user2 = mock.Mock() user2 = fake_clients.FakeUser(
user2.id = 'user_2' name="admin@example.com", password="admin_password",
user2.name = "admin@example.com" email="admin@example.com")
user2.email = "admin@example.com"
user2.domain = "default"
user2.password = "admin_password"
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['test_role'], user2.id: ['admin']}
setup_temp_cache({'test_project': project}, test_role = fake_clients.FakeRole("test_role")
{user.id: user, user2.id: user2})
assignments = [
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="test_role",
user={'id': user.id}
),
fake_clients.FakeRoleAssignment(
scope={'project': {'id': project.id}},
role_name="admin",
user={'id': user2.id}
),
]
setup_identity_cache(
projects=[project], users=[user, user2],
role_assignments=assignments, extra_roles=[test_role])
url = "/v1/actions/ResetPassword" url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"} data = {'email': "test@example.com"}
@ -191,31 +204,30 @@ class ModifySettingsTests(AdjutantAPITestCase):
Tests the update operator using email sending Tests the update operator using email sending
""" """
user = mock.Mock() user = fake_clients.FakeUser(
user.id = 'user_id' name="test@example.com", password="test_password",
user.name = "test@example.com" email="test@example.com")
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
project = mock.Mock() project = fake_clients.FakeProject(name="test_project")
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['project_admin']}
setup_temp_cache({'test_project': project}, assignment = fake_clients.FakeRoleAssignment(
{user.id: user}) scope={'project': {'id': project.id}},
role_name="project_admin",
user={'id': user.id}
)
setup_identity_cache(
projects=[project], users=[user], role_assignments=[assignment])
url = "/v1/actions/UpdateEmail" url = "/v1/actions/UpdateEmail"
data = {'new_email': "new_test@example.com"} data = {'new_email': "new_test@example.com"}
headers = { headers = {
'project_name': "test_project", 'project_name': "test_project",
'project_id': "test_project_id", 'project_id': project.id,
'roles': "project_admin,_member_,project_mod", 'roles': "project_admin,_member_,project_mod",
'username': "test@example.com", 'username': "test@example.com",
'user_id': "user_id", 'user_id': user.id,
'authenticated': True 'authenticated': True
} }

View File

@ -20,6 +20,8 @@ from django.test.utils import override_settings
from django.test import TestCase from django.test import TestCase
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from adjutant.common.tests import fake_clients
class modify_dict_settings(override_settings): class modify_dict_settings(override_settings):
""" """
@ -199,6 +201,12 @@ class AdjutantTestCase(TestCase, TestCaseMixin):
cls._remove_settings_changes() cls._remove_settings_changes()
super(AdjutantTestCase, cls).tearDownClass() super(AdjutantTestCase, cls).tearDownClass()
def tearDown(self):
fake_clients.identity_temp_cache.clear()
fake_clients.neutron_cache.clear()
fake_clients.nova_cache.clear()
fake_clients.cinder_cache.clear()
class AdjutantAPITestCase(APITestCase, TestCaseMixin): class AdjutantAPITestCase(APITestCase, TestCaseMixin):
""" """
@ -214,3 +222,9 @@ class AdjutantAPITestCase(APITestCase, TestCaseMixin):
def tearDownClass(cls): def tearDownClass(cls):
cls._remove_settings_changes() cls._remove_settings_changes()
super(AdjutantAPITestCase, cls).tearDownClass() super(AdjutantAPITestCase, cls).tearDownClass()
def tearDown(self):
fake_clients.identity_temp_cache.clear()
fake_clients.neutron_cache.clear()
fake_clients.nova_cache.clear()
fake_clients.cinder_cache.clear()

View File

@ -36,7 +36,20 @@ def get_managable_roles(user_roles):
return managable_role_names return managable_role_names
class IdentityManager(object): def subtree_ids_list(subtree, id_list=[]):
if not subtree:
return id_list
for key in subtree.iterkeys():
id_list.append(key)
if subtree[key]:
subtree_ids_list(subtree[key], id_list)
return id_list
# NOTE(adriant): I'm adding no cover here since this class can never be covered
# by unit and non-tempest functional tests. This class only works when talking
# to a real Keystone, so tests can never cover it.
class IdentityManager(object): # pragma: no cover
""" """
A wrapper object for the Keystone Client. Mainly setup as A wrapper object for the Keystone Client. Mainly setup as
such for easier testing, but also so it can be replaced such for easier testing, but also so it can be replaced
@ -78,17 +91,24 @@ class IdentityManager(object):
role_dict = {role.id: role for role in roles} role_dict = {role.id: role for role in roles}
users = {} users = {}
user_assignments = self.ks_client.role_assignments.list( user_assignments = self.ks_client.role_assignments.list(
project=project) project=project)
for assignment in user_assignments: for assignment in user_assignments:
try: try:
user = users.get(assignment.user['id'], None) user = users.get(assignment.user['id'], None)
if user: if not user:
user.roles.append(role_dict[assignment.role['id']]) user = self.ks_client.users.get(
else: assignment.user['id'])
user = self.ks_client.users.get(assignment.user['id']) user.roles = []
user.roles = [role_dict[assignment.role['id']], ] user.inherited_roles = []
users[user.id] = user users[user.id] = user
if assignment.scope.get('OS-INHERIT:inherited_to'):
user.inherited_roles.append(
role_dict[assignment.role['id']])
else:
user.roles.append(role_dict[assignment.role['id']])
except AttributeError: except AttributeError:
# Just means the assignment is a group, so ignore it. # Just means the assignment is a group, so ignore it.
pass pass
@ -96,6 +116,46 @@ class IdentityManager(object):
return [] return []
return users.values() return users.values()
def list_inherited_users(self, project):
"""
Find all the users whose roles are inherited down to the given project.
"""
try:
roles = self.ks_client.roles.list()
role_dict = {role.id: role for role in roles}
users = {}
project = self.ks_client.projects.get(project)
while project.parent_id:
project = self.ks_client.projects.get(project.parent_id)
user_assignments = self.ks_client.role_assignments.list(
project=project)
for assignment in user_assignments:
if not assignment.scope.get('OS-INHERIT:inherited_to'):
continue
try:
user = users.get(
assignment.user['id'], None)
if user:
user.roles.append(
role_dict[assignment.role['id']])
else:
user = self.ks_client.users.get(
assignment.user['id'])
user.roles = [
role_dict[assignment.role['id']], ]
user.inherited_roles = []
users[user.id] = user
except AttributeError:
# Just means the assignment is a group.
pass
for user_id, user in users.iteritems():
user.roles = list(set(user.roles))
except ks_exceptions.NotFound:
return []
return users.values()
def create_user(self, name, password, email, created_on, domain=None, def create_user(self, name, password, email, created_on, domain=None,
default_project=None): default_project=None):
@ -126,8 +186,21 @@ class IdentityManager(object):
role = None role = None
return role return role
def get_roles(self, user, project): def get_roles(self, user, project, inherited=False):
return self.ks_client.roles.list(user=user, project=project) roles = self.ks_client.roles.list()
role_dict = {role.id: role for role in roles}
user_roles = []
user_assignments = self.ks_client.role_assignments.list(
user=user, project=project)
for assignment in user_assignments:
if (assignment.scope.get('OS-INHERIT:inherited_to') and not
inherited) or (
inherited and not
assignment.scope.get('OS-INHERIT:inherited_to')):
continue
user_roles.append(role_dict[assignment.role['id']])
return user_roles
def get_all_roles(self, user): def get_all_roles(self, user):
""" """
@ -146,15 +219,25 @@ class IdentityManager(object):
return projects return projects
def add_user_role(self, user, role, project): def add_user_role(self, user, role, project, inherited=False):
try: try:
self.ks_client.roles.grant(role, user=user, project=project) if inherited:
self.ks_client.roles.grant(
role, user=user, project=project,
os_inherit_extension_inherited=inherited)
else:
self.ks_client.roles.grant(role, user=user, project=project)
except ks_exceptions.Conflict: except ks_exceptions.Conflict:
# Conflict is ok, it means the user already has this role. # Conflict is ok, it means the user already has this role.
pass pass
def remove_user_role(self, user, role, project): def remove_user_role(self, user, role, project, inherited=False):
self.ks_client.roles.revoke(role, user=user, project=project) if inherited:
self.ks_client.roles.revoke(
role, user=user, project=project,
os_inherit_extension_inherited=inherited)
else:
self.ks_client.roles.revoke(role, user=user, project=project)
def find_project(self, project_name, domain): def find_project(self, project_name, domain):
try: try:
@ -172,12 +255,36 @@ class IdentityManager(object):
except ks_exceptions.NotFound: except ks_exceptions.NotFound:
return None return None
def get_project(self, project_id): def get_project(self, project_id, subtree_as_ids=False,
parents_as_ids=False):
try: try:
return self.ks_client.projects.get(project_id) project = self.ks_client.projects.get(
project_id, subtree_as_ids=subtree_as_ids,
parents_as_ids=parents_as_ids)
if parents_as_ids:
depth = 1
last_root = None
root = project.parents.keys()[0]
value = project.parents.values()[0]
while value is not None:
depth += 1
last_root = root
root = value.keys()[0]
value = value.values()[0]
project.root = last_root
project.depth = depth
if subtree_as_ids:
project.subtree_ids = subtree_ids_list(project.subtree)
return project
except ks_exceptions.NotFound: except ks_exceptions.NotFound:
return None return None
def list_sub_projects(self, project_id):
try:
return self.ks_client.projects.list(parent_id=project_id)
except ks_exceptions.NotFound:
return []
def update_project(self, project, name=None, domain=None, description=None, def update_project(self, project, name=None, domain=None, description=None,
enabled=None, **kwargs): enabled=None, **kwargs):
try: try:
@ -189,9 +296,10 @@ class IdentityManager(object):
return None return None
def create_project(self, project_name, created_on, parent=None, def create_project(self, project_name, created_on, parent=None,
domain=None): domain=None, description=""):
project = self.ks_client.projects.create( project = self.ks_client.projects.create(
project_name, domain, parent=parent, created_on=created_on) project_name, domain, parent=parent, created_on=created_on,
description=description)
return project return project
def get_domain(self, domain_id): def get_domain(self, domain_id):