Adding admin only endpoint to force password resets.
* Different email templates for each type of password reset. * For now the force reset will be mainly for new users, hence "initial_password" template. Change-Id: Ie0fecacfed7d767727bd2729fca888a45467a43d
This commit is contained in:
parent
3476781a0e
commit
de017bd970
|
@ -109,6 +109,20 @@ TASK_SETTINGS:
|
||||||
handle_duplicates: cancel
|
handle_duplicates: cancel
|
||||||
emails:
|
emails:
|
||||||
initial: null
|
initial: null
|
||||||
|
token:
|
||||||
|
subject: Password Reset for OpenStack
|
||||||
|
reply: no-reply@example.com
|
||||||
|
template: password_reset.txt
|
||||||
|
html_template: password_reset.txt
|
||||||
|
force_password:
|
||||||
|
handle_duplicates: cancel
|
||||||
|
emails:
|
||||||
|
initial: null
|
||||||
|
token:
|
||||||
|
subject: Setup Your OpenStack Password
|
||||||
|
reply: no-reply@example.com
|
||||||
|
template: initial_password.txt
|
||||||
|
html_template: initial_password.txt
|
||||||
edit_user:
|
edit_user:
|
||||||
emails:
|
emails:
|
||||||
initial: null
|
initial: null
|
||||||
|
|
|
@ -246,7 +246,7 @@ class RoleList(tasks.TaskView):
|
||||||
return Response({'roles': managable_roles})
|
return Response({'roles': managable_roles})
|
||||||
|
|
||||||
|
|
||||||
class ResetPassword(tasks.ResetPassword):
|
class UserResetPassword(tasks.ResetPassword):
|
||||||
"""
|
"""
|
||||||
The openstack forgot password endpoint.
|
The openstack forgot password endpoint.
|
||||||
---
|
---
|
||||||
|
@ -258,3 +258,23 @@ class ResetPassword(tasks.ResetPassword):
|
||||||
This returns a 404.
|
This returns a 404.
|
||||||
"""
|
"""
|
||||||
return Response(status=404)
|
return Response(status=404)
|
||||||
|
|
||||||
|
|
||||||
|
class UserSetPassword(tasks.ResetPassword):
|
||||||
|
"""
|
||||||
|
The openstack endpoint to force a password reset.
|
||||||
|
---
|
||||||
|
"""
|
||||||
|
|
||||||
|
task_type = "force_password"
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
"""
|
||||||
|
The ForcePassword endpoint does not support GET.
|
||||||
|
This returns a 404.
|
||||||
|
"""
|
||||||
|
return Response(status=404)
|
||||||
|
|
||||||
|
@utils.admin
|
||||||
|
def post(self, request, format=None):
|
||||||
|
return super(UserSetPassword, self).post(request)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Hello,
|
||||||
|
|
||||||
|
You can setup your initial OpenStack user password by following this link:
|
||||||
|
{{ tokenurl }}{{ token }}/
|
||||||
|
|
||||||
|
Once setup you will have access to the web dashboard.
|
|
@ -0,0 +1,7 @@
|
||||||
|
Hello,
|
||||||
|
|
||||||
|
Your password reset link is:
|
||||||
|
{{ tokenurl }}{{ token }}/
|
||||||
|
|
||||||
|
If you did not request this reset ignore this email.
|
||||||
|
|
|
@ -83,6 +83,7 @@ class OpenstackAPITests(APITestCase):
|
||||||
'user_id': "test_user_id",
|
'user_id': "test_user_id",
|
||||||
'authenticated': True
|
'authenticated': True
|
||||||
}
|
}
|
||||||
|
|
||||||
data = {'email': "test@example.com", 'roles': ["Member"],
|
data = {'email': "test@example.com", 'roles': ["Member"],
|
||||||
'project_id': 'test_project_id'}
|
'project_id': 'test_project_id'}
|
||||||
response = self.client.post(url, data, format='json', headers=headers)
|
response = self.client.post(url, data, format='json', headers=headers)
|
||||||
|
@ -104,3 +105,48 @@ class OpenstackAPITests(APITestCase):
|
||||||
|
|
||||||
response = self.client.get(url, headers=headers)
|
response = self.client.get(url, headers=headers)
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'stacktask.actions.models.user_store.IdentityManager', FakeManager)
|
||||||
|
def test_force_reset_password(self):
|
||||||
|
"""
|
||||||
|
Ensure the force password endpoint works as expected,
|
||||||
|
and only for admin.
|
||||||
|
|
||||||
|
Should also check if template can be rendered.
|
||||||
|
"""
|
||||||
|
|
||||||
|
user = mock.Mock()
|
||||||
|
user.id = 'user_id'
|
||||||
|
user.username = "test@example.com"
|
||||||
|
user.email = "test@example.com"
|
||||||
|
user.password = "test_password"
|
||||||
|
|
||||||
|
setup_temp_cache({}, {user.username: user})
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'project_name': "test_project",
|
||||||
|
'project_id': "test_project_id",
|
||||||
|
'roles': "Member",
|
||||||
|
'username': "test@example.com",
|
||||||
|
'user_id': "test_user_id",
|
||||||
|
'authenticated': True
|
||||||
|
}
|
||||||
|
|
||||||
|
url = "/v1/openstack/users/password-set"
|
||||||
|
data = {'email': "test@example.com"}
|
||||||
|
response = self.client.post(url, data, format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||||
|
response = self.client.post(url, data, format='json', headers=headers)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
headers["roles"] = "admin,Member"
|
||||||
|
response = self.client.post(url, data, format='json', headers=headers)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response.data, None)
|
||||||
|
|
||||||
|
new_token = Token.objects.all()[0]
|
||||||
|
url = "/v1/tokens/" + new_token.token
|
||||||
|
data = {'password': 'new_test_password'}
|
||||||
|
response = self.client.post(url, data, format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(user.password, 'new_test_password')
|
||||||
|
|
|
@ -31,9 +31,12 @@ urlpatterns = [
|
||||||
openstack.UserRoles.as_view()),
|
openstack.UserRoles.as_view()),
|
||||||
url(r'^openstack/users/(?P<user_id>\w+)/?$',
|
url(r'^openstack/users/(?P<user_id>\w+)/?$',
|
||||||
openstack.UserDetail.as_view()),
|
openstack.UserDetail.as_view()),
|
||||||
|
url(r'^openstack/users/password-reset?$',
|
||||||
|
openstack.UserResetPassword.as_view()),
|
||||||
|
url(r'^openstack/users/password-set?$',
|
||||||
|
openstack.UserSetPassword.as_view()),
|
||||||
url(r'^openstack/users/?$', openstack.UserList.as_view()),
|
url(r'^openstack/users/?$', openstack.UserList.as_view()),
|
||||||
url(r'^openstack/roles/?$', openstack.RoleList.as_view()),
|
url(r'^openstack/roles/?$', openstack.RoleList.as_view()),
|
||||||
url(r'^openstack/forgotpassword/?$', openstack.ResetPassword.as_view()),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if settings.SHOW_ACTION_ENDPOINTS:
|
if settings.SHOW_ACTION_ENDPOINTS:
|
||||||
|
|
|
@ -108,7 +108,26 @@ TASK_SETTINGS = {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
'reset_password': {
|
'reset_password': {
|
||||||
'handle_duplicates': 'cancel'
|
'handle_duplicates': 'cancel',
|
||||||
|
'emails': {
|
||||||
|
'token': {
|
||||||
|
'reply': 'no-reply@example.com',
|
||||||
|
'html_template': 'password_reset.txt',
|
||||||
|
'template': 'password_reset.txt',
|
||||||
|
'subject': 'Password Reset for OpenStack'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'force_password': {
|
||||||
|
'handle_duplicates': 'cancel',
|
||||||
|
'emails': {
|
||||||
|
'token': {
|
||||||
|
'reply': 'no-reply@example.com',
|
||||||
|
'html_template': 'initial_password.txt',
|
||||||
|
'template': 'initial_password.txt',
|
||||||
|
'subject': 'Setup Your OpenStack Password'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue