Addressing 4.3 "Admin User Password Reset Permitted"
* switching to the keystone v3 api * various fixes to tests after user_store changes * minor pep8 cleanup Change-Id: Ie40cfcae0e392aef9a3e92da4acd4f0a21a627b0
This commit is contained in:
parent
854c6f6322
commit
1e75d348f9
@ -51,7 +51,8 @@ KEYSTONE:
|
||||
username: admin
|
||||
password: openstack
|
||||
project_name: admin
|
||||
auth_url: http://localhost:5000/v2.0
|
||||
# MUST BE V3 API:
|
||||
auth_url: http://localhost:5000/v3
|
||||
DEFAULT_REGION: RegionOne
|
||||
|
||||
TOKEN_SUBMISSION_URL: http://192.168.122.160:8080/token/
|
||||
@ -174,11 +175,14 @@ TASK_SETTINGS:
|
||||
ACTION_SETTINGS:
|
||||
NewUser:
|
||||
allowed_roles:
|
||||
- Member
|
||||
- project_owner
|
||||
- project_mod
|
||||
- heat_stack_owner
|
||||
- _member_
|
||||
ResetUser:
|
||||
blacklisted_roles:
|
||||
- Admin
|
||||
- admin
|
||||
DefaultProjectResources:
|
||||
RegionOne:
|
||||
network_name: somenetwork
|
||||
|
@ -12,13 +12,16 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from stacktask.actions import user_store
|
||||
from stacktask.actions import serializers
|
||||
from django.conf import settings
|
||||
|
||||
from jsonfield import JSONField
|
||||
from logging import getLogger
|
||||
|
||||
from stacktask.actions import serializers
|
||||
from stacktask.actions import user_store
|
||||
|
||||
|
||||
class Action(models.Model):
|
||||
@ -475,8 +478,8 @@ class NewProject(UserNameAction):
|
||||
def _submit(self, token_data):
|
||||
"""
|
||||
The submit action is prformed when a token is submitted.
|
||||
This is done for a user account only, and so should now only set up the user,
|
||||
not the project, which was done in approve.
|
||||
This is done for a user account only, and so should now only
|
||||
set up the user, not the project, which was done in approve.
|
||||
"""
|
||||
|
||||
id_manager = user_store.IdentityManager()
|
||||
@ -552,13 +555,25 @@ class ResetUser(UserNameAction):
|
||||
'email'
|
||||
]
|
||||
|
||||
blacklist = settings.ACTION_SETTINGS.get(
|
||||
'ResetUser', {}).get("blacklisted_roles", {})
|
||||
|
||||
def _validate(self):
|
||||
id_manager = user_store.IdentityManager()
|
||||
|
||||
user = id_manager.find_user(self.username)
|
||||
|
||||
if user:
|
||||
if user.email == self.email:
|
||||
roles = id_manager.get_all_roles(user)
|
||||
|
||||
user_roles = []
|
||||
for project, roles in roles.iteritems():
|
||||
user_roles.extend(role.name for role in roles)
|
||||
|
||||
if set(self.blacklist) & set(user_roles):
|
||||
valid = False
|
||||
self.add_note('Cannot reset users with blacklisted roles.')
|
||||
elif user.email == self.email:
|
||||
valid = True
|
||||
self.action.need_token = True
|
||||
self.set_token_fields(["password"])
|
||||
@ -693,7 +708,6 @@ class EditUserRoles(UserIdAction):
|
||||
|
||||
if self.action.state == "default":
|
||||
try:
|
||||
#user = id_manager.find_user(self.username)
|
||||
user = self._get_target_user()
|
||||
|
||||
roles = []
|
||||
@ -738,7 +752,8 @@ class EditUserRoles(UserIdAction):
|
||||
% (self.user_id, self.roles, self.project_id))
|
||||
|
||||
|
||||
# Update settings dict with tuples in the format: (<ActionClass>, <ActionSerializer>)
|
||||
# Update settings dict with tuples in the format:
|
||||
# (<ActionClass>, <ActionSerializer>)
|
||||
def register_action_class(action_class, serializer_class):
|
||||
data = {}
|
||||
data[action_class.__name__] = (action_class, serializer_class)
|
||||
|
@ -12,19 +12,20 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from keystoneclient.v2_0 import client
|
||||
from neutronclient.v2_0 import client as neutron_client
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from keystoneclient.v3 import client as client_v3
|
||||
|
||||
from neutronclient.v2_0 import client as neutron_client
|
||||
|
||||
|
||||
def get_keystoneclient():
|
||||
# TODO(Adriant): Add region support.
|
||||
auth = client.Client(
|
||||
auth = client_v3.Client(
|
||||
username=settings.KEYSTONE['username'],
|
||||
password=settings.KEYSTONE['password'],
|
||||
tenant_name=settings.KEYSTONE['project_name'],
|
||||
auth_url=settings.KEYSTONE['auth_url'],
|
||||
project_name=settings.KEYSTONE['project_name'],
|
||||
auth_url=settings.KEYSTONE['auth_url_v3'],
|
||||
region_name=settings.DEFAULT_REGION
|
||||
)
|
||||
return auth
|
||||
|
@ -13,13 +13,15 @@
|
||||
# under the License.
|
||||
|
||||
from django.test import TestCase
|
||||
from stacktask.api.models import Task
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
from stacktask.api.v1 import tests
|
||||
from stacktask.actions.tenant_setup.models import (
|
||||
DefaultProjectResources, AddAdminToProject)
|
||||
|
||||
import mock
|
||||
|
||||
from stacktask.actions.tenant_setup.models import (
|
||||
AddAdminToProject, DefaultProjectResources)
|
||||
from stacktask.api.models import Task
|
||||
from stacktask.api.v1 import tests
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
|
||||
|
||||
neutron_cache = {}
|
||||
|
||||
@ -263,7 +265,7 @@ class TenantSetupActionTests(TestCase):
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
project = tests.temp_cache['projects']['test_project']
|
||||
self.assertEquals(project.roles['admin'], ['admin'])
|
||||
self.assertEquals(project.roles['user_id_0'], ['admin'])
|
||||
|
||||
@mock.patch('stacktask.actions.tenant_setup.models.IdentityManager',
|
||||
FakeManager)
|
||||
@ -292,10 +294,10 @@ class TenantSetupActionTests(TestCase):
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
project = tests.temp_cache['projects']['test_project']
|
||||
self.assertEquals(project.roles['admin'], ['admin'])
|
||||
self.assertEquals(project.roles['user_id_0'], ['admin'])
|
||||
|
||||
action.post_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
project = tests.temp_cache['projects']['test_project']
|
||||
self.assertEquals(project.roles['admin'], ['admin'])
|
||||
self.assertEquals(project.roles['user_id_0'], ['admin'])
|
||||
|
@ -13,13 +13,15 @@
|
||||
# under the License.
|
||||
|
||||
from django.test import TestCase
|
||||
from stacktask.api.models import Task
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
from stacktask.api.v1 import tests
|
||||
from stacktask.actions.models import (
|
||||
NewUser, NewProject, ResetUser, EditUserRoles)
|
||||
|
||||
import mock
|
||||
|
||||
from stacktask.actions.models import (
|
||||
EditUserRoles, NewProject, NewUser, ResetUser)
|
||||
from stacktask.api.models import Task
|
||||
from stacktask.api.v1 import tests
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
|
||||
|
||||
class ActionTests(TestCase):
|
||||
|
||||
@ -60,14 +62,15 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
self.assertEquals(len(tests.temp_cache['users']), 2)
|
||||
# The new user id in this case will be "user_id_1"
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']['test@example.com'].email,
|
||||
tests.temp_cache['users']["user_id_1"].email,
|
||||
'test@example.com')
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']['test@example.com'].password,
|
||||
tests.temp_cache['users']["user_id_1"].password,
|
||||
'123456')
|
||||
|
||||
self.assertEquals(project.roles['test@example.com'], ['Member'])
|
||||
self.assertEquals(project.roles["user_id_1"], ['Member'])
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
FakeManager)
|
||||
@ -82,10 +85,10 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.username: user})
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0", keystone_user={
|
||||
@ -110,7 +113,7 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(project.roles[user.username], ['Member'])
|
||||
self.assertEquals(project.roles[user.id], ['Member'])
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
FakeManager)
|
||||
@ -124,15 +127,15 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.roles = {user.username: ['Member']}
|
||||
project.roles = {user.id: ['Member']}
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.username: user})
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0", keystone_user={
|
||||
@ -158,7 +161,7 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(project.roles[user.username], ['Member'])
|
||||
self.assertEquals(project.roles[user.id], ['Member'])
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
FakeManager)
|
||||
@ -192,8 +195,6 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
self.assertEquals('admin' in tests.temp_cache['users'], True)
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
FakeManager)
|
||||
def test_new_project(self):
|
||||
@ -226,19 +227,18 @@ class ActionTests(TestCase):
|
||||
self.assertEquals(
|
||||
tests.temp_cache['projects']['test_project'].name,
|
||||
'test_project')
|
||||
self.assertEquals('admin' in tests.temp_cache['users'], True)
|
||||
self.assertEquals(task.cache, {'project_id': 2})
|
||||
self.assertEquals(task.cache, {'project_id': "project_id_1"})
|
||||
|
||||
token_data = {'password': '123456'}
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
print tests.temp_cache['users']
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']['test@example.com'].email,
|
||||
tests.temp_cache['users']["user_id_1"].email,
|
||||
'test@example.com')
|
||||
project = tests.temp_cache['projects']['test_project']
|
||||
self.assertEquals(
|
||||
sorted(project.roles['test@example.com']),
|
||||
sorted(project.roles["user_id_1"]),
|
||||
sorted(['Member', '_member_', 'project_owner',
|
||||
'project_mod', 'heat_stack_owner']))
|
||||
|
||||
@ -272,27 +272,25 @@ class ActionTests(TestCase):
|
||||
self.assertEquals(
|
||||
tests.temp_cache['projects']['test_project'].name,
|
||||
'test_project')
|
||||
self.assertEquals('admin' in tests.temp_cache['users'], True)
|
||||
self.assertEquals(task.cache, {'project_id': 2})
|
||||
self.assertEquals(task.cache, {'project_id': "project_id_1"})
|
||||
|
||||
action.post_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
self.assertEquals(
|
||||
tests.temp_cache['projects']['test_project'].name,
|
||||
'test_project')
|
||||
self.assertEquals('admin' in tests.temp_cache['users'], True)
|
||||
self.assertEquals(task.cache, {'project_id': 2})
|
||||
self.assertEquals(task.cache, {'project_id': "project_id_1"})
|
||||
|
||||
token_data = {'password': '123456'}
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']['test@example.com'].email,
|
||||
tests.temp_cache['users']["user_id_1"].email,
|
||||
'test@example.com')
|
||||
project = tests.temp_cache['projects']['test_project']
|
||||
self.assertEquals(
|
||||
sorted(project.roles['test@example.com']),
|
||||
sorted(project.roles["user_id_1"]),
|
||||
sorted(['Member', '_member_', 'project_owner',
|
||||
'project_mod', 'heat_stack_owner']))
|
||||
|
||||
@ -305,10 +303,10 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0", keystone_user={
|
||||
@ -330,18 +328,18 @@ class ActionTests(TestCase):
|
||||
self.assertEquals(
|
||||
tests.temp_cache['projects']['test_project'].name,
|
||||
'test_project')
|
||||
self.assertEquals(task.cache, {'project_id': 2})
|
||||
self.assertEquals(task.cache, {'project_id': "project_id_1"})
|
||||
|
||||
token_data = {'password': '123456'}
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']['test@example.com'].email,
|
||||
tests.temp_cache['users'][user.id].email,
|
||||
'test@example.com')
|
||||
project = tests.temp_cache['projects']['test_project']
|
||||
self.assertEquals(
|
||||
sorted(project.roles['test@example.com']),
|
||||
sorted(project.roles[user.id]),
|
||||
sorted(['Member', '_member_', 'project_owner',
|
||||
'project_mod', 'heat_stack_owner']))
|
||||
|
||||
@ -386,11 +384,11 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "gibberish"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0", keystone_user={
|
||||
@ -415,7 +413,7 @@ class ActionTests(TestCase):
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']['test@example.com'].password,
|
||||
tests.temp_cache['users'][user.id].password,
|
||||
'123456')
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
@ -462,7 +460,7 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
@ -491,8 +489,8 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(len(project.roles[user.username]), 2)
|
||||
self.assertEquals(set(project.roles[user.username]),
|
||||
self.assertEquals(len(project.roles[user.id]), 2)
|
||||
self.assertEquals(set(project.roles[user.id]),
|
||||
set(['Member', 'project_mod']))
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
@ -503,13 +501,13 @@ class ActionTests(TestCase):
|
||||
"""
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.roles = {user.username: ['Member', 'project_mod']}
|
||||
project.roles = {user.id: ['Member', 'project_mod']}
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
@ -538,8 +536,8 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(len(project.roles[user.username]), 2)
|
||||
self.assertEquals(set(project.roles[user.username]),
|
||||
self.assertEquals(len(project.roles[user.id]), 2)
|
||||
self.assertEquals(set(project.roles[user.id]),
|
||||
set(['Member', 'project_mod']))
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
@ -551,13 +549,13 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.roles = {user.username: ['Member', 'project_mod']}
|
||||
project.roles = {user.id: ['Member', 'project_mod']}
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
@ -585,7 +583,7 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(project.roles[user.username], ['Member'])
|
||||
self.assertEquals(project.roles[user.id], ['Member'])
|
||||
|
||||
@mock.patch('stacktask.actions.models.user_store.IdentityManager',
|
||||
FakeManager)
|
||||
@ -596,13 +594,13 @@ class ActionTests(TestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.roles = {user.username: ['Member']}
|
||||
project.roles = {user.id: ['Member']}
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
@ -631,4 +629,4 @@ class ActionTests(TestCase):
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(project.roles[user.username], ['Member'])
|
||||
self.assertEquals(project.roles[user.id], ['Member'])
|
||||
|
@ -12,11 +12,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack_clients import get_keystoneclient
|
||||
from collections import defaultdict
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from keystoneclient.openstack.common.apiclient import (
|
||||
exceptions as ks_exceptions
|
||||
)
|
||||
from django.conf import settings
|
||||
|
||||
from openstack_clients import get_keystoneclient
|
||||
|
||||
|
||||
def get_managable_roles(user_roles):
|
||||
@ -58,14 +62,38 @@ class IdentityManager(object):
|
||||
user = None
|
||||
return user
|
||||
|
||||
def list_users(self, project):
|
||||
try:
|
||||
roles = self.ks_client.roles.list()
|
||||
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']], ]
|
||||
users[user.id] = user
|
||||
except AttributeError:
|
||||
# Just means the assignment is a group, so ignore it.
|
||||
pass
|
||||
except ks_exceptions.NotFound:
|
||||
users = []
|
||||
return users.values()
|
||||
|
||||
def create_user(self, name, password, email, project_id):
|
||||
user = self.ks_client.users.create(
|
||||
name=name, password=password,
|
||||
email=email, tenant_id=project_id)
|
||||
email=email, project_id=project_id)
|
||||
return user
|
||||
|
||||
def update_user_password(self, user, password):
|
||||
self.ks_client.users.update_password(user, password)
|
||||
self.ks_client.users.update(user, password=password)
|
||||
|
||||
def find_role(self, name):
|
||||
try:
|
||||
@ -75,33 +103,48 @@ class IdentityManager(object):
|
||||
return role
|
||||
|
||||
def get_roles(self, user, project):
|
||||
return self.ks_client.roles.roles_for_user(user, tenant=project)
|
||||
return self.ks_client.roles.list(user=user, project=project)
|
||||
|
||||
def get_all_roles(self, user):
|
||||
"""
|
||||
Returns roles for a given user across all projects.
|
||||
"""
|
||||
roles = self.ks_client.roles.list()
|
||||
role_dict = {role.id: role for role in roles}
|
||||
|
||||
user_assignments = self.ks_client.role_assignments.list(user=user)
|
||||
projects = defaultdict([])
|
||||
for assignment in user_assignments:
|
||||
project = assignment.scope['project']['id']
|
||||
projects[project].append(role_dict[assignment.role['id']])
|
||||
|
||||
return projects
|
||||
|
||||
def add_user_role(self, user, role, project_id):
|
||||
try:
|
||||
self.ks_client.roles.add_user_role(user, role, project_id)
|
||||
self.ks_client.roles.grant(role, user=user, project=project_id)
|
||||
except ks_exceptions.Conflict:
|
||||
# Conflict is ok, it means the user already has this role.
|
||||
pass
|
||||
|
||||
def remove_user_role(self, user, role, project_id):
|
||||
self.ks_client.roles.remove_user_role(user, role, project_id)
|
||||
self.ks_client.roles.revoke(role, user=user, project=project_id)
|
||||
|
||||
def find_project(self, project_name):
|
||||
try:
|
||||
project = self.ks_client.tenants.find(name=project_name)
|
||||
project = self.ks_client.projects.find(name=project_name)
|
||||
except ks_exceptions.NotFound:
|
||||
project = None
|
||||
return project
|
||||
|
||||
def get_project(self, project_id):
|
||||
try:
|
||||
project = self.ks_client.tenants.get(project_id)
|
||||
project = self.ks_client.projects.get(project_id)
|
||||
except ks_exceptions.NotFound:
|
||||
project = None
|
||||
return project
|
||||
|
||||
def create_project(self, project_name, created_on):
|
||||
project = self.ks_client.tenants.create(project_name,
|
||||
created_on=created_on)
|
||||
project = self.ks_client.projects.create(project_name,
|
||||
created_on=created_on)
|
||||
return project
|
||||
|
@ -12,14 +12,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.utils import timezone
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
from rest_framework.response import Response
|
||||
|
||||
from stacktask.api.v1 import tasks
|
||||
from stacktask.api import utils
|
||||
from stacktask.api import models
|
||||
from stacktask.actions import user_store
|
||||
from stacktask.api import models
|
||||
from stacktask.api import utils
|
||||
from stacktask.api.v1 import tasks
|
||||
|
||||
|
||||
class UserList(tasks.InviteUser):
|
||||
@ -35,11 +36,10 @@ class UserList(tasks.InviteUser):
|
||||
project = id_manager.get_project(project_id)
|
||||
|
||||
active_emails = set()
|
||||
for user in project.list_users():
|
||||
for user in id_manager.list_users(project):
|
||||
skip = False
|
||||
self.logger.info(user)
|
||||
roles = []
|
||||
for role in id_manager.get_roles(user, project):
|
||||
for role in user.roles:
|
||||
if role.name in role_blacklist:
|
||||
skip = True
|
||||
continue
|
||||
@ -52,7 +52,7 @@ class UserList(tasks.InviteUser):
|
||||
user_status = 'Active' if enabled else 'Account Disabled'
|
||||
active_emails.add(email)
|
||||
user_list.append({'id': user.id,
|
||||
'name': user.username,
|
||||
'name': user.name,
|
||||
'email': email,
|
||||
'roles': roles,
|
||||
'cohort': 'Member',
|
||||
@ -124,7 +124,7 @@ class UserDetail(tasks.TaskView):
|
||||
if not roles or roles_blacklisted:
|
||||
return Response(no_user, status=404)
|
||||
return Response({'id': user.id,
|
||||
"username": user.username,
|
||||
"username": user.name,
|
||||
"email": getattr(user, 'email', ''),
|
||||
'roles': roles})
|
||||
|
||||
|
@ -20,12 +20,12 @@ temp_cache = {}
|
||||
|
||||
def setup_temp_cache(projects, users):
|
||||
admin_user = mock.Mock()
|
||||
admin_user.id = 0
|
||||
admin_user.username = 'admin'
|
||||
admin_user.id = 'user_id_0'
|
||||
admin_user.name = 'admin'
|
||||
admin_user.password = 'password'
|
||||
admin_user.email = 'admin@example.com'
|
||||
|
||||
users.update({admin_user.username: admin_user})
|
||||
users.update({admin_user.id: admin_user})
|
||||
|
||||
global temp_cache
|
||||
|
||||
@ -59,7 +59,7 @@ class FakeProject():
|
||||
usernames.append(username)
|
||||
users = []
|
||||
for user in temp_cache['users'].values():
|
||||
if user.username in usernames:
|
||||
if user.name in usernames:
|
||||
users.append(user)
|
||||
return users
|
||||
|
||||
@ -68,38 +68,61 @@ class FakeManager(object):
|
||||
|
||||
def find_user(self, name):
|
||||
global temp_cache
|
||||
return temp_cache['users'].get(name, None)
|
||||
for user in temp_cache['users'].values():
|
||||
if user.name == name:
|
||||
return user
|
||||
return None
|
||||
|
||||
def get_user(self, user_id):
|
||||
global temp_cache
|
||||
return temp_cache['users'].get(user_id, None)
|
||||
|
||||
def list_users(self, project):
|
||||
global temp_cache
|
||||
roles = temp_cache['projects'][project.name].roles
|
||||
users = []
|
||||
|
||||
for user_id, roles in roles.iteritems():
|
||||
user = self.get_user(user_id)
|
||||
user.roles = []
|
||||
|
||||
for role in roles:
|
||||
r = mock.Mock()
|
||||
r.name = role
|
||||
user.roles.append(r)
|
||||
return users
|
||||
|
||||
def create_user(self, name, password, email, project_id):
|
||||
global temp_cache
|
||||
user = mock.Mock()
|
||||
temp_cache['i'] += 1
|
||||
user.id = temp_cache['i']
|
||||
user.username = name
|
||||
user.id = "user_id_%s" % int(temp_cache['i'])
|
||||
user.name = name
|
||||
user.password = password
|
||||
user.email = email
|
||||
user.default_project = project_id
|
||||
temp_cache['users'][name] = user
|
||||
temp_cache['users'][user.id] = user
|
||||
|
||||
temp_cache['i'] += 0.5
|
||||
return user
|
||||
|
||||
def update_user_password(self, user, password):
|
||||
global temp_cache
|
||||
user = temp_cache['users'][user.username]
|
||||
user = temp_cache['users'][user.id]
|
||||
user.password = password
|
||||
|
||||
def find_role(self, name):
|
||||
global temp_cache
|
||||
return temp_cache['roles'].get(name, None)
|
||||
if temp_cache['roles'].get(name, None):
|
||||
role = mock.Mock()
|
||||
role.name = name
|
||||
return role
|
||||
return None
|
||||
|
||||
def get_roles(self, user, project):
|
||||
global temp_cache
|
||||
try:
|
||||
roles = []
|
||||
for role in project.roles[user.username]:
|
||||
for role in project.roles[user.id]:
|
||||
r = mock.Mock()
|
||||
r.name = role
|
||||
roles.append(r)
|
||||
@ -107,17 +130,29 @@ class FakeManager(object):
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
def get_all_roles(self, user):
|
||||
global temp_cache
|
||||
projects = {}
|
||||
for project in 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)
|
||||
|
||||
return projects
|
||||
|
||||
def add_user_role(self, user, role, project_id):
|
||||
project = self.get_project(project_id)
|
||||
try:
|
||||
project.roles[user.username].append(role)
|
||||
project.roles[user.id].append(role.name)
|
||||
except KeyError:
|
||||
project.roles[user.username] = [role]
|
||||
project.roles[user.id] = [role.name]
|
||||
|
||||
def remove_user_role(self, user, role, project_id):
|
||||
project = self.get_project(project_id)
|
||||
try:
|
||||
project.roles[user.username].remove(role)
|
||||
project.roles[user.id].remove(role.name)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@ -137,8 +172,8 @@ class FakeManager(object):
|
||||
if p_id:
|
||||
project.id = p_id
|
||||
else:
|
||||
temp_cache['i'] += 1
|
||||
project.id = temp_cache['i']
|
||||
temp_cache['i'] += 0.5
|
||||
project.id = "project_id_%s" % int(temp_cache['i'])
|
||||
project.name = project_name
|
||||
project.roles = {}
|
||||
temp_cache['projects'][project_name] = project
|
||||
|
@ -12,13 +12,19 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
import mock
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from stacktask.api.models import Task, Token
|
||||
import mock
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
import json
|
||||
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
|
||||
|
||||
@ -121,11 +127,11 @@ class AdminAPITests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/ResetPassword"
|
||||
data = {'email': "test@example.com"}
|
||||
@ -154,11 +160,11 @@ class AdminAPITests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/ResetPassword"
|
||||
data = {'email': "test@example.com"}
|
||||
@ -373,7 +379,7 @@ class AdminAPITests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
@ -383,7 +389,7 @@ class AdminAPITests(APITestCase):
|
||||
user2.email = "test2@example.com"
|
||||
user2.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user, user2.name: user2})
|
||||
setup_temp_cache({}, {user.id: user, user2.name: user2})
|
||||
|
||||
url = "/v1/actions/ResetPassword"
|
||||
data = {'email': "test@example.com"}
|
||||
@ -429,11 +435,11 @@ class AdminAPITests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/ResetPassword"
|
||||
data = {'email': "test@example.com"}
|
||||
@ -982,3 +988,33 @@ class AdminAPITests(APITestCase):
|
||||
url, params, format='json', headers=headers
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@mock.patch(
|
||||
'stacktask.actions.models.user_store.IdentityManager', FakeManager)
|
||||
@mock.patch(
|
||||
'stacktask.actions.tenant_setup.models.IdentityManager', FakeManager)
|
||||
def test_reset_admin(self):
|
||||
"""
|
||||
Ensure that you cannot issue a password reset for an
|
||||
admin user.
|
||||
"""
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.roles = {user.id: ['admin']}
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
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, None)
|
||||
self.assertEqual(0, Token.objects.count())
|
||||
|
@ -12,10 +12,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from stacktask.api.models import Token
|
||||
import mock
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
|
||||
|
||||
@ -118,11 +120,11 @@ class OpenstackAPITests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
headers = {
|
||||
'project_name': "test_project",
|
||||
|
@ -12,10 +12,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from stacktask.api.models import Task, Token
|
||||
import mock
|
||||
from stacktask.api.v1.tests import FakeManager, setup_temp_cache
|
||||
|
||||
|
||||
@ -140,10 +142,10 @@ class TaskViewTests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.username: user})
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/InviteUser"
|
||||
headers = {
|
||||
@ -176,15 +178,15 @@ class TaskViewTests(APITestCase):
|
||||
"""
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.roles = {user.username: ['Member']}
|
||||
project.roles = {user.id: ['Member']}
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.username: user})
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/InviteUser"
|
||||
headers = {
|
||||
@ -297,10 +299,10 @@ class TaskViewTests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/InviteUser"
|
||||
headers = {
|
||||
@ -344,11 +346,11 @@ class TaskViewTests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/ResetPassword"
|
||||
data = {'email': "test@example.com"}
|
||||
@ -374,11 +376,11 @@ class TaskViewTests(APITestCase):
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id'
|
||||
user.username = "test@example.com"
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.password = "test_password"
|
||||
|
||||
setup_temp_cache({}, {user.username: user})
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
# Submit password reset
|
||||
url = "/v1/actions/ResetPassword"
|
||||
|
@ -63,7 +63,8 @@ KEYSTONE = {
|
||||
'username': 'admin',
|
||||
'password': 'openstack',
|
||||
'project_name': 'admin',
|
||||
'auth_url': "http://localhost:5000/v2.0"
|
||||
'auth_url': "http://localhost:5000/v2.0",
|
||||
'auth_url_v3': "http://localhost:5000/v3"
|
||||
}
|
||||
|
||||
DEFAULT_REGION = 'RegionOne'
|
||||
@ -135,6 +136,9 @@ ACTION_SETTINGS = {
|
||||
'NewUser': {
|
||||
'allowed_roles': ['project_mod', 'project_owner', "Member"]
|
||||
},
|
||||
'ResetUser': {
|
||||
'blacklisted_roles': ['admin', "Admin"]
|
||||
},
|
||||
'DefaultProjectResources': {
|
||||
'RegionOne': {
|
||||
'DNS_NAMESERVERS': ['193.168.1.2', '193.168.1.3'],
|
||||
|
Loading…
Reference in New Issue
Block a user