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
|
||||
emails:
|
||||
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:
|
||||
emails:
|
||||
initial: null
|
||||
|
|
|
@ -246,7 +246,7 @@ class RoleList(tasks.TaskView):
|
|||
return Response({'roles': managable_roles})
|
||||
|
||||
|
||||
class ResetPassword(tasks.ResetPassword):
|
||||
class UserResetPassword(tasks.ResetPassword):
|
||||
"""
|
||||
The openstack forgot password endpoint.
|
||||
---
|
||||
|
@ -258,3 +258,23 @@ class ResetPassword(tasks.ResetPassword):
|
|||
This returns a 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",
|
||||
'authenticated': True
|
||||
}
|
||||
|
||||
data = {'email': "test@example.com", 'roles': ["Member"],
|
||||
'project_id': 'test_project_id'}
|
||||
response = self.client.post(url, data, format='json', headers=headers)
|
||||
|
@ -104,3 +105,48 @@ class OpenstackAPITests(APITestCase):
|
|||
|
||||
response = self.client.get(url, headers=headers)
|
||||
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()),
|
||||
url(r'^openstack/users/(?P<user_id>\w+)/?$',
|
||||
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/roles/?$', openstack.RoleList.as_view()),
|
||||
url(r'^openstack/forgotpassword/?$', openstack.ResetPassword.as_view()),
|
||||
]
|
||||
|
||||
if settings.SHOW_ACTION_ENDPOINTS:
|
||||
|
|
|
@ -108,7 +108,26 @@ TASK_SETTINGS = {
|
|||
]
|
||||
},
|
||||
'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