Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 34 additions & 22 deletions redash/handlers/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -193,6 +193,8 @@ def post(self):
:<json string description:
:<json string schedule: Schedule interval, in seconds, for repeated execution of this query
:<json object options: Query options
:<json string tags: Query tags


.. _query-response-label:

Expand Down Expand Up @@ -221,15 +223,21 @@ def post(self):
require_access(data_source, self.current_user, not_view_only)
require_access_to_dropdown_queries(self.current_user, query_def)

for field in [
"id",
"created_at",
"api_key",
"visualizations",
"latest_query_data",
"last_modified_by",
]:
query_def.pop(field, None)
query_def = project(
query_def,
(
"data_source_id",
"query",
"name",
"description",
"schedule",
"options",
"tags",
),
)

if "tags" in query_def:
query_def["tags"] = [tag for tag in set(query_def["tags"]) if tag]

query_def["query_text"] = query_def.pop("query")
query_def["user"] = self.current_user
Expand Down Expand Up @@ -320,6 +328,7 @@ def post(self, query_id):
:<json string description:
:<json string schedule: Schedule interval, in seconds, for repeated execution of this query
:<json object options: Query options
:<json string tags: Query tags

Responds with the updated :ref:`query <query-response-label>` object.
"""
Expand All @@ -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)
Expand Down
46 changes: 46 additions & 0 deletions tests/handlers/test_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Loading