* stop testing `collect_query_parameters`, it's an implementation detail
* add tests for `missing_query_params`
* rename SQLQuery -> ParameterizedSqlQuery
* rename sql_query.py to parameterized_query.py
* split to parameterized queries and parameterized SQL queries, where
parameterized queries only do templating and parameterized SQL queries
add tree validation on top of it
* move missing parameter detection to ParameterizedQuery
* get rid of some old code
* fix tests
* set syntax to `custom`
* revert the max-age-related refactoring
* 👋 tree validations 😢
* BaseQueryRunner is no longer a factory for ParameterizedQuery, for now
* add an endpoint for running a query by its id and (optional) parameters
without having to provide the query text
* adds parameter schema to ParameterizedQuery
* adds parameter schema validation (currently for strings)
* validate number parameters
* validate date parameters
* validate parameters on POST /api/queries/<id>/results
* validate enum parameters
* validate date range parameters
* validate query-based dropdowns by preprocessing them at the handler
level and converting them to a populated enum
* change _is_date_range to be a tad more succinct
* a single assignment with a `map` is sufficiently explanatory
* Update redash/utils/parameterized_query.py
Co-Authored-By: rauchy <omer@rauchy.net>
* Update redash/utils/parameterized_query.py
Co-Authored-By: rauchy <omer@rauchy.net>
* Update redash/utils/parameterized_query.py
Co-Authored-By: rauchy <omer@rauchy.net>
* Update redash/utils/parameterized_query.py
Co-Authored-By: rauchy <omer@rauchy.net>
* Update redash/handlers/query_results.py
Co-Authored-By: rauchy <omer@rauchy.net>
* Update redash/utils/parameterized_query.py
Co-Authored-By: rauchy <omer@rauchy.net>
* build error message inside the error
* support all types of numbers as number parameters
* check for permissions when populating query-based dropdowns
* check for access to query before running it
* check for empty rows when populating query-based enums
* don't bother loading query results if user doesn't have access
* 💥 on unexpected parameter types
* parameter schema default is a list, not a dictionary
* remove redundant null guards
* add an endpoint for running a query by its id and (optional) parameters
without having to provide the query text
* check for access to query before running it
* Use null as the default scheduled value.
* Don't serialize None to json, so we can use SQL is not null predicate.
* Fix warning about unicode in tests
* Handling empty query.schedule in UI (#3283)
* Add migration to convert empty schedules to null and drop the not null contraint.
* explicitly look for a False under details['is_invitation_pending'] and
not any falsey result, to avoid locking out invitations which were
created before the Pending Invitation feature was introduced. Solves https://github.com/getredash/redash/issues/3297
* test that old invites (that do not have any is_invitation_pending flag set in their details object) are still acceptable
* Added support for Apache Drill datasource
* Improvements in `Drill` query runner and minor refactoring
1. Drill query runner now inherits from `BaseHTTPQueryRunner`, because they both have a lot of common code.
2. `BaseHTTPQueryRunner.get_response` method now accepts `http_method` argument (original implementation was only capable of sending `GET` HTTP requests).
3. Added `order` to `BaseHTTPRequestRunner` configuration schema to fix order of UI elements based on the schema.
4. Eliminated duplicate method `_guess_type` in `GoogleSpreadsheet`, `Results` and `Drill` query runners, moved `guess_type` to `redash.query_runner`.
5. Removed tests for `_guess_type` in `GoogleSpreadsheet`, `Results` and `Drill` query runners, merged them into single test case and moved to `tests.query_runner.test_utils`.
6. Various minor changes (code style, imports, etc).
* default `is_invitation_pending` to false and actively set it to true
when inviting users, so that existing users won't show "Invitation
Pending"
* fix tests that broke due to default is_invitation_pending value
* update Flask-OAuthLib
* determine invitation_pending according to empty password. This commit will be reverted, I'm just deferring the implementation
* show '(Invitation Pending)' to users who haven't accepted their invitation yet
* allow resending invitations
* allow deletion of pending users from user list
* set invitation as not pending when following invite link
* prevent deleting activated users
* test that users who follow invitation links are set as non-pending invitations
* prevent re-using invitations
* invitees who use SSO will now also be marked as "non-pending"
* lint
* add last_active_at to users page
* Use our JSON encoder as the SQLAlchemy JSON serializer.
* Fixed some inconsistencies in the user query class methods.
* Minor cosmetic fixes.
* Add some make tasks for easier development.
* Add user detail sync system based on Redis backend.
There is a periodic Celery task that updates a new “details” JSONB column in the “user” table with the data from Redis.
Currently this is only used for tracking the date of last activity of a user but can be extended with other user information later.
Updates a few dependencies.
* Normalize a few Flask extension API names.
* Reduce implementation complexity of JSONEncoder.
* Use request_started signal to make sure we have a request context.
Otherwise loading the user based on the request won’t work.
* Fix test that checks if disabled users can login.
This correctly uses a URL path that includes the current organization and checks for the error message.
The previous test seems to have been a red herring.
* Minor cosmetic fixes.
* Remove needs_sync in favor of just deleting things.
* Misc review fixes.
* Ignore line length.
* Split redash.models import several modules.
* Move walrus UTC DateTimeField into redash.models.types.
* Restore distinctly loading dashboards.
* Simplify default values for user details.
* Define __repr__ methods generically.
* Consistently have underscore methods at the top of model methods.
* Fix tests.
* Split redash.models import several modules.
* Update to latest walrus and redis-py.
* Update kombu to 4.2.2 for redis-py 3.x compatibility.
* Remove redis-cli container after running Make task.
* Move buffer condition after datetime/time conditions.
* Update walrus to 0.7.1.
* Refactor some query APIs.
This uses the flask-sqlalchemy helpers consistently and makes more use of mixins.
* Post rebase fixes.
* Use correct kombu version
* Fix migration down revision
* display correct error message when attempting to disable yourself
* 403 (Forbidden) feels like a better status code than 400 (Bad Request)
* fix broken test
* remove redundant error title
* add SQLQuery class with tests for safe queries and non-safe tautology attacks
* add test for union query injections
* split .apply calls to newline
* add tests for comment attacks
* remove double underscore
* extract complex children check to variable
* inherit from object because I'm not a lamer
Co-Authored-By: rauchy <omer@rauchy.net>
* simplify cognitive complexity
* check that additional columns are not injected
* detect appended queries
* inline .apply calls
* move SQLQuery to it's own module
* move SQLQuery tests to their own module
* serialize SQLQuery instances
* raise an exception when attempting to serialize an unsafe query
* queries without parameters are safe
* remove redundant parentheses
* use cached properties
* rename SQLInjectionException to SQLInjectionError
* support multiple word params and param negations
* refactor out methods that don't involve any state
* don't cache text()
* reduce cognitive complexity
* Fix tag counts for dashboards to be distinct.
This also makes use of the Dashboard.all base query.
Fix#3108.
* Use Query.all_queries as the base query for Query.all_tags.
* Add test case for Dashboard.all_tags.
* avoid Query's updated_at from changing when it is linked to new query results
* move comment to previous line
* move QueryResult tests to their own module
* add test which verifies that updated_at is not changed on query data
updates
* tests were false positives - they compared HH:MM:SS, but that never
changed because the original time was 1 week behind.
* remove redundant constructor
* remove hack and use a proper event to prevent updated_at from changing
* use self.assertEqual instead of assert
* Prevent open redirection attack
* Add redirection url after logging in test
* Sanitize url just before redirecting it
* Consider when next parameter is None
* Consistently use simplejson to loading and dumping JSON.
This introduces the new functions redash.utils.json_dumps and redash.utils.json_loads and simplifies the custom encoder setup.
UUIDs are now handled by the default encoder, too.
Fixes#2807.
Use string comparison in parse_boolean instead of the (simple)json module.
The previous implementation of remote header login did not
support the multiorg mode of Re:Dash. These changes modify
the trusted header authentication to expose a per-organization
login endpoint that logs users in the specified organization.
The feature itself is not that interesting as multiorg is pretty
much impossible to use in a standalone Re:Dash installation. What's
more interesting is that all tests are executed in multiorg mode. It's
not possible to write tests for the trusted header authentication if
the method does not support multiorg mode.
To make benefits of these changes more concrete, some tests were
written to test the basic functionality of trusted header
authentication.
While RFC 5321 alows for the username/mailbox art of the address to be
case-sensitive, it is hightly discouraged.
The local-part of a mailbox MUST BE treated as case
sensitive. Therefore, SMTP implementations MUST take care to
preserve the case of mailbox local-parts. In particular, for
some hosts, the user "smith" is different from the user
"Smith". However, exploiting the case sensitivity of mailbox
local-parts impedes interoperability and is discouraged.
Mailbox domains follow normal DNS rules and are hence not
case sensitive.
-- https://tools.ietf.org/rfc/rfc5321.txt
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
The issue is, if you try to revoke the permission of a user from an
object, all the permissions on this object get removed. The fix is
assigning filtered query object to it's own reference.
According to SQLAlchemy documentation, `filter` method applies to
the **copy** of the query object which means calling filter doesn't
affect the object receiving filter call. For more information;
http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.filter
* Draft queries are now called "Unpublished" -- felt like it better convey the feature.
* Unpublished queries won't be shown in "All Queries" for non owners, but will appear in
search.
* You can't add unpublished queries to dashboards or alerts.