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)
# Mutators
def grant_roles(self, user, roles, project_id):
return self._user_roles_edit(user, roles, project_id, remove=False)
def grant_roles(self, user, roles, project_id, inherited=False):
return self._user_roles_edit(
user, roles, project_id, remove=False, inherited=inherited)
def remove_roles(self, user, roles, project_id):
return self._user_roles_edit(user, roles, project_id, remove=True)
def remove_roles(self, user, roles, project_id, inherited=False):
return self._user_roles_edit(
user, roles, project_id, remove=True, inherited=inherited)
# 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()
if not remove:
action_fn = id_manager.add_user_role
@ -297,7 +300,7 @@ class UserMixin(ResourceMixin):
raise TypeError("Keystone missing role: %s" % role)
for role in ks_roles:
action_fn(user, role, project_id)
action_fn(user, role, project_id, inherited=inherited)
except Exception as e:
self.add_note(
"Error: '%s' while %s the roles: %s on user: %s " %
@ -398,10 +401,12 @@ class ProjectMixin(ResourceMixin):
def _create_project(self):
id_manager = user_store.IdentityManager()
description = getattr(self, "description", "")
try:
project = id_manager.create_project(
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:
self.add_note(
"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.projects import (
NewProjectWithUserAction, AddDefaultUsersToProjectAction)
NewProjectWithUserAction, NewProjectAction,
AddDefaultUsersToProjectAction)
from adjutant.actions.v1.users import (
EditUserRolesAction, NewUserAction, ResetUserPasswordAction,
UpdateUserEmailAction)
@ -37,6 +38,7 @@ def register_action_class(action_class, serializer_class):
# Register Project actions:
register_action_class(
NewProjectWithUserAction, serializers.NewProjectWithUserSerializer)
register_action_class(NewProjectAction, serializers.NewProjectSerializer)
register_action_class(
AddDefaultUsersToProjectAction,
serializers.AddDefaultUsersToProjectSerializer)

View File

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

View File

@ -46,15 +46,26 @@ class BaseUserIdSerializer(serializers.Serializer):
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)
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):
parent_id = serializers.CharField(
max_length=64, default=None, allow_null=True)
project_name = serializers.CharField(max_length=64)
domain_id = serializers.CharField(max_length=64, default='default')
description = serializers.CharField(default="", allow_blank=True)
class NewProjectWithUserSerializer(BaseUserNameSerializer):
@ -70,11 +81,21 @@ class ResetUserSerializer(BaseUserNameSerializer):
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)
project_id = serializers.CharField(max_length=64)
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):
setup_network = serializers.BooleanField(default=True)

View File

@ -22,7 +22,8 @@ from adjutant.actions.v1.projects import (
NewProjectAction)
from adjutant.api.models import Task
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
@ -38,7 +39,7 @@ class ProjectActionTests(TestCase):
user password at submit step.
"""
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -59,29 +60,29 @@ class ProjectActionTests(TestCase):
action.post_approve()
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')
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(
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'})
action.post_approve()
self.assertEquals(action.valid, True)
token_data = {'password': '123456'}
action.submit(token_data)
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(
fake_clients.identity_temp_cache['users']["user_id_1"].name,
'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(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -91,7 +92,7 @@ class ProjectActionTests(TestCase):
ensure reapprove does nothing.
"""
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -112,34 +113,40 @@ class ProjectActionTests(TestCase):
action.post_approve()
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')
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(
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'})
action.post_approve()
self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEqual(
len(fake_clients.identity_temp_cache['new_projects']), 1)
self.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 1)
self.assertEquals(
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'})
token_data = {'password': '123456'}
action.submit(token_data)
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(
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(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -150,7 +157,7 @@ class ProjectActionTests(TestCase):
Ensure reapprove correctly finishes.
"""
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -187,11 +194,14 @@ class ProjectActionTests(TestCase):
# No roles_granted yet, but user created
self.assertTrue("user_id" 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(
fake_clients.identity_temp_cache['users']["user_id_1"].email,
'test@example.com')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertFalse("user_id_1" in project.roles)
len(fake_clients.identity_temp_cache['role_assignments']), 0)
# And then swap back the correct function
action.grant_roles = old_grant_function
@ -205,9 +215,12 @@ class ProjectActionTests(TestCase):
action.submit(token_data)
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(
sorted(project.roles["user_id_1"]),
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -216,13 +229,10 @@ class ProjectActionTests(TestCase):
Create a project for a user that already exists.
"""
user = mock.Mock()
user.id = 'user_id_1'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
@ -243,24 +253,28 @@ class ProjectActionTests(TestCase):
action.post_approve()
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.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 0)
self.assertEquals(
task.cache,
{'user_id': 'user_id_1', 'project_id': 'project_id_1',
{'project_id': new_project.id, 'user_id': user.id,
'user_state': 'existing'})
token_data = {'password': '123456'}
action.submit(token_data)
# submit does nothing for existing
action.submit({})
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(
fake_clients.identity_temp_cache['users'][user.id].email,
'test@example.com')
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(
sorted(project.roles[user.id]),
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -271,13 +285,10 @@ class ProjectActionTests(TestCase):
a user with the same name but different email address
"""
user = mock.Mock()
user.id = "test_id"
user.name = "test_user"
user.email = "different@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test_user", password="123", email="different@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
@ -313,7 +324,7 @@ class ProjectActionTests(TestCase):
Tests when the project is removed after the post approve step.
"""
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -334,13 +345,9 @@ class ProjectActionTests(TestCase):
action.post_approve()
self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEquals(
task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1',
'user_state': 'default'})
new_project = fake_clients.identity_temp_cache['new_projects'][0]
self.assertEquals(new_project.name, 'test_project')
fake_clients.identity_temp_cache['projects'] = {}
@ -353,7 +360,7 @@ class ProjectActionTests(TestCase):
Tests when the user is removed after the post approve step.
"""
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -374,13 +381,10 @@ class ProjectActionTests(TestCase):
action.post_approve()
self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEquals(
task.cache,
{'project_id': 'project_id_1', 'user_id': 'user_id_1',
'user_state': 'default'})
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')
fake_clients.identity_temp_cache['users'] = {}
@ -393,15 +397,11 @@ class ProjectActionTests(TestCase):
Create a project for a user that is disabled.
"""
user = mock.Mock()
user.id = 'user_id_1'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.enabled = False
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com",
enabled=False)
# create disabled user
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
@ -423,13 +423,17 @@ class ProjectActionTests(TestCase):
action.post_approve()
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.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 0)
self.assertEquals(
task.cache,
{'user_id': 'user_id_1',
'project_id': 'project_id_1',
{'user_id': user.id,
'project_id': new_project.id,
'user_state': 'disabled'})
self.assertEquals(
action.action.cache["token_fields"],
@ -440,18 +444,17 @@ class ProjectActionTests(TestCase):
action.submit(token_data)
self.assertEquals(action.valid, True)
# check that user has been created correctly
self.assertEquals(
fake_clients.identity_temp_cache['users'][user.id].email,
'test@example.com')
self.assertEquals(
fake_clients.identity_temp_cache['users'][user.id].enabled,
True)
self.assertEquals(user.password, '123456')
# check that user has been enabled correctly
self.assertEquals(user.email, 'test@example.com')
self.assertEquals(user.enabled, True)
# 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(
sorted(project.roles[user.id]),
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -464,7 +467,7 @@ class ProjectActionTests(TestCase):
"""
# Start with nothing created
setup_temp_cache({}, {})
setup_identity_cache()
# Sign up for the project+user, validate.
task = Task.objects.create(
@ -485,8 +488,8 @@ class ProjectActionTests(TestCase):
self.assertEquals(action.valid, True)
# Create the disabled user directly with the Identity Manager.
fm = FakeManager()
user = fm.create_user(
fake_client = fake_clients.FakeManager()
user = fake_client.create_user(
name="test@example.com",
password='origpass',
email="test@example.com",
@ -494,19 +497,22 @@ class ProjectActionTests(TestCase):
domain='default',
default_project=None
)
fm.disable_user(user.id)
fake_client.disable_user(user.id)
# approve previous signup
action.post_approve()
self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(
project.name,
'test_project')
new_project = fake_clients.identity_temp_cache['new_projects'][0]
self.assertEquals(new_project.name, 'test_project')
self.assertEqual(
len(fake_clients.identity_temp_cache['new_users']), 1)
self.assertEquals(
task.cache,
{'user_id': user.id,
'project_id': project.id,
'project_id': new_project.id,
'user_state': 'disabled'})
# check that user has been re-enabled with a generated password.
@ -521,18 +527,21 @@ class ProjectActionTests(TestCase):
# Ensure user has new password:
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):
"""
Create a project that already exists.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({project.name: project}, {})
setup_identity_cache(projects=[project])
task = Task.objects.create(
ip_address="0.0.0.0",
@ -560,7 +569,7 @@ class ProjectActionTests(TestCase):
def test_new_project_invalid_domain_id(self):
""" Create a project using an invalid domain """
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -594,7 +603,7 @@ class ProjectActionTests(TestCase):
user password at submit step.
"""
setup_temp_cache({}, {})
setup_identity_cache()
task = Task.objects.create(
ip_address="0.0.0.0",
@ -616,26 +625,29 @@ class ProjectActionTests(TestCase):
action.post_approve()
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')
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(
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'})
token_data = {'password': '123456'}
action.submit(token_data)
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(
fake_clients.identity_temp_cache['users']["user_id_1"].email,
'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(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -653,18 +665,14 @@ class ProjectActionTests(TestCase):
default_users = ['admin']
default_roles = ['admin']
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
task = Task.objects.create(
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(
{'domain_id': 'default'}, task=task, order=1)
@ -675,8 +683,10 @@ class ProjectActionTests(TestCase):
action.post_approve()
self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(project.roles['user_id_0'], ['admin'])
fake_client = fake_clients.FakeManager()
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):
"""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
the project isn't created yet during pre_approve.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache()
task = Task.objects.create(
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.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
task = Task.objects.create(
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(
{'domain_id': 'default'}, task=task, order=1)
@ -738,41 +738,40 @@ class ProjectActionTests(TestCase):
action.post_approve()
self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(project.roles['user_id_0'], ['admin'])
fake_client = fake_clients.FakeManager()
user = fake_client.find_user('admin', 'default')
roles = fake_client._get_roles_as_names(user, project)
self.assertEquals(roles, ['admin'])
action.post_approve()
self.assertEquals(action.valid, True)
project = fake_clients.identity_temp_cache['projects']['test_project']
self.assertEquals(project.roles['user_id_0'], ['admin'])
roles = fake_client._get_roles_as_names(user, project)
self.assertEquals(roles, ['admin'])
def test_new_project_action(self):
"""
Tests the new project action for an existing user.
"""
user = mock.Mock()
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = fake_clients.FakeProject(name="parent_project")
project = mock.Mock()
project.id = "parent_project"
project.domain = "default"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({project.id: project}, {user.id: user})
setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id",
"project_id": "parent_project",
keystone_user={"user_id": user.id,
"project_id": project.id,
"project_domain_id": 'default'})
data = {
'domain_id': 'default',
'parent_id': "parent_project",
'parent_id': project.id,
'project_name': 'test_project',
'description': '',
}
action = NewProjectAction(data, task=task, order=1)
@ -782,17 +781,15 @@ class ProjectActionTests(TestCase):
action.post_approve()
self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEquals(
fake_clients.identity_temp_cache['projects'][
'test_project'].parent, 'parent_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)
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(
sorted(project.roles["test_user_id"]),
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -801,30 +798,28 @@ class ProjectActionTests(TestCase):
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()
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = fake_clients.FakeProject(name="parent_project")
project = mock.Mock()
project.id = "parent_project"
project.domain = "default"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({project.id: project}, {user.id: user})
setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id",
"project_id": "parent_project",
keystone_user={"user_id": user.id,
"project_id": project.id,
"project_domain_id": 'default'})
data = {
'domain_id': 'default',
'parent_id': "parent_project",
'parent_id': project.id,
'project_name': 'test_project',
'description': '',
}
action = NewProjectAction(data, task=task, order=1)
@ -834,28 +829,28 @@ class ProjectActionTests(TestCase):
action.post_approve()
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(
fake_clients.identity_temp_cache[
'projects']['test_project'].parent, 'parent_project')
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
action.post_approve()
# Nothing should change
self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache['projects']['test_project'].name,
'test_project')
self.assertEquals(
fake_clients.identity_temp_cache[
'projects']['test_project'].parent, 'parent_project')
self.assertEquals(new_project.name, 'test_project')
self.assertEquals(new_project.parent_id, project.id)
project = fake_clients.identity_temp_cache['projects']['test_project']
roles = fake_client._get_roles_as_names(user, new_project)
self.assertEquals(
sorted(project.roles["test_user_id"]),
sorted(roles),
sorted(['_member_', 'project_admin',
'project_mod', 'heat_stack_owner']))
@ -868,27 +863,24 @@ class ProjectActionTests(TestCase):
as the current user's project id
"""
user = mock.Mock()
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = fake_clients.FakeProject(name="parent_project")
project = mock.Mock()
project.id = "parent_project"
project.domain = "default"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({project.id: project}, {user.id: user})
setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id",
"project_id": "not_parent_project",
keystone_user={"user_id": user.id,
"project_id": project.id,
"project_domain_id": 'default'})
data = {
'domain_id': 'default',
'parent_id': "parent_project",
'parent_id': "not_parent_project_id",
'project_name': 'test_project',
'description': '',
}
action = NewProjectAction(data, task=task, order=1)
@ -908,27 +900,24 @@ class ProjectActionTests(TestCase):
as the current user's domain id
"""
user = mock.Mock()
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = fake_clients.FakeProject(name="parent_project")
project = mock.Mock()
project.id = "parent_project"
project.domain = "default"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({project.id: project}, {user.id: user})
setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id",
"project_id": "parent_project",
keystone_user={"user_id": user.id,
"project_id": project.id,
"project_domain_id": 'default'})
data = {
'domain_id': 'notdefault',
'parent_id': "parent_project",
'parent_id': project.id,
'project_name': 'test_project',
'description': '',
}
action = NewProjectAction(data, task=task, order=1)
@ -947,27 +936,24 @@ class ProjectActionTests(TestCase):
New project action where there is no specified parent id
"""
user = mock.Mock()
user.id = "test_user_id"
user.name = "test_user"
user.domain = 'default'
project = fake_clients.FakeProject(name="parent_project")
project = mock.Mock()
project.id = "parent_project"
project.domain = "default"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({project.id: project}, {user.id: user})
setup_identity_cache(projects=[project], users=[user])
task = Task.objects.create(
ip_address="0.0.0.0",
keystone_user={"user_id": "test_user_id",
"project_id": "parent_project",
keystone_user={"user_id": user.id,
"project_id": project.id,
"project_domain_id": 'default'})
data = {
'domain_id': 'default',
'parent_id': None,
'project_name': 'test_project',
'description': '',
}
action = NewProjectAction(data, task=task, order=1)
@ -978,9 +964,9 @@ class ProjectActionTests(TestCase):
action.post_approve()
self.assertEquals(action.valid, True)
self.assertEquals(
fake_clients.identity_temp_cache[
'projects']['test_project'].parent, 'default')
new_project = fake_clients.identity_temp_cache['new_projects'][0]
self.assertEquals(new_project.name, 'test_project')
self.assertEquals(new_project.parent_id, None)
action.submit({})
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.common.tests.utils import modify_dict_settings
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,
nova_cache, setup_mock_caches)
@ -61,7 +61,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
data = {
'setup_network': True,
@ -111,7 +111,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
data = {
'setup_network': False,
@ -156,7 +156,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
data = {
'setup_network': True,
@ -248,7 +248,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
task.cache = {'project_id': "test_project_id"}
@ -330,7 +330,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
task.cache = {'project_id': "test_project_id"}
@ -377,7 +377,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
task.cache = {'project_id': "test_project_id"}
@ -429,7 +429,7 @@ class ProjectSetupActionTests(TestCase):
project.domain = 'default'
project.roles = {}
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
setup_mock_caches('RegionOne', 'test_project_id')
task = Task.objects.create(
@ -489,11 +489,6 @@ class ProjectSetupActionTests(TestCase):
get_fake_cinderclient)
class QuotaActionTests(TestCase):
def tearDown(self):
cinder_cache.clear()
nova_cache.clear()
neutron_cache.clear()
def test_update_quota(self):
"""
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.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')
# Test sending to only a single region
@ -559,7 +554,7 @@ class QuotaActionTests(TestCase):
user.domain = 'default'
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('RegionTwo', project.id)
@ -618,7 +613,7 @@ class QuotaActionTests(TestCase):
user.domain = 'default'
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('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',
'project_id',
'roles',
'inherited_roles',
'domain_id',
]
@ -116,6 +117,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
# default action: Create a new user in the tenant and add roles
user = self.create_user(token_data['password'])
self.grant_roles(user, self.roles, self.project_id)
self.grant_roles(user, self.inherited_roles, self.project_id, True)
self.add_note(
'User %s has been created, with roles %s in project %s.'
@ -126,6 +128,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
user = self.find_user()
self.enable_user(user)
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.add_note('User %s password has been changed.' % self.username)
@ -139,6 +142,7 @@ class NewUserAction(UserNameAction, ProjectMixin, UserMixin):
# Existing action: only add roles.
user = self.find_user()
self.grant_roles(user, self.roles, self.project_id)
self.grant_roles(user, self.inherited_roles, self.project_id, True)
self.add_note(
'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
# case since '_validate_username_exists' will ensure the True case
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.')
return False
@ -234,6 +238,7 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
'project_id',
'user_id',
'roles',
'inherited_roles',
'remove'
]
@ -251,35 +256,35 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
project = id_manager.get_project(self.project_id)
# user roles
current_roles = id_manager.get_roles(user, project)
current_role_names = {role.name for role in current_roles}
# NOTE(adriant): Only allow someone to edit roles if all roles from
# the target user can be managed by editor.
can_manage_roles = user_store.get_managable_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
current_inherited_roles = id_manager.get_roles(
user, project, inherited=True)
current_roles = {role.name for role in current_roles}
current_inherited_roles = {
role.name for role in current_inherited_roles}
if self.remove:
remaining = set(current_role_names) & set(self.roles)
if not remaining:
remaining = set(current_roles) & set(self.roles)
remaining_inherited = (
set(current_inherited_roles) & set(self.inherited_roles))
if not remaining and not remaining_inherited:
self.action.state = "complete"
self.add_note(
"User doesn't have roles to remove.")
else:
self.roles = list(remaining)
self.inherited_roles = list(remaining_inherited)
self.add_note(
'User has roles to remove.')
else:
missing = set(self.roles) - set(current_role_names)
if not missing:
missing = set(self.roles) - set(current_roles)
missing_inherited = (
set(self.inherited_roles) - set(current_inherited_roles))
if not missing and not missing_inherited:
self.action.state = "complete"
self.add_note(
'User already has roles.')
else:
self.roles = list(missing)
self.inherited_roles = list(missing_inherited)
self.add_note(
'User user missing roles.')
# All paths are valid here
@ -314,23 +319,34 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
user = self._get_target_user()
self._user_roles_edit(user, self.roles, self.project_id,
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(
'User %s has had roles %s removed from project %s.'
% (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(
'User %s has been given roles %s in project %s.'
% (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":
if self.remove:
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))
else:
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))
@ -357,6 +373,7 @@ class UpdateUserEmailAction(UserIdAction, UserMixin):
self.user = self._get_target_user()
if self.user:
return True
self.add_note("Unable to find target user.")
return False
def _validate_email_not_in_use(self):

View File

@ -53,6 +53,14 @@ class UserList(tasks.InviteUser):
roles.append(role.name)
if skip:
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', '')
enabled = getattr(user, 'enabled')
@ -63,11 +71,36 @@ class UserList(tasks.InviteUser):
'name': user.name,
'email': email,
'roles': roles,
'inherited_roles': inherited_roles,
'cohort': 'Member',
'status': user_status,
'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:
project_tasks = models.Task.objects.filter(
project_id=project_id,
@ -98,12 +131,16 @@ class UserList(tasks.InviteUser):
# than it helps. May uncomment once different duplication checking
# measures are in place.
# if task['task_data']['email'] not in active_emails:
user = {'id': task['uuid'],
'name': task['task_data']['email'],
'email': task['task_data']['email'],
'roles': task['task_data']['roles'],
'cohort': 'Invited',
'status': task['status']}
user = {
'id': task['uuid'],
'name': task['task_data']['email'],
'email': task['task_data']['email'],
'roles': task['task_data']['roles'],
'inherited_roles':
task['task_data']['inherited_roles'],
'cohort': 'Invited',
'status': task['status']
}
if not settings.USERNAME_IS_EMAIL:
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_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({'id': user.id,
"username": user.name,
"email": getattr(user, 'email', ''),
'roles': roles})
'roles': roles,
'inherited_roles': inherited_roles})
@utils.mod_or_admin
def delete(self, request, user_id):
@ -185,12 +227,29 @@ class UserRoles(tasks.TaskView):
""" Get role info based on the user id. """
id_manager = user_store.IdentityManager()
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_manager.get_project(project_id)
roles = []
for role in id_manager.get_roles(user, project):
roles.append(role.to_dict())
return Response({"roles": roles})
class_conf = settings.TASK_SETTINGS.get(
self.task_type, settings.DEFAULT_TASK_SETTINGS)
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
def put(self, args, **kwargs):

View File

@ -27,7 +27,9 @@ from rest_framework import status
from rest_framework.test import APITestCase
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
@ -65,7 +67,7 @@ class AdminAPITests(APITestCase):
"""
Test the basic task detail view.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -126,14 +128,10 @@ class AdminAPITests(APITestCase):
Expired token should do nothing, then delete itself.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -160,14 +158,10 @@ class AdminAPITests(APITestCase):
Expired token should do nothing, then delete itself.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -193,14 +187,10 @@ class AdminAPITests(APITestCase):
Token should contain actions, task_type, required fields.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -222,28 +212,27 @@ class AdminAPITests(APITestCase):
self.assertEqual(1, Token.objects.count())
def test_token_list_get(self):
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
"""
Create two password resets, then confirm we can list tokens.
"""
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
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"
data = {'email': "test@example.com"}
response = self.client.post(url, data, format='json')
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')
self.assertEqual(response.status_code, status.HTTP_200_OK)
first_task_id = Task.objects.all()[0].uuid
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
@ -256,16 +245,19 @@ class AdminAPITests(APITestCase):
response = self.client.get(url, headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
len(response.json()['tokens']), 2)
self.assertEqual(response.json()['tokens'][1]['task'],
first_task_id)
self.assertEqual(len(response.json()['tokens']), 2)
task_ids = [t.uuid for t in Task.objects.all()]
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):
"""
Can't approve a completed task.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -297,7 +289,7 @@ class AdminAPITests(APITestCase):
and error notifcations
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -358,13 +350,9 @@ class AdminAPITests(APITestCase):
Updates it and attempts to reapprove.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
headers = {
'project_name': "test_project",
@ -466,7 +454,7 @@ class AdminAPITests(APITestCase):
"""
Test that you can acknowledge a notification.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
headers = {
'project_name': "test_project",
@ -535,7 +523,7 @@ class AdminAPITests(APITestCase):
"""
Test that you cant reacknowledge a notification.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
headers = {
'project_name': "test_project",
@ -693,7 +681,7 @@ class AdminAPITests(APITestCase):
"""
Tests the email notification engine
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -727,21 +715,14 @@ class AdminAPITests(APITestCase):
test deleting of expired tokens.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
user2 = mock.Mock()
user2.id = 'user_id2'
user2.name = "test2@example.com"
user2.email = "test2@example.com"
user2.domain = 'default'
user2.password = "test_password"
user2 = fake_clients.FakeUser(
name="test2@example.com", password="123",
email="test2@example.com")
setup_temp_cache({}, {user.id: user, user2.name: user2})
setup_identity_cache(users=[user, user2])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -787,14 +768,10 @@ class AdminAPITests(APITestCase):
test for reissue of tokens
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -833,25 +810,21 @@ class AdminAPITests(APITestCase):
test for reissue of tokens for non-admin
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -885,14 +858,10 @@ class AdminAPITests(APITestCase):
Tests that a cancelled task cannot have a token reissued
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -928,14 +897,10 @@ class AdminAPITests(APITestCase):
Tests that a completed task cannot have a token reissued
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -971,7 +936,7 @@ class AdminAPITests(APITestCase):
Tests that an unapproved task cannot have a token reissued
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'email': "test@example.com", "project_name": "test_project"}
@ -1003,7 +968,7 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel a task.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -1158,25 +1117,21 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel your own task.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -1201,25 +1156,21 @@ class AdminAPITests(APITestCase):
Ensure the ability to cancel ONLY your own task.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -1233,34 +1184,31 @@ class AdminAPITests(APITestCase):
def test_task_list(self):
"""
Create some user invite tasks, then make sure we can list them.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@ -1282,33 +1230,29 @@ class AdminAPITests(APITestCase):
Test that tasks returns in the default sort.
The default sort is by created_on descending.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@ -1334,29 +1278,25 @@ class AdminAPITests(APITestCase):
def test_task_list_filter(self):
"""
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@ -1418,13 +1358,13 @@ class AdminAPITests(APITestCase):
project2.domain = 'default'
project2.roles = {}
setup_temp_cache(
setup_identity_cache(
{'test_project': project, 'test_project_2': project2}, {})
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_name': project.name,
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "owner@example.com",
'user_id': "test_user_id",
@ -1436,8 +1376,8 @@ class AdminAPITests(APITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
headers = {
'project_name': "test_project",
'project_id': "test_project_id_2",
'project_name': project2.name,
'project_id': project2.id,
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
@ -1459,28 +1399,8 @@ class AdminAPITests(APITestCase):
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 = {
'project_name': "test_project",
@ -1557,20 +1477,19 @@ class AdminAPITests(APITestCase):
admin user.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
project = fake_clients.FakeProject(name="test_project")
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['admin']}
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
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"
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 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.utils import (AdjutantAPITestCase,
modify_dict_settings)
@ -41,31 +42,28 @@ class TaskViewTests(AdjutantAPITestCase):
Simple test to confirm the serializers are correctly processing
wrong data or missing fields.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
'authenticated': True
}
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)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json(),
{'email': ['This field is required.']})
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)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
@ -78,25 +76,21 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure the new user workflow goes as expected.
Create task, create token, submit token.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
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(len(mail.outbox), 2)
self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].name,
fake_clients.identity_temp_cache['new_users'][0].name,
'test@example.com')
def test_new_user_no_project(self):
"""
Can't create a user for a non-existent project.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/InviteUser"
headers = {
@ -137,9 +131,10 @@ class TaskViewTests(AdjutantAPITestCase):
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"
headers = {
@ -160,7 +155,7 @@ class TaskViewTests(AdjutantAPITestCase):
Can't create a user if unauthenticated.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/InviteUser"
headers = {}
@ -177,31 +172,24 @@ class TaskViewTests(AdjutantAPITestCase):
"""
Adding existing user to project.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="parent_project")
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({'test_project': project}, {user.id: user})
setup_identity_cache(projects=[project], users=[user])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -218,31 +206,32 @@ class TaskViewTests(AdjutantAPITestCase):
Already has role.
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.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['_member_']}
project = fake_clients.FakeProject(name="test_project")
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"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
@ -254,7 +243,7 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure the new project workflow goes as expected.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -279,6 +268,9 @@ class TaskViewTests(AdjutantAPITestCase):
{'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]
url = "/v1/tokens/" + new_token.token
data = {'password': 'testpassword'}
@ -291,7 +283,7 @@ class TaskViewTests(AdjutantAPITestCase):
that the a 400 is recieved and no final emails are sent.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -315,6 +307,8 @@ class TaskViewTests(AdjutantAPITestCase):
response.data,
{'notes': ['created token']}
)
self.assertEqual(len(mail.outbox), 3)
fake_clients.identity_temp_cache['projects'] = {}
new_token = Token.objects.all()[0]
@ -322,6 +316,7 @@ class TaskViewTests(AdjutantAPITestCase):
data = {'password': 'testpassword'}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(len(mail.outbox), 3)
def test_new_project_existing(self):
"""
@ -329,13 +324,9 @@ class TaskViewTests(AdjutantAPITestCase):
if project is already present.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -366,16 +357,10 @@ class TaskViewTests(AdjutantAPITestCase):
No token should be needed.
"""
# pre-create user
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache(
projects={},
users={user.id: user})
setup_identity_cache(users=[user])
# unauthenticated sign up as existing user
url = "/v1/actions/CreateProject"
@ -406,7 +391,7 @@ class TaskViewTests(AdjutantAPITestCase):
"""
Project already exists but new user attempting to create it.
"""
setup_temp_cache({}, {})
setup_identity_cache()
# create signup#1 - project1 with user 1
url = "/v1/actions/CreateProject"
@ -455,14 +440,10 @@ class TaskViewTests(AdjutantAPITestCase):
Create task + create token, submit token.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
data = {'email': "test@example.com"}
@ -486,14 +467,10 @@ class TaskViewTests(AdjutantAPITestCase):
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
# Submit password reset
url = "/v1/actions/ResetPassword"
@ -517,7 +494,7 @@ class TaskViewTests(AdjutantAPITestCase):
data = {'password': 'new_test_password1'}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, 400)
self.assertEqual(user.password, 'test_password')
self.assertEqual(user.password, '123')
# Now reset with the second token
second_token = Token.objects.all()[1]
@ -532,7 +509,7 @@ class TaskViewTests(AdjutantAPITestCase):
Actions should be successful, so usernames are not exposed.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/ResetPassword"
data = {'email': "test@exampleinvalid.com"}
@ -547,7 +524,7 @@ class TaskViewTests(AdjutantAPITestCase):
CreateProject should create a notification.
We should be able to grab it.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -577,13 +554,7 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure we can't submit duplicate tasks
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
@ -600,25 +571,21 @@ class TaskViewTests(AdjutantAPITestCase):
"""
Ensure we can't submit duplicate tasks
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': 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'}
'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -626,7 +593,7 @@ class TaskViewTests(AdjutantAPITestCase):
self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -638,14 +605,10 @@ class TaskViewTests(AdjutantAPITestCase):
Confirm that the task id is returned when admin.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
headers = {
'project_name': "test_project",
@ -660,7 +623,10 @@ class TaskViewTests(AdjutantAPITestCase):
response = self.client.post(url, data, format='json', headers=headers)
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.assertEqual(
response.json()['task'],
new_task.uuid)
@ -670,14 +636,10 @@ class TaskViewTests(AdjutantAPITestCase):
Confirm that the task id is not returned unless admin.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
headers = {
'project_name': "test_project",
@ -692,6 +654,10 @@ class TaskViewTests(AdjutantAPITestCase):
response = self.client.post(url, data, format='json', headers=headers)
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'))
def test_update_email_task(self):
@ -700,13 +666,10 @@ class TaskViewTests(AdjutantAPITestCase):
Create task, create token, submit token.
"""
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail"
headers = {
@ -714,7 +677,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
'user_id': user.id,
'authenticated': True
}
@ -753,13 +716,10 @@ class TaskViewTests(AdjutantAPITestCase):
to send a confirmation email to the old email address it does.
"""
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail"
headers = {
@ -767,7 +727,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
'user_id': user.id,
'authenticated': True
}
@ -816,13 +776,10 @@ class TaskViewTests(AdjutantAPITestCase):
email address it does.
"""
user = mock.Mock()
user.id = 'test_user_id'
user.name = "nkdfslnkls"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="nkdfslnkls", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail"
headers = {
@ -830,7 +787,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "nkdfslnkls",
'user_id': "test_user_id",
'user_id': user.id,
'authenticated': True,
'email': 'test@example.com',
}
@ -859,13 +816,10 @@ class TaskViewTests(AdjutantAPITestCase):
def test_update_email_task_invalid_email(self):
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail"
headers = {
@ -873,7 +827,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
'user_id': user.id,
'authenticated': True
}
@ -887,19 +841,14 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=True)
def test_update_email_pre_existing_user_with_email(self):
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
user2 = mock.Mock()
user2.id = 'new_user_id'
user2.name = "new_test@example.com"
user2.email = "new_test@example.com"
user2.domain = 'default'
user2 = fake_clients.FakeUser(
name="new_test@example.com", password="123",
email="new_test@example.com")
setup_temp_cache({}, {user.id: user, user2.id: user2})
setup_identity_cache(users=[user, user2])
url = "/v1/actions/UpdateEmail"
headers = {
@ -924,19 +873,14 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=False)
def test_update_email_user_with_email_username_not_email(self):
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test"
user.email = "test@example.com"
user.domain = 'Default'
user = fake_clients.FakeUser(
name="test", password="123", email="test@example.com")
user2 = mock.Mock()
user2.id = 'new_user_id'
user2.name = "new_test"
user2.email = "new_test@example.com"
user2.domain = 'Default'
user2 = fake_clients.FakeUser(
name="new_test", password="123",
email="new_test@example.com")
setup_temp_cache({}, {user.id: user, user2.id: user})
setup_identity_cache(users=[user, user2])
url = "/v1/actions/UpdateEmail"
headers = {
@ -944,7 +888,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
'user_id': user.id,
'authenticated': True
}
@ -969,13 +913,10 @@ class TaskViewTests(AdjutantAPITestCase):
Ensure that an unauthenticated user cant access the endpoint.
"""
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail"
headers = {
@ -989,13 +930,10 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=False)
def test_update_email_task_username_not_email(self):
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test_user"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test_user", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/UpdateEmail"
headers = {
@ -1003,7 +941,7 @@ class TaskViewTests(AdjutantAPITestCase):
'project_id': "test_project_id",
'roles': "project_admin,_member_,project_mod",
'username': "test_user",
'user_id': "test_user_id",
'user_id': user.id,
'authenticated': True
}
@ -1028,25 +966,21 @@ class TaskViewTests(AdjutantAPITestCase):
"""
Invites a user where the email is different to the username.
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project}, {})
setup_identity_cache(projects=[project])
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "user",
'user_id': "test_user_id",
'authenticated': True
}
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)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -1063,7 +997,7 @@ class TaskViewTests(AdjutantAPITestCase):
self.assertEqual(len(mail.outbox), 2)
self.assertEquals(
fake_clients.identity_temp_cache['users']["user_id_1"].name,
fake_clients.identity_temp_cache['new_users'][0].name,
'new_user')
@override_settings(USERNAME_IS_EMAIL=False)
@ -1073,14 +1007,10 @@ class TaskViewTests(AdjutantAPITestCase):
Create task + create token, submit token.
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test_user"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test_user", password="123", email="test@example.com")
setup_temp_cache({}, {user.id: user})
setup_identity_cache(users=[user])
url = "/v1/actions/ResetPassword"
# NOTE(amelia): Requiring both username and email here may be
@ -1112,7 +1042,7 @@ class TaskViewTests(AdjutantAPITestCase):
@override_settings(USERNAME_IS_EMAIL=False)
def test_new_project_username_not_email(self):
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/CreateProject"
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
# notified of
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project = fake_clients.FakeProject(name="test_project")
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
user2 = mock.Mock()
user2.id = 'test_user_id_2'
user2.name = "test2@example.com"
user2.email = "test2@example.com"
user2.domain = 'default'
user2 = fake_clients.FakeUser(
name="test2@example.com", password="123",
email="test2@example.com")
user3 = mock.Mock()
user3.id = 'test_user_id_3'
user3.name = "test3@example.com"
user3.email = "test3@example.com"
user3.domain = 'default'
user3 = fake_clients.FakeUser(
name="test3@example.com", password="123",
email="test2@example.com")
project.roles = {user.id: ['project_admin', '_member_'],
user2.id: ['project_admin', '_member_'],
user3.id: ['project_mod', '_member_']}
assignments = [
fake_clients.FakeRoleAssignment(
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},
{user.id: user, user2.id: user2, user3.id: user3})
setup_identity_cache(
projects=[project], users=[user, user2, user3],
role_assignments=assignments)
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
@ -1216,7 +1166,7 @@ class TaskViewTests(AdjutantAPITestCase):
}
data = {'email': "new_test@example.com",
'roles': ['_member_']}
'roles': ['_member_'], 'project_id': project.id}
response = self.client.post(url, data, format='json', headers=headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json(), {'notes': ['created token']})
@ -1260,25 +1210,24 @@ class TaskViewTests(AdjutantAPITestCase):
send to that the update action doesn't fall over
"""
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project = fake_clients.FakeProject(name="test_project")
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
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"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
@ -1324,25 +1273,31 @@ class TaskViewTests(AdjutantAPITestCase):
Tests the sending of additional emails an admin email set in
the conf
"""
project = fake_clients.FakeProject(name="test_project")
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
user = fake_clients.FakeUser(
name="test@example.com", password="123", email="test@example.com")
user = mock.Mock()
user.id = 'test_user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
assignments = [
fake_clients.FakeRoleAssignment(
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}
),
]
project.roles = {user.id: ['project_admin', '_member_']}
setup_temp_cache({'test_project': project}, {user.id: user, })
setup_identity_cache(
projects=[project], users=[user], role_assignments=assignments)
url = "/v1/actions/InviteUser"
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "test_user_id",
@ -1392,7 +1347,7 @@ class TaskViewTests(AdjutantAPITestCase):
action is invalid.
"""
setup_temp_cache({}, {})
setup_identity_cache()
url = "/v1/actions/InviteUser"
headers = {

View File

@ -12,53 +12,125 @@
# License for the specific language governing permissions and limitations
# under the License.
from uuid import uuid4
from django.conf import settings
import mock
identity_temp_cache = {}
neutron_cache = {}
nova_cache = {}
cinder_cache = {}
def setup_temp_cache(projects, users):
default_domain = mock.Mock()
class FakeProject(object):
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.name = 'Default'
admin_user = mock.Mock()
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
projects.append(default_domain)
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.id = 'RegionOne'
region_one.name = 'RegionOne'
region_two = mock.Mock()
region_two.id = 'RegionTwo'
global identity_temp_cache
# TODO(adriant): region and project keys are name, should be ID.
identity_temp_cache = {
'i': 1,
'users': users,
'projects': projects,
'roles': {
'_member_': '_member_',
'admin': 'admin',
'project_admin': 'project_admin',
'project_mod': 'project_mod',
'heat_stack_owner': 'heat_stack_owner'
},
'users': {u.id: u for u in users},
'new_users': [],
'projects': {p.id: p for p in projects},
'new_projects': [],
'role_assignments': role_assignments,
'new_role_assignments': [],
'roles': {r.id: r for r in roles},
'regions': {
'RegionOne': region_one,
'RegionTwo': region_two
@ -72,25 +144,25 @@ def setup_temp_cache(projects, users):
class FakeManager(object):
def _project_from_id(self, project):
if isinstance(project, mock.Mock):
if isinstance(project, FakeProject):
return project
else:
return self.get_project(project)
def _role_from_id(self, role):
if isinstance(role, mock.Mock):
if isinstance(role, FakeRole):
return role
else:
return self.get_role(role)
def _user_from_id(self, user):
if isinstance(user, mock.Mock):
if isinstance(user, FakeUser):
return user
else:
return self.get_user(user)
def _domain_from_id(self, domain):
if isinstance(domain, mock.Mock):
if isinstance(domain, FakeProject) and domain.is_domain:
return domain
else:
return self.get_domain(domain)
@ -99,7 +171,8 @@ class FakeManager(object):
domain = self._domain_from_id(domain)
global identity_temp_cache
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 None
@ -110,36 +183,62 @@ class FakeManager(object):
def list_users(self, project):
project = self._project_from_id(project)
global identity_temp_cache
roles = identity_temp_cache['projects'][project.name].roles
users = []
users = {}
for user_id, user_roles in roles.items():
user = self.get_user(user_id)
user.roles = []
for assignment in identity_temp_cache['role_assignments']:
if assignment.scope['project']['id'] == project.id:
for role in user_roles:
r = mock.Mock()
r.name = role
user.roles.append(r)
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
users.append(user)
return users
r = self.find_role(assignment.role['name'])
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,
domain='default', default_project=None):
domain = self._domain_from_id(domain)
default_project = self._project_from_id(default_project)
global identity_temp_cache
user = mock.Mock()
user.id = "user_id_%s" % int(identity_temp_cache['i'])
user.name = name
user.password = password
user.email = email
user.domain = domain.id
user.default_project = default_project
user = FakeUser(
name=name, password=password, email=email,
domain_id=domain.id, default_project=default_project)
identity_temp_cache['users'][user.id] = user
identity_temp_cache['i'] += 0.5
identity_temp_cache['new_users'].append(user)
return user
def update_user_password(self, user, password):
@ -164,90 +263,115 @@ class FakeManager(object):
def find_role(self, name):
global identity_temp_cache
if identity_temp_cache['roles'].get(name, None):
role = mock.Mock()
role.name = name
return role
for role in identity_temp_cache['roles'].values():
if role.name == name:
return role
return None
def get_roles(self, user, project):
def get_roles(self, user, project, inherited=False):
user = self._user_from_id(user)
project = self._project_from_id(project)
try:
roles = []
for role in project.roles[user.id]:
r = mock.Mock()
r.name = role
global identity_temp_cache
roles = []
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)
return roles
except KeyError:
return []
return roles
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):
user = self._user_from_id(user)
global identity_temp_cache
projects = {}
for project in identity_temp_cache['projects'].values():
projects[project.id] = []
for role in project.roles[user.id]:
r = mock.Mock()
r.name = role
projects[project.id].append(r)
for assignment in identity_temp_cache['role_assignments']:
if assignment.user['id'] == user.id:
r = self.find_role(assignment.role['name'])
try:
projects[assignment.scope['project']['id']].append(r)
except KeyError:
projects[assignment.scope['project']['id']] = [r]
return projects
def add_user_role(self, user, role, project):
user = self._user_from_id(user)
role = self._role_from_id(role)
project = self._project_from_id(project)
try:
project.roles[user.id].append(role.name)
except KeyError:
project.roles[user.id] = [role.name]
def _make_role_assignment(self, user, role, project, inherited=False):
scope = {
'project': {
'id': project.id}}
if inherited:
scope['OS-INHERIT:inherited_to'] = "projects"
role_assignment = FakeRoleAssignment(
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)
role = self._role_from_id(role)
project = self._project_from_id(project)
try:
project.roles[user.id].remove(role.name)
except KeyError:
pass
role_assignment = self._make_role_assignment(user, role, project)
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):
domain = self._domain_from_id(domain)
global identity_temp_cache
for project in identity_temp_cache['projects'].values():
if (project.name.lower() == project_name.lower() and
project.domain == domain.id):
project.domain_id == domain.id):
return project
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
for project in identity_temp_cache['projects'].values():
if project.id == project_id:
return project
return identity_temp_cache['projects'].get(project_id, 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)
domain = self._domain_from_id(domain)
global identity_temp_cache
project = mock.Mock()
if p_id:
project.id = p_id
else:
identity_temp_cache['i'] += 0.5
project.id = "project_id_%s" % int(identity_temp_cache['i'])
project.name = project_name
project = FakeProject(
name=project_name, created_on=created_on, description=description,
domain_id=domain.id
)
if parent:
project.parent = parent.id
else:
project.parent = domain.id
project.domain = domain.id
project.roles = {}
identity_temp_cache['projects'][project_name] = project
project.parent_id = parent.id
identity_temp_cache['projects'][project.id] = project
identity_temp_cache['new_projects'].append(project)
return project
def update_project(self, project, **kwargs):

View File

@ -17,7 +17,9 @@ import mock
from rest_framework import status
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,
modify_dict_settings)
@ -42,28 +44,34 @@ class ModifySettingsTests(AdjutantAPITestCase):
Test override reset, by changing the reset password blacklisted roles
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="test_password",
email="test@example.com")
user2 = mock.Mock()
user2.id = 'user_2'
user2.name = "admin@example.com"
user2.email = "admin@example.com"
user2.domain = "default"
user2.password = "admin_password"
user2 = fake_clients.FakeUser(
name="admin@example.com", password="admin_password",
email="admin@example.com")
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['test_role'], user2.id: ['admin']}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project},
{user.id: user, user2.id: user2})
test_role = fake_clients.FakeRole("test_role")
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"
data = {'email': "test@example.com"}
@ -103,21 +111,20 @@ class ModifySettingsTests(AdjutantAPITestCase):
Test override reset, by changing the reset password blacklisted roles
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "admin@example.com"
user.email = "admin@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="admin@example.com", password="admin_password",
email="admin@example.com")
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['admin']}
project = fake_clients.FakeProject(name="test_project")
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"
data = {'email': 'admin@example.com'}
@ -151,28 +158,34 @@ class ModifySettingsTests(AdjutantAPITestCase):
Test override reset, by changing the reset password blacklisted roles
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="test_password",
email="test@example.com")
user2 = mock.Mock()
user2.id = 'user_2'
user2.name = "admin@example.com"
user2.email = "admin@example.com"
user2.domain = "default"
user2.password = "admin_password"
user2 = fake_clients.FakeUser(
name="admin@example.com", password="admin_password",
email="admin@example.com")
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['test_role'], user2.id: ['admin']}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project},
{user.id: user, user2.id: user2})
test_role = fake_clients.FakeRole("test_role")
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"
data = {'email': "test@example.com"}
@ -191,31 +204,30 @@ class ModifySettingsTests(AdjutantAPITestCase):
Tests the update operator using email sending
"""
user = mock.Mock()
user.id = 'user_id'
user.name = "test@example.com"
user.email = "test@example.com"
user.domain = 'default'
user.password = "test_password"
user = fake_clients.FakeUser(
name="test@example.com", password="test_password",
email="test@example.com")
project = mock.Mock()
project.id = 'test_project_id'
project.name = 'test_project'
project.domain = 'default'
project.roles = {user.id: ['project_admin']}
project = fake_clients.FakeProject(name="test_project")
setup_temp_cache({'test_project': project},
{user.id: user})
assignment = fake_clients.FakeRoleAssignment(
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"
data = {'new_email': "new_test@example.com"}
headers = {
'project_name': "test_project",
'project_id': "test_project_id",
'project_id': project.id,
'roles': "project_admin,_member_,project_mod",
'username': "test@example.com",
'user_id': "user_id",
'user_id': user.id,
'authenticated': True
}

View File

@ -20,6 +20,8 @@ from django.test.utils import override_settings
from django.test import TestCase
from rest_framework.test import APITestCase
from adjutant.common.tests import fake_clients
class modify_dict_settings(override_settings):
"""
@ -199,6 +201,12 @@ class AdjutantTestCase(TestCase, TestCaseMixin):
cls._remove_settings_changes()
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):
"""
@ -214,3 +222,9 @@ class AdjutantAPITestCase(APITestCase, TestCaseMixin):
def tearDownClass(cls):
cls._remove_settings_changes()
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
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
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}
users = {}
user_assignments = self.ks_client.role_assignments.list(
project=project)
for assignment in user_assignments:
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']], ]
if not user:
user = self.ks_client.users.get(
assignment.user['id'])
user.roles = []
user.inherited_roles = []
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:
# Just means the assignment is a group, so ignore it.
pass
@ -96,6 +116,46 @@ class IdentityManager(object):
return []
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,
default_project=None):
@ -126,8 +186,21 @@ class IdentityManager(object):
role = None
return role
def get_roles(self, user, project):
return self.ks_client.roles.list(user=user, project=project)
def get_roles(self, user, project, inherited=False):
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):
"""
@ -146,15 +219,25 @@ class IdentityManager(object):
return projects
def add_user_role(self, user, role, project):
def add_user_role(self, user, role, project, inherited=False):
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:
# Conflict is ok, it means the user already has this role.
pass
def remove_user_role(self, user, role, project):
self.ks_client.roles.revoke(role, user=user, project=project)
def remove_user_role(self, user, role, project, inherited=False):
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):
try:
@ -172,12 +255,36 @@ class IdentityManager(object):
except ks_exceptions.NotFound:
return None
def get_project(self, project_id):
def get_project(self, project_id, subtree_as_ids=False,
parents_as_ids=False):
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:
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,
enabled=None, **kwargs):
try:
@ -189,9 +296,10 @@ class IdentityManager(object):
return None
def create_project(self, project_name, created_on, parent=None,
domain=None):
domain=None, description=""):
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
def get_domain(self, domain_id):