diff --git a/redash/handlers/queries.py b/redash/handlers/queries.py index 71ae418da8..eb9fb1a8bf 100644 --- a/redash/handlers/queries.py +++ b/redash/handlers/queries.py @@ -2,7 +2,7 @@ from flask import jsonify, request, url_for from flask_login import login_required from flask_restful import abort -from funcy import partial +from funcy import partial, project from sqlalchemy.orm.exc import StaleDataError from redash import models, settings @@ -193,6 +193,8 @@ def post(self): :` object. """ @@ -329,23 +338,26 @@ def post(self, query_id): require_object_modify_permission(query, self.current_user) require_access_to_dropdown_queries(self.current_user, query_def) - for field in [ - "id", - "created_at", - "api_key", - "visualizations", - "latest_query_data", - "user", - "last_modified_by", - "org", - ]: - query_def.pop(field, None) + query_def = project( + query_def, + ( + "data_source_id", + "query", + "name", + "description", + "schedule", + "options", + "tags", + "version", + "latest_query_data_id", + ), + ) if "query" in query_def: query_def["query_text"] = query_def.pop("query") if "tags" in query_def: - query_def["tags"] = [tag for tag in query_def["tags"] if tag] + query_def["tags"] = [tag for tag in set(query_def["tags"]) if tag] if "data_source_id" in query_def: data_source = models.DataSource.get_by_id_and_org(query_def["data_source_id"], self.current_org) diff --git a/tests/handlers/test_queries.py b/tests/handlers/test_queries.py index 7fbf51128c..66dbdceced 100644 --- a/tests/handlers/test_queries.py +++ b/tests/handlers/test_queries.py @@ -75,6 +75,52 @@ def test_query_search(self): class TestQueryResourcePost(BaseTestCase): + def test_prevents_update_query_owner(self): + query = self.factory.create_query() + user = self.factory.create_user() + owner = query.user + owner_id = query.user.id + query_id = query.id + data = {"user_id": user.id, "name": "testing"} + db.session.expire_all() + rv = self.make_request( + "post", + "/api/queries/{0}".format(query_id), + data=data, + user=owner, + ) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.json["user"]["id"], owner_id) + + def test_pervents_create_query_as_archived(self): + user = self.factory.create_admin() + ds = self.factory.create_data_source() + rv = self.make_request( + "post", + "/api/queries", + data={"name": "Testing", "data_source_id": ds.id, "query": "test", "is_archived": True}, + user=user, + ) + self.assertEqual(rv.status_code, 200) + self.assertNotEqual(rv.json["is_archived"], True) + + def test_pervents_update_query_skip_updated_at(self): + query = self.factory.create_query() + owner = query.user + updated_at = query.updated_at + query_id = query.id + data = {"skip_updated_at": True} + db.session.expire_all() + rv = self.make_request( + "post", + "/api/queries/{0}".format(query_id), + data=data, + user=owner, + ) + self.assertEqual(rv.status_code, 200) + db.session.expire_all() + self.assertNotEqual(query.updated_at, updated_at) + def test_update_query(self): admin = self.factory.create_admin() query = self.factory.create_query()