Added Update Email task and action
The task only allows the current user to update their own email address, a confirmation email is sent to the new address before the switch. Change-Id: I62b169d262c6455ffec96bdb29e254279e973851
This commit is contained in:
parent
58ac750bcc
commit
829d6ac30e
@ -125,6 +125,14 @@ Basic default endpoints for the TaskViews.
|
||||
* unauthenticated endpoint
|
||||
* auto-approved
|
||||
* issue a uri+token to user email to reset password
|
||||
* ../v1/actions/UpdateEmail - GET
|
||||
* return a json describing the actions and required fields for the endpoint.
|
||||
* ../v1/actions/UpdateEmail - POST
|
||||
* Authenticated but open to any user
|
||||
* auto-approved
|
||||
* takes an email address
|
||||
* issue a uri+token to new email to update to that email
|
||||
|
||||
|
||||
#### OpenStack Style TaskView Endpoints:
|
||||
|
||||
|
@ -70,6 +70,7 @@ ACTIVE_TASKVIEWS:
|
||||
- UserList
|
||||
- RoleList
|
||||
- SignUp
|
||||
- UserUpdateEmail
|
||||
|
||||
DEFAULT_TASK_SETTINGS:
|
||||
emails:
|
||||
@ -297,6 +298,24 @@ TASK_SETTINGS:
|
||||
token: null
|
||||
role_blacklist:
|
||||
- admin
|
||||
update_email:
|
||||
duplicate_policy: cancel
|
||||
additional_actions:
|
||||
- SendAdditionalEmailAction
|
||||
emails:
|
||||
initial: null
|
||||
token:
|
||||
subject: Confirm OpenStack Email Update
|
||||
template: email_update_token.txt
|
||||
completed:
|
||||
subject: OpenStack Email Updated
|
||||
template: email_update_completed.txt
|
||||
action_settings:
|
||||
SendAdditionalEmailAction:
|
||||
initial:
|
||||
subject: OpenStack Email Update Requested
|
||||
template: email_update_started.txt
|
||||
email_current_user: True
|
||||
|
||||
# mapping between roles and managable roles
|
||||
ROLES_MAPPING:
|
||||
|
@ -113,6 +113,12 @@ class IdentityManager(object):
|
||||
def update_user_password(self, user, password):
|
||||
self.ks_client.users.update(user, password=password)
|
||||
|
||||
def update_user_email(self, user, email):
|
||||
self.ks_client.users.update(user, email=email)
|
||||
|
||||
def update_user_name(self, user, name):
|
||||
self.ks_client.users.update(user, name=name)
|
||||
|
||||
def find_role(self, name):
|
||||
try:
|
||||
role = self.ks_client.roles.find(name=name)
|
||||
|
@ -331,6 +331,30 @@ class UserMixin(ResourceMixin):
|
||||
(e, self.username))
|
||||
raise
|
||||
|
||||
def update_email(self, email, user=None):
|
||||
id_manager = user_store.IdentityManager()
|
||||
try:
|
||||
if not user:
|
||||
user = self.find_user()
|
||||
id_manager.update_user_email(user, email)
|
||||
except Exception as e:
|
||||
self.add_note(
|
||||
"Error: '%s' while changing email for user: %s" %
|
||||
(e, self.username))
|
||||
raise
|
||||
|
||||
def update_user_name(self, username, user=None):
|
||||
id_manager = user_store.IdentityManager()
|
||||
try:
|
||||
if not user:
|
||||
user = self.find_user()
|
||||
id_manager.update_user_name(user, username)
|
||||
except Exception as e:
|
||||
self.add_note(
|
||||
"Error: '%s' while changing username for user: %s" %
|
||||
(e, self.username))
|
||||
raise
|
||||
|
||||
|
||||
class ProjectMixin(ResourceMixin):
|
||||
"""Mixin with functions for projects."""
|
||||
|
@ -18,7 +18,8 @@ from stacktask.actions.v1 import serializers
|
||||
from stacktask.actions.v1.projects import (
|
||||
NewProjectWithUserAction, AddDefaultUsersToProjectAction)
|
||||
from stacktask.actions.v1.users import (
|
||||
EditUserRolesAction, NewUserAction, ResetUserPasswordAction)
|
||||
EditUserRolesAction, NewUserAction, ResetUserPasswordAction,
|
||||
UpdateUserEmailAction)
|
||||
from stacktask.actions.v1.resources import (
|
||||
NewDefaultNetworkAction, NewProjectDefaultNetworkAction,
|
||||
SetProjectQuotaAction)
|
||||
@ -44,6 +45,8 @@ register_action_class(
|
||||
register_action_class(NewUserAction, serializers.NewUserSerializer)
|
||||
register_action_class(ResetUserPasswordAction, serializers.ResetUserSerializer)
|
||||
register_action_class(EditUserRolesAction, serializers.EditUserRolesSerializer)
|
||||
register_action_class(
|
||||
UpdateUserEmailAction, serializers.UpdateUserEmailSerializer)
|
||||
|
||||
# Register Resource actions:
|
||||
register_action_class(
|
||||
|
@ -91,3 +91,7 @@ class SetProjectQuotaSerializer(serializers.Serializer):
|
||||
|
||||
class SendAdditionalEmailSerializer(serializers.Serializer):
|
||||
pass
|
||||
|
||||
|
||||
class UpdateUserEmailSerializer(BaseUserIdSerializer):
|
||||
new_email = serializers.EmailField()
|
||||
|
@ -17,7 +17,8 @@ import mock
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from stacktask.actions.v1.users import (
|
||||
EditUserRolesAction, NewUserAction, ResetUserPasswordAction)
|
||||
EditUserRolesAction, NewUserAction, ResetUserPasswordAction,
|
||||
UpdateUserEmailAction)
|
||||
from stacktask.api.models import Task
|
||||
from stacktask.api.v1 import tests
|
||||
from stacktask.api.v1.tests import (FakeManager, setup_temp_cache,
|
||||
@ -754,7 +755,7 @@ class UserActionTests(StacktaskTestCase):
|
||||
action.pre_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
# Remove role from ROLES_MAPPING
|
||||
# Change settings
|
||||
with self.modify_dict_settings(ROLES_MAPPING={
|
||||
'key_list': ['project_mod'],
|
||||
'operation': "remove",
|
||||
@ -785,7 +786,6 @@ class UserActionTests(StacktaskTestCase):
|
||||
Tests that the role mappings do come from settings and a new role
|
||||
added there will be allowed.
|
||||
"""
|
||||
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
@ -800,7 +800,6 @@ class UserActionTests(StacktaskTestCase):
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
# Add a new role to the temp cache
|
||||
tests.temp_cache['roles']['new_role'] = 'new_role'
|
||||
|
||||
task = Task.objects.create(
|
||||
@ -911,7 +910,7 @@ class UserActionTests(StacktaskTestCase):
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0",
|
||||
keystone_user={
|
||||
'roles': ['admin', 'project_mod'],
|
||||
'roles': ['project_mod'],
|
||||
'project_id': 'test_project_id',
|
||||
'project_domain_id': 'default',
|
||||
})
|
||||
@ -944,3 +943,202 @@ class UserActionTests(StacktaskTestCase):
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users'][user.id].email,
|
||||
'test@example.com')
|
||||
|
||||
@override_settings(USERNAME_IS_EMAIL=True)
|
||||
def test_update_email(self):
|
||||
"""
|
||||
Base test case for user updating email address.
|
||||
"""
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.domain = 'default'
|
||||
project.roles = {}
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id_1'
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.domain = 'default'
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0",
|
||||
keystone_user={
|
||||
'roles': ['project_mod'],
|
||||
'project_id': 'test_project_id',
|
||||
'project_domain_id': 'default',
|
||||
})
|
||||
|
||||
data = {
|
||||
'new_email': 'new_test@example.com',
|
||||
'user_id': user.id,
|
||||
}
|
||||
|
||||
action = UpdateUserEmailAction(data, task=task, order=1)
|
||||
|
||||
action.pre_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
action.post_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
token_data = {'confirm': True}
|
||||
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']["user_id_1"].email,
|
||||
'new_test@example.com')
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']["user_id_1"].name,
|
||||
'new_test@example.com')
|
||||
|
||||
@override_settings(USERNAME_IS_EMAIL=True)
|
||||
def test_update_email_invalid_user(self):
|
||||
"""
|
||||
Test case for an invalid user being updated.
|
||||
"""
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.domain = 'default'
|
||||
project.roles = {}
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id_1'
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.domain = 'default'
|
||||
|
||||
setup_temp_cache({'test_project': project}, {})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0",
|
||||
keystone_user={
|
||||
'roles': ['project_mod'],
|
||||
'project_id': 'test_project_id',
|
||||
'project_domain_id': 'default',
|
||||
})
|
||||
|
||||
data = {
|
||||
'new_email': 'new_test@example.com',
|
||||
'user_id': "non_user_id",
|
||||
}
|
||||
|
||||
action = UpdateUserEmailAction(data, task=task, order=1)
|
||||
|
||||
action.pre_approve()
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
action.post_approve()
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
token_data = {'confirm': True}
|
||||
|
||||
action.submit(token_data)
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
@override_settings(USERNAME_IS_EMAIL=True)
|
||||
def test_update_email_invalid_email(self):
|
||||
"""
|
||||
Test case for a user attempting to update with an invalid email.
|
||||
"""
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.domain = 'default'
|
||||
project.roles = {}
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id_1'
|
||||
user.name = "test@example.com"
|
||||
user.email = "test@example.com"
|
||||
user.domain = 'default'
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0",
|
||||
keystone_user={
|
||||
'roles': ['project_mod'],
|
||||
'project_id': 'test_project_id',
|
||||
'project_domain_id': 'default',
|
||||
})
|
||||
|
||||
data = {
|
||||
'new_email': 'new_testexample.com',
|
||||
'user_id': "non_user_id",
|
||||
}
|
||||
|
||||
action = UpdateUserEmailAction(data, task=task, order=1)
|
||||
|
||||
action.pre_approve()
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
action.post_approve()
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
action.submit({'confirm': True})
|
||||
self.assertEquals(action.valid, False)
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']["user_id_1"].email,
|
||||
'test@example.com')
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']["user_id_1"].name,
|
||||
'test@example.com')
|
||||
|
||||
@override_settings(USERNAME_IS_EMAIL=False)
|
||||
def test_update_email_username_not_email(self):
|
||||
"""
|
||||
Test case for a user attempting to update with an invalid email.
|
||||
"""
|
||||
project = mock.Mock()
|
||||
project.id = 'test_project_id'
|
||||
project.name = 'test_project'
|
||||
project.domain = 'default'
|
||||
project.roles = {}
|
||||
|
||||
user = mock.Mock()
|
||||
user.id = 'user_id_1'
|
||||
user.name = "test_user"
|
||||
user.email = "test@example.com"
|
||||
user.domain = 'default'
|
||||
|
||||
setup_temp_cache({'test_project': project}, {user.id: user})
|
||||
|
||||
task = Task.objects.create(
|
||||
ip_address="0.0.0.0",
|
||||
keystone_user={
|
||||
'roles': ['project_mod'],
|
||||
'project_id': 'test_project_id',
|
||||
'project_domain_id': 'default',
|
||||
})
|
||||
|
||||
data = {
|
||||
'new_email': 'new_testexample.com',
|
||||
'user_id': "user_id_1",
|
||||
}
|
||||
|
||||
action = UpdateUserEmailAction(data, task=task, order=1)
|
||||
|
||||
action.pre_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
action.post_approve()
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
action.submit({'confirm': True})
|
||||
self.assertEquals(action.valid, True)
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']["user_id_1"].email,
|
||||
'new_testexample.com')
|
||||
|
||||
self.assertEquals(
|
||||
tests.temp_cache['users']["user_id_1"].name,
|
||||
'test_user')
|
||||
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
from stacktask.actions import user_store
|
||||
@ -325,3 +326,67 @@ class EditUserRolesAction(UserIdAction, ProjectMixin, UserMixin):
|
||||
self.add_note(
|
||||
"User %s didn't have roles %s in project %s."
|
||||
% (self.user_id, self.roles, self.project_id))
|
||||
|
||||
|
||||
class UpdateUserEmailAction(UserIdAction, UserMixin):
|
||||
"""
|
||||
Simple action to update a users email address for a given user.
|
||||
"""
|
||||
|
||||
required = [
|
||||
'user_id',
|
||||
'new_email',
|
||||
]
|
||||
|
||||
def _get_email(self):
|
||||
# Sending to new email address
|
||||
return self.new_email
|
||||
|
||||
def _validate(self):
|
||||
self.action.valid = (self._validate_user() and
|
||||
self._validate_email_not_in_use())
|
||||
self.action.save()
|
||||
|
||||
def _validate_user(self):
|
||||
self.user = self._get_target_user()
|
||||
if self.user:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _validate_email_not_in_use(self):
|
||||
if settings.USERNAME_IS_EMAIL:
|
||||
self.domain_id = self.action.task.keystone_user[
|
||||
'project_domain_id']
|
||||
|
||||
id_manager = user_store.IdentityManager()
|
||||
|
||||
if id_manager.find_user(self.new_email, self.domain_id):
|
||||
self.add_note("User with same username already exists")
|
||||
return False
|
||||
self.add_note("No user with same username")
|
||||
return True
|
||||
|
||||
def _pre_approve(self):
|
||||
self._validate()
|
||||
self.set_auto_approve(True)
|
||||
|
||||
def _post_approve(self):
|
||||
self._validate()
|
||||
self.action.need_token = True
|
||||
self.set_token_fields(["confirm"])
|
||||
|
||||
def _submit(self, token_data):
|
||||
self._validate()
|
||||
|
||||
if not self.valid:
|
||||
return
|
||||
|
||||
if token_data["confirm"]:
|
||||
self.old_username = str(self.user.name)
|
||||
self.update_email(self.new_email, user=self.user)
|
||||
|
||||
if settings.USERNAME_IS_EMAIL:
|
||||
self.update_user_name(self.new_email, user=self.user)
|
||||
|
||||
self.add_note('The email for user %s has been changed to %s.'
|
||||
% (self.old_username, self.new_email))
|
||||
|
@ -53,3 +53,16 @@ def admin(func, *args, **kwargs):
|
||||
"""
|
||||
return require_roles(
|
||||
{'admin'}, func, *args, **kwargs)
|
||||
|
||||
|
||||
@decorator
|
||||
def authenticated(func, *args, **kwargs):
|
||||
"""
|
||||
endpoints setup with this decorator require the user to be signed in
|
||||
"""
|
||||
request = args[1]
|
||||
if not request.keystone_user.get('authenticated', False):
|
||||
return Response({'errors': ["Credentials incorrect or none given."]},
|
||||
401)
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
@ -30,6 +30,8 @@ register_taskview_class(r'^actions/CreateProject/?$', tasks.CreateProject)
|
||||
register_taskview_class(r'^actions/InviteUser/?$', tasks.InviteUser)
|
||||
register_taskview_class(r'^actions/ResetPassword/?$', tasks.ResetPassword)
|
||||
register_taskview_class(r'^actions/EditUser/?$', tasks.EditUser)
|
||||
register_taskview_class(r'^actions/UpdateEmail/?$', tasks.UpdateEmail)
|
||||
|
||||
|
||||
register_taskview_class(
|
||||
r'^openstack/users/?$', openstack.UserList)
|
||||
@ -43,5 +45,7 @@ register_taskview_class(
|
||||
r'^openstack/users/password-reset/?$', openstack.UserResetPassword)
|
||||
register_taskview_class(
|
||||
r'^openstack/users/password-set/?$', openstack.UserSetPassword)
|
||||
register_taskview_class(
|
||||
r'^openstack/users/email-update/?$', openstack.UserUpdateEmail)
|
||||
register_taskview_class(
|
||||
r'^openstack/sign-up/?$', openstack.SignUp)
|
||||
|
@ -286,6 +286,20 @@ class UserSetPassword(tasks.ResetPassword):
|
||||
return super(UserSetPassword, self).post(request)
|
||||
|
||||
|
||||
class UserUpdateEmail(tasks.UpdateEmail):
|
||||
"""
|
||||
The openstack endpoint for a user to update their own email.
|
||||
---
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
The EmailUpdate endpoint does not support GET.
|
||||
This returns a 404.
|
||||
"""
|
||||
return Response(status=404)
|
||||
|
||||
|
||||
class SignUp(tasks.CreateProject):
|
||||
"""
|
||||
The openstack endpoint for signups.
|
||||
|
@ -580,3 +580,29 @@ class EditUser(TaskView):
|
||||
add_task_id_for_roles(request, processed, response_dict, ['admin'])
|
||||
|
||||
return Response(response_dict, status=status)
|
||||
|
||||
|
||||
class UpdateEmail(TaskView):
|
||||
task_type = "update_email"
|
||||
|
||||
default_actions = ["UpdateUserEmailAction", ]
|
||||
|
||||
@utils.authenticated
|
||||
def post(self, request, format=None):
|
||||
"""
|
||||
Endpoint bound to the update email action.
|
||||
This will submit and approve an update email action.
|
||||
"""
|
||||
|
||||
request.data['user_id'] = request.keystone_user['user_id']
|
||||
|
||||
processed, status = self.process_actions(request)
|
||||
|
||||
errors = processed.get('errors', None)
|
||||
if errors:
|
||||
self.logger.info("(%s) - Validation errors with task." %
|
||||
timezone.now())
|
||||
return Response(errors, status=status)
|
||||
|
||||
response_dict = {'notes': processed['notes']}
|
||||
return Response(response_dict, status=status)
|
||||
|
4
stacktask/api/v1/templates/email_update_completed.txt
Normal file
4
stacktask/api/v1/templates/email_update_completed.txt
Normal file
@ -0,0 +1,4 @@
|
||||
This email is to confirm that your Openstack account email has now been changed.
|
||||
|
||||
Kind regards,
|
||||
The Openstack team
|
@ -1,6 +1,6 @@
|
||||
Hello,
|
||||
|
||||
We have had an email address change request from you. We have sent a confirmation email to your new email: {{ actions.UpdateUserEmailAction.new_email }}
|
||||
We have had an email address change request from you. A confirmation email will be sent to '{{ actions.UpdateUserEmailAction.new_email }}'.
|
||||
|
||||
If this was not you please get in touch with an administrator immediately.
|
||||
|
||||
|
13
stacktask/api/v1/templates/email_update_token.txt
Normal file
13
stacktask/api/v1/templates/email_update_token.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Hello,
|
||||
|
||||
We have received a request to update your Openstack email to this account.
|
||||
|
||||
Please click the link below to update your email:
|
||||
{{ tokenurl }}{{ token }}
|
||||
|
||||
This link will expire automatically after 24 hours. If expired, you will need to request another email update.
|
||||
|
||||
If you did not request this email update, please get in touch with your systems administrator to report suspicious activity and secure your account.
|
||||
|
||||
Kind regards,
|
||||
The Openstack team
|
@ -143,6 +143,14 @@ class FakeManager(object):
|
||||
user = self._user_from_id(user)
|
||||
user.password = password
|
||||
|
||||
def update_user_name(self, user, username):
|
||||
user = self._user_from_id(user)
|
||||
user.name = username
|
||||
|
||||
def update_user_email(self, user, email):
|
||||
user = self._user_from_id(user)
|
||||
user.email = email
|
||||
|
||||
def enable_user(self, user):
|
||||
user = self._user_from_id(user)
|
||||
user.enabled = True
|
||||
|
@ -654,7 +654,210 @@ class TaskViewTests(StacktaskAPITestCase):
|
||||
|
||||
self.assertFalse(response.data.get('task'))
|
||||
|
||||
# Positive tests for when USERNAME_IS_EMAIL=False
|
||||
def test_update_email_task(self):
|
||||
"""
|
||||
Ensure the update email workflow goes as expected.
|
||||
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'
|
||||
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/UpdateEmail"
|
||||
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 = {'new_email': "new_test@example.com"}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, {'notes': ['created token']})
|
||||
|
||||
new_token = Token.objects.all()[0]
|
||||
url = "/v1/tokens/" + new_token.token
|
||||
|
||||
data = {'confirm': True}
|
||||
response = self.client.post(url, data, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEquals(user.name, 'new_test@example.com')
|
||||
|
||||
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'
|
||||
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/UpdateEmail"
|
||||
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 = {'new_email': "new_test@examplecom"}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(response.data,
|
||||
{'new_email': [u'Enter a valid email address.']})
|
||||
|
||||
@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'
|
||||
|
||||
user2 = mock.Mock()
|
||||
user2.id = 'new_user_id'
|
||||
user2.name = "new_test@example.com"
|
||||
user2.email = "new_test@example.com"
|
||||
user2.domain = 'default'
|
||||
|
||||
setup_temp_cache({}, {user.id: user, user2.id: user2})
|
||||
|
||||
url = "/v1/actions/UpdateEmail"
|
||||
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,
|
||||
'project_domain_id': 'default',
|
||||
}
|
||||
|
||||
data = {'new_email': "new_test@example.com"}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(response.data, ['actions invalid'])
|
||||
self.assertEqual(len(Token.objects.all()), 0)
|
||||
|
||||
self.assertEqual(len(mail.outbox), 0)
|
||||
|
||||
@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'
|
||||
|
||||
user2 = mock.Mock()
|
||||
user2.id = 'new_user_id'
|
||||
user2.name = "new_test"
|
||||
user2.email = "new_test@example.com"
|
||||
user2.domain = 'Default'
|
||||
|
||||
setup_temp_cache({}, {user.id: user, user2.id: user})
|
||||
|
||||
url = "/v1/actions/UpdateEmail"
|
||||
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 = {'new_email': "new_test@example.com"}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, {'notes': ['created token']})
|
||||
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
|
||||
new_token = Token.objects.all()[0]
|
||||
url = "/v1/tokens/" + new_token.token
|
||||
|
||||
data = {'confirm': True}
|
||||
response = self.client.post(url, data, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEquals(user.email, 'new_test@example.com')
|
||||
|
||||
def test_update_email_task_not_authenticated(self):
|
||||
"""
|
||||
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'
|
||||
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/UpdateEmail"
|
||||
headers = {
|
||||
}
|
||||
|
||||
data = {'new_email': "new_test@examplecom"}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
@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'
|
||||
|
||||
setup_temp_cache({}, {user.id: user})
|
||||
|
||||
url = "/v1/actions/UpdateEmail"
|
||||
headers = {
|
||||
'project_name': "test_project",
|
||||
'project_id': "test_project_id",
|
||||
'roles': "project_admin,_member_,project_mod",
|
||||
'username': "test_user",
|
||||
'user_id': "test_user_id",
|
||||
'authenticated': True
|
||||
}
|
||||
|
||||
data = {'new_email': "new_test@example.com"}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data, {'notes': ['created token']})
|
||||
|
||||
new_token = Token.objects.all()[0]
|
||||
url = "/v1/tokens/" + new_token.token
|
||||
|
||||
data = {'confirm': True}
|
||||
response = self.client.post(url, data, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEquals(user.name, "test_user")
|
||||
self.assertEquals(user.email, 'new_test@example.com')
|
||||
|
||||
# Tests for USERNAME_IS_EMAIL=False
|
||||
@override_settings(USERNAME_IS_EMAIL=False)
|
||||
def test_invite_user_email_not_username(self):
|
||||
"""
|
||||
|
@ -86,6 +86,7 @@ ACTIVE_TASKVIEWS = [
|
||||
'InviteUser',
|
||||
'ResetPassword',
|
||||
'EditUser',
|
||||
'UpdateEmail'
|
||||
]
|
||||
|
||||
DEFAULT_TASK_SETTINGS = {
|
||||
@ -230,7 +231,12 @@ TASK_SETTINGS = {
|
||||
'subject': 'Setup Your OpenStack Password'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'update_email': {
|
||||
'emails': {
|
||||
'initial': None,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ROLES_MAPPING = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user