From 0004ed0856963b6cd2cd74e7a6c77dae27a6988e Mon Sep 17 00:00:00 2001
From: Emmanuel Cazenave <ecazenave@entrouvert.com>
Date: Tue, 18 Dec 2018 16:37:33 +0100
Subject: [PATCH] allow redirect after user edition (#28779)

---
 .../authentic2/manager/user_edit.html         |  5 ++++
 src/authentic2/manager/user_views.py          | 19 ++++++++++++--
 tests/test_manager.py                         | 25 +++++++++++++++++++
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/src/authentic2/manager/templates/authentic2/manager/user_edit.html b/src/authentic2/manager/templates/authentic2/manager/user_edit.html
index 3f9a4a6b..25f54890 100644
--- a/src/authentic2/manager/templates/authentic2/manager/user_edit.html
+++ b/src/authentic2/manager/templates/authentic2/manager/user_edit.html
@@ -7,3 +7,8 @@
   <a href="{% url 'a2-manager-user-detail' pk=object.pk %}">{{ object.get_full_name }}</a>
   <a href="#">{% trans "Edit" %}</a>
 {% endblock %}
+
+{% block hidden_inputs %}
+    {{ block.super }}
+    {% if next %}<input type="hidden" name="next" value="{{ next }}">{% endif %}
+{% endblock %}
diff --git a/src/authentic2/manager/user_views.py b/src/authentic2/manager/user_views.py
index 5c2cad66..4e8f4de2 100644
--- a/src/authentic2/manager/user_views.py
+++ b/src/authentic2/manager/user_views.py
@@ -19,7 +19,7 @@ from import_export.fields import Field
 
 from authentic2.constants import SWITCH_USER_SESSION_KEY
 from authentic2.models import Attribute, PasswordReset
-from authentic2.utils import switch_user, send_password_reset_mail, redirect, send_email_change_email
+from authentic2.utils import switch_user, send_password_reset_mail, redirect, select_next_url
 from authentic2.a2_rbac.utils import get_default_ou
 from authentic2 import hooks
 from django_rbac.utils import get_role_model, get_role_parenting_model, get_ou_model
@@ -291,7 +291,6 @@ class UserEditView(OtherActionsMixin, ActionMixin, BaseEditView):
     form_class = UserEditForm
     permissions = ['custom_user.change_user']
     fields = ['username', 'ou', 'first_name', 'last_name']
-    success_url = '..'
     slug_field = 'uuid'
     action = _('Change')
     title = _('Edit user')
@@ -307,6 +306,22 @@ class UserEditView(OtherActionsMixin, ActionMixin, BaseEditView):
             fields.append('is_superuser')
         return fields
 
+    def _get_next_url(self):
+        return select_next_url(
+            self.request,
+            default=reverse('a2-manager-user-detail', kwargs={'pk': self.object.pk}),
+            include_post=True)
+
+    def get_context_data(self, **kwargs):
+        context = super(UserEditView, self).get_context_data(**kwargs)
+        next_url = self._get_next_url()
+        context['next'] = next_url
+        context['cancel_url'] = next_url
+        return context
+
+    def get_success_url(self):
+        return self._get_next_url()
+
     def form_valid(self, form):
         response = super(UserEditView, self).form_valid(form)
         hooks.call_hooks('event', name='manager-edit-user', user=self.request.user,
diff --git a/tests/test_manager.py b/tests/test_manager.py
index d874344b..96085030 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -790,3 +790,28 @@ def test_manager_add_user_querystring(superuser_or_admin, app, ou1):
     response = app.get(url)
 
     assert querystring in response.location
+
+
+def test_manager_edit_user_next(app, simple_user, superuser_or_admin):
+    next_url = u'/example.nowhere.null/'
+    url = u'/manage/users/%s/edit/?next=%s' % (simple_user.pk, next_url)
+    login(app, superuser_or_admin, '/manage/')
+    response = app.get(url)
+
+    # cancel if not handled through form submission
+    assert response.pyquery.remove_namespaces()('a.cancel').attr('href') == next_url
+
+    form = response.form
+    form.set('last_name', 'New name')
+    assert urlparse(form.submit().location).path == next_url
+
+
+def test_manager_edit_user_next_form_error(superuser_or_admin, app, ou1, simple_user):
+    next_url = u'/example.nowhere.null/'
+    url = u'/manage/users/%s/edit/?next=%s' % (simple_user.pk, next_url)
+    login(app, superuser_or_admin, '/manage/')
+    response = app.get(url)
+    form = response.form
+    form.set('email', 'jd')  # erroneous
+    resp = form.submit()
+    assert '<input type="hidden" name="next" value="%s">' % next_url in resp.ubody
-- 
2.19.2

