mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	settings: Migrate main settings-change code to API.
This was one of the few major remaining endpoints that were still on the old-style legacy API.
This commit is contained in:
		@@ -5,7 +5,7 @@ var OUTGOING_WEBHOOK_BOT_TYPE = '3';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
common.start_and_log_in();
 | 
					common.start_and_log_in();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var form_sel = 'form[action^="/json/settings/change"]';
 | 
					var form_sel = 'form[action^="/json/settings"]';
 | 
				
			||||||
var regex_zuliprc = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\n$/;
 | 
					var regex_zuliprc = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\n$/;
 | 
				
			||||||
var regex_flaskbotrc = /^data:application\/octet-stream;charset=utf-8,\[.\]\nemail=.+\nkey=.+\nsite=.+\n$/;
 | 
					var regex_flaskbotrc = /^data:application\/octet-stream;charset=utf-8,\[.\]\nemail=.+\nkey=.+\nsite=.+\n$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -155,7 +155,7 @@ exports.set_up = function () {
 | 
				
			|||||||
        data.email = $('.email_change_container').find("input[name='email']").val();
 | 
					        data.email = $('.email_change_container').find("input[name='email']").val();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        channel.patch({
 | 
					        channel.patch({
 | 
				
			||||||
            url: '/json/settings/change',
 | 
					            url: '/json/settings',
 | 
				
			||||||
            data: data,
 | 
					            data: data,
 | 
				
			||||||
            success: function (data) {
 | 
					            success: function (data) {
 | 
				
			||||||
                if ('account_email' in data) {
 | 
					                if ('account_email' in data) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </form>
 | 
					            </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <form action="/json/settings/change" method="post"
 | 
					            <form action="/json/settings" method="patch"
 | 
				
			||||||
                class="form-horizontal your-account-settings">
 | 
					                class="form-horizontal your-account-settings">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <div class="m-10 inline-block grid user-name-parent">
 | 
					                <div class="m-10 inline-block grid user-name-parent">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1023,6 +1023,7 @@ class TestHumanUsersOnlyDecorator(ZulipTestCase):
 | 
				
			|||||||
            self.assert_json_error(result, "This endpoint does not accept bot requests.")
 | 
					            self.assert_json_error(result, "This endpoint does not accept bot requests.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        patch_endpoints = [
 | 
					        patch_endpoints = [
 | 
				
			||||||
 | 
					            "/api/v1/settings",
 | 
				
			||||||
            "/api/v1/settings/display",
 | 
					            "/api/v1/settings/display",
 | 
				
			||||||
            "/api/v1/settings/notifications",
 | 
					            "/api/v1/settings/notifications",
 | 
				
			||||||
            "/api/v1/settings/ui",
 | 
					            "/api/v1/settings/ui",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,9 +103,9 @@ class EmailChangeTestCase(ZulipTestCase):
 | 
				
			|||||||
        data = {'email': 'hamlet-new@zulip.com'}
 | 
					        data = {'email': 'hamlet-new@zulip.com'}
 | 
				
			||||||
        email = self.example_email("hamlet")
 | 
					        email = self.example_email("hamlet")
 | 
				
			||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
        url = '/json/settings/change'
 | 
					        url = '/json/settings'
 | 
				
			||||||
        self.assertEqual(len(mail.outbox), 0)
 | 
					        self.assertEqual(len(mail.outbox), 0)
 | 
				
			||||||
        result = self.client_post(url, data)
 | 
					        result = self.client_patch(url, data)
 | 
				
			||||||
        self.assertEqual(len(mail.outbox), 1)
 | 
					        self.assertEqual(len(mail.outbox), 1)
 | 
				
			||||||
        self.assert_in_success_response(['Check your email for a confirmation link.'], result)
 | 
					        self.assert_in_success_response(['Check your email for a confirmation link.'], result)
 | 
				
			||||||
        email_message = mail.outbox[0]
 | 
					        email_message = mail.outbox[0]
 | 
				
			||||||
@@ -132,8 +132,8 @@ class EmailChangeTestCase(ZulipTestCase):
 | 
				
			|||||||
        email = user_profile.email
 | 
					        email = user_profile.email
 | 
				
			||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
        do_set_realm_property(user_profile.realm, 'email_changes_disabled', True)
 | 
					        do_set_realm_property(user_profile.realm, 'email_changes_disabled', True)
 | 
				
			||||||
        url = '/json/settings/change'
 | 
					        url = '/json/settings'
 | 
				
			||||||
        result = self.client_post(url, data)
 | 
					        result = self.client_patch(url, data)
 | 
				
			||||||
        self.assertEqual(len(mail.outbox), 0)
 | 
					        self.assertEqual(len(mail.outbox), 0)
 | 
				
			||||||
        self.assertEqual(result.status_code, 400)
 | 
					        self.assertEqual(result.status_code, 400)
 | 
				
			||||||
        self.assert_in_response("Email address changes are disabled in this organization.",
 | 
					        self.assert_in_response("Email address changes are disabled in this organization.",
 | 
				
			||||||
@@ -145,9 +145,9 @@ class EmailChangeTestCase(ZulipTestCase):
 | 
				
			|||||||
        user_profile = self.example_user('hamlet')
 | 
					        user_profile = self.example_user('hamlet')
 | 
				
			||||||
        email = user_profile.email
 | 
					        email = user_profile.email
 | 
				
			||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
        url = '/json/settings/change'
 | 
					        url = '/json/settings'
 | 
				
			||||||
        self.assertEqual(len(mail.outbox), 0)
 | 
					        self.assertEqual(len(mail.outbox), 0)
 | 
				
			||||||
        result = self.client_post(url, data)
 | 
					        result = self.client_patch(url, data)
 | 
				
			||||||
        self.assertEqual(len(mail.outbox), 1)
 | 
					        self.assertEqual(len(mail.outbox), 1)
 | 
				
			||||||
        self.assert_in_success_response(['Check your email for a confirmation link.'], result)
 | 
					        self.assert_in_success_response(['Check your email for a confirmation link.'], result)
 | 
				
			||||||
        email_message = mail.outbox[0]
 | 
					        email_message = mail.outbox[0]
 | 
				
			||||||
@@ -172,8 +172,8 @@ class EmailChangeTestCase(ZulipTestCase):
 | 
				
			|||||||
        data = {'email': 'hamlet-new'}
 | 
					        data = {'email': 'hamlet-new'}
 | 
				
			||||||
        email = self.example_email("hamlet")
 | 
					        email = self.example_email("hamlet")
 | 
				
			||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
        url = '/json/settings/change'
 | 
					        url = '/json/settings'
 | 
				
			||||||
        result = self.client_post(url, data)
 | 
					        result = self.client_patch(url, data)
 | 
				
			||||||
        self.assert_in_response('Invalid address', result)
 | 
					        self.assert_in_response('Invalid address', result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_post_same_email(self):
 | 
					    def test_post_same_email(self):
 | 
				
			||||||
@@ -181,7 +181,7 @@ class EmailChangeTestCase(ZulipTestCase):
 | 
				
			|||||||
        data = {'email': self.example_email("hamlet")}
 | 
					        data = {'email': self.example_email("hamlet")}
 | 
				
			||||||
        email = self.example_email("hamlet")
 | 
					        email = self.example_email("hamlet")
 | 
				
			||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
        url = '/json/settings/change'
 | 
					        url = '/json/settings'
 | 
				
			||||||
        result = self.client_post(url, data)
 | 
					        result = self.client_patch(url, data)
 | 
				
			||||||
        self.assertEqual('success', result.json()['result'])
 | 
					        self.assertEqual('success', result.json()['result'])
 | 
				
			||||||
        self.assertEqual('', result.json()['msg'])
 | 
					        self.assertEqual('', result.json()['msg'])
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,8 +122,8 @@ class RealmTest(ZulipTestCase):
 | 
				
			|||||||
        email = user_profile.email
 | 
					        email = user_profile.email
 | 
				
			||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
        do_set_realm_property(user_profile.realm, 'name_changes_disabled', True)
 | 
					        do_set_realm_property(user_profile.realm, 'name_changes_disabled', True)
 | 
				
			||||||
        url = '/json/settings/change'
 | 
					        url = '/json/settings'
 | 
				
			||||||
        result = self.client_post(url, data)
 | 
					        result = self.client_patch(url, data)
 | 
				
			||||||
        self.assertEqual(result.status_code, 200)
 | 
					        self.assertEqual(result.status_code, 200)
 | 
				
			||||||
        # Since the setting fails silently, no message is returned
 | 
					        # Since the setting fails silently, no message is returned
 | 
				
			||||||
        self.assert_in_response("", result)
 | 
					        self.assert_in_response("", result)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,12 +61,12 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
    def test_successful_change_settings(self):
 | 
					    def test_successful_change_settings(self):
 | 
				
			||||||
        # type: () -> None
 | 
					        # type: () -> None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        A call to /json/settings/change with valid parameters changes the user's
 | 
					        A call to /json/settings with valid parameters changes the user's
 | 
				
			||||||
        settings correctly and returns correct values.
 | 
					        settings correctly and returns correct values.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.login(self.example_email("hamlet"))
 | 
					        self.login(self.example_email("hamlet"))
 | 
				
			||||||
        json_result = self.client_post(
 | 
					        json_result = self.client_patch(
 | 
				
			||||||
            "/json/settings/change",
 | 
					            "/json/settings",
 | 
				
			||||||
            dict(
 | 
					            dict(
 | 
				
			||||||
                full_name='Foo Bar',
 | 
					                full_name='Foo Bar',
 | 
				
			||||||
                old_password=initial_password(self.example_email("hamlet")),
 | 
					                old_password=initial_password(self.example_email("hamlet")),
 | 
				
			||||||
@@ -91,8 +91,8 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
        full_name = user.full_name
 | 
					        full_name = user.full_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.settings(NAME_CHANGES_DISABLED=True):
 | 
					        with self.settings(NAME_CHANGES_DISABLED=True):
 | 
				
			||||||
            json_result = self.client_post("/json/settings/change",
 | 
					            json_result = self.client_patch("/json/settings",
 | 
				
			||||||
                                           dict(full_name='Foo Bar'))
 | 
					                                            dict(full_name='Foo Bar'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # We actually fail silently here, since this only happens if
 | 
					        # We actually fail silently here, since this only happens if
 | 
				
			||||||
        # somebody is trying to game our API, and there's no reason to
 | 
					        # somebody is trying to game our API, and there's no reason to
 | 
				
			||||||
@@ -103,13 +103,13 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
        self.assertEqual(user.full_name, full_name)
 | 
					        self.assertEqual(user.full_name, full_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Now try a too-long name
 | 
					        # Now try a too-long name
 | 
				
			||||||
        json_result = self.client_post("/json/settings/change",
 | 
					        json_result = self.client_patch("/json/settings",
 | 
				
			||||||
                                       dict(full_name='x' * 1000))
 | 
					                                        dict(full_name='x' * 1000))
 | 
				
			||||||
        self.assert_json_error(json_result, 'Name too long!')
 | 
					        self.assert_json_error(json_result, 'Name too long!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Now try a too-short name
 | 
					        # Now try a too-short name
 | 
				
			||||||
        json_result = self.client_post("/json/settings/change",
 | 
					        json_result = self.client_patch("/json/settings",
 | 
				
			||||||
                                       dict(full_name='x'))
 | 
					                                        dict(full_name='x'))
 | 
				
			||||||
        self.assert_json_error(json_result, 'Name too short!')
 | 
					        self.assert_json_error(json_result, 'Name too short!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_illegal_characters_in_name_changes(self):
 | 
					    def test_illegal_characters_in_name_changes(self):
 | 
				
			||||||
@@ -118,8 +118,8 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
        self.login(email)
 | 
					        self.login(email)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Now try a name with invalid characters
 | 
					        # Now try a name with invalid characters
 | 
				
			||||||
        json_result = self.client_post("/json/settings/change",
 | 
					        json_result = self.client_patch("/json/settings",
 | 
				
			||||||
                                       dict(full_name='Opheli*'))
 | 
					                                        dict(full_name='Opheli*'))
 | 
				
			||||||
        self.assert_json_error(json_result, 'Invalid characters in name!')
 | 
					        self.assert_json_error(json_result, 'Invalid characters in name!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # This is basically a don't-explode test.
 | 
					    # This is basically a don't-explode test.
 | 
				
			||||||
@@ -151,8 +151,8 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
        new_password and confirm_password must match
 | 
					        new_password and confirm_password must match
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.login(self.example_email("hamlet"))
 | 
					        self.login(self.example_email("hamlet"))
 | 
				
			||||||
        result = self.client_post(
 | 
					        result = self.client_patch(
 | 
				
			||||||
            "/json/settings/change",
 | 
					            "/json/settings",
 | 
				
			||||||
            dict(
 | 
					            dict(
 | 
				
			||||||
                new_password="mismatched_password",
 | 
					                new_password="mismatched_password",
 | 
				
			||||||
                confirm_password="not_the_same",
 | 
					                confirm_password="not_the_same",
 | 
				
			||||||
@@ -166,8 +166,8 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
        new_password and confirm_password must match
 | 
					        new_password and confirm_password must match
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.login(self.example_email("hamlet"))
 | 
					        self.login(self.example_email("hamlet"))
 | 
				
			||||||
        result = self.client_post(
 | 
					        result = self.client_patch(
 | 
				
			||||||
            "/json/settings/change",
 | 
					            "/json/settings",
 | 
				
			||||||
            dict(
 | 
					            dict(
 | 
				
			||||||
                old_password='bad_password',
 | 
					                old_password='bad_password',
 | 
				
			||||||
                new_password="ignored",
 | 
					                new_password="ignored",
 | 
				
			||||||
@@ -183,8 +183,8 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
				
			|||||||
        probably use a patch interface for these changes.)
 | 
					        probably use a patch interface for these changes.)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.login(self.example_email("hamlet"))
 | 
					        self.login(self.example_email("hamlet"))
 | 
				
			||||||
        result = self.client_post("/json/settings/change",
 | 
					        result = self.client_patch("/json/settings",
 | 
				
			||||||
                                  dict(old_password='ignored',))
 | 
					                                   dict(old_password='ignored',))
 | 
				
			||||||
        self.assert_json_error(result, "No new data supplied")
 | 
					        self.assert_json_error(result, "No new data supplied")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def do_test_change_user_display_setting(self, setting_name):
 | 
					    def do_test_change_user_display_setting(self, setting_name):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,7 +65,6 @@ class PublicURLTest(ZulipTestCase):
 | 
				
			|||||||
                     302: ["/accounts/logout/"],
 | 
					                     302: ["/accounts/logout/"],
 | 
				
			||||||
                     401: ["/json/messages",
 | 
					                     401: ["/json/messages",
 | 
				
			||||||
                           "/json/invite_users",
 | 
					                           "/json/invite_users",
 | 
				
			||||||
                           "/json/settings/change",
 | 
					 | 
				
			||||||
                           "/json/subscriptions/exists",
 | 
					                           "/json/subscriptions/exists",
 | 
				
			||||||
                           "/api/v1/users/me/subscriptions/properties",
 | 
					                           "/api/v1/users/me/subscriptions/properties",
 | 
				
			||||||
                           "/json/fetch_api_key",
 | 
					                           "/json/fetch_api_key",
 | 
				
			||||||
@@ -77,12 +76,17 @@ class PublicURLTest(ZulipTestCase):
 | 
				
			|||||||
                           "/api/v1/fetch_api_key",
 | 
					                           "/api/v1/fetch_api_key",
 | 
				
			||||||
                           ],
 | 
					                           ],
 | 
				
			||||||
                     }
 | 
					                     }
 | 
				
			||||||
 | 
					        patch_urls = {
 | 
				
			||||||
 | 
					            401: ["/json/settings"],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        put_urls = {401: ["/json/users/me/pointer"],
 | 
					        put_urls = {401: ["/json/users/me/pointer"],
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
        for status_code, url_set in six.iteritems(get_urls):
 | 
					        for status_code, url_set in six.iteritems(get_urls):
 | 
				
			||||||
            self.fetch("client_get", url_set, status_code)
 | 
					            self.fetch("client_get", url_set, status_code)
 | 
				
			||||||
        for status_code, url_set in six.iteritems(post_urls):
 | 
					        for status_code, url_set in six.iteritems(post_urls):
 | 
				
			||||||
            self.fetch("client_post", url_set, status_code)
 | 
					            self.fetch("client_post", url_set, status_code)
 | 
				
			||||||
 | 
					        for status_code, url_set in six.iteritems(patch_urls):
 | 
				
			||||||
 | 
					            self.fetch("client_patch", url_set, status_code)
 | 
				
			||||||
        for status_code, url_set in six.iteritems(put_urls):
 | 
					        for status_code, url_set in six.iteritems(put_urls):
 | 
				
			||||||
            self.fetch("client_put", url_set, status_code)
 | 
					            self.fetch("client_put", url_set, status_code)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,7 +82,7 @@ def json_change_ui_settings(request, user_profile,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return json_success(result)
 | 
					    return json_success(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@authenticated_json_post_view
 | 
					@human_users_only
 | 
				
			||||||
@has_request_variables
 | 
					@has_request_variables
 | 
				
			||||||
def json_change_settings(request, user_profile,
 | 
					def json_change_settings(request, user_profile,
 | 
				
			||||||
                         full_name=REQ(default=""),
 | 
					                         full_name=REQ(default=""),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ import zerver.views.muting
 | 
				
			|||||||
legacy_urls = [
 | 
					legacy_urls = [
 | 
				
			||||||
    # These are json format views used by the web client.  They require a logged in browser.
 | 
					    # These are json format views used by the web client.  They require a logged in browser.
 | 
				
			||||||
    url(r'^json/invite_users$', zerver.views.invite.json_invite_users),
 | 
					    url(r'^json/invite_users$', zerver.views.invite.json_invite_users),
 | 
				
			||||||
    url(r'^json/settings/change$', zerver.views.user_settings.json_change_settings),
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # We should remove this endpoint and all code related to it.
 | 
					    # We should remove this endpoint and all code related to it.
 | 
				
			||||||
    # It returns a 404 if the stream doesn't exist, which is confusing
 | 
					    # It returns a 404 if the stream doesn't exist, which is confusing
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -324,6 +324,8 @@ v1_api_and_json_patterns = [
 | 
				
			|||||||
        {'POST': 'zerver.views.hotspots.mark_hotspot_as_read'}),
 | 
					        {'POST': 'zerver.views.hotspots.mark_hotspot_as_read'}),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # settings -> zerver.views.user_settings
 | 
					    # settings -> zerver.views.user_settings
 | 
				
			||||||
 | 
					    url(r'^settings$', rest_dispatch,
 | 
				
			||||||
 | 
					        {'PATCH': 'zerver.views.user_settings.json_change_settings'}),
 | 
				
			||||||
    url(r'^settings/display$', rest_dispatch,
 | 
					    url(r'^settings/display$', rest_dispatch,
 | 
				
			||||||
        {'PATCH': 'zerver.views.user_settings.update_display_settings_backend'}),
 | 
					        {'PATCH': 'zerver.views.user_settings.update_display_settings_backend'}),
 | 
				
			||||||
    url(r'^settings/notifications$', rest_dispatch,
 | 
					    url(r'^settings/notifications$', rest_dispatch,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user