Skip to content

Commit

Permalink
Change: encrtpy data source options
Browse files Browse the repository at this point in the history
  • Loading branch information
arikfr committed Jan 31, 2019
1 parent bd559b6 commit 0a50438
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""add_encrypted_options_to_data_sources
Revision ID: 98af61feea92
Revises: 73beceabb948
Create Date: 2019-01-31 09:21:31.517265
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '98af61feea92'
down_revision = '73beceabb948'
branch_labels = None
depends_on = None


def upgrade():
# TODO:
# create column
# copy values
# drop old column
pass


def downgrade():
pass
11 changes: 7 additions & 4 deletions redash/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
from sqlalchemy_utils import generic_relationship
from sqlalchemy_utils.types import TSVectorType
from sqlalchemy_utils.models import generic_repr
from sqlalchemy_utils.types.encrypted.encrypted_type import FernetEngine

from redash import redis_connection, utils
from redash import redis_connection, utils, settings
from redash.destinations import (get_configuration_schema_for_destination_type,
get_destination)
from redash.metrics import database # noqa: F401
Expand All @@ -36,7 +37,7 @@
from .changes import ChangeTrackingMixin, Change # noqa
from .mixins import BelongsToOrgMixin, TimestampMixin
from .organizations import Organization
from .types import Configuration, MutableDict, MutableList, PseudoJSON
from .types import EncryptedConfiguration, Configuration, MutableDict, MutableList, PseudoJSON
from .users import (AccessPermission, AnonymousUser, ApiUser, Group, User) # noqa

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -76,7 +77,9 @@ class DataSource(BelongsToOrgMixin, db.Model):

name = Column(db.String(255))
type = Column(db.String(255))
options = Column(ConfigurationContainer.as_mutable(Configuration))
# TODO: remove
_options = Column('options', db.Text, default='{}')
options = Column('encrypted_options', ConfigurationContainer.as_mutable(EncryptedConfiguration(db.Text, settings.SECRET_KEY, FernetEngine)))
queue_name = Column(db.String(255), default="queries")
scheduled_queue_name = Column(db.String(255), default="scheduled_queries")
created_at = Column(db.DateTime(True), default=db.func.now())
Expand Down Expand Up @@ -554,7 +557,7 @@ def outdated_queries(cls):
.options(joinedload(Query.latest_query_data).load_only('retrieved_at'))
.filter(Query.schedule.isnot(None))
.order_by(Query.id))

now = utils.utcnow()
outdated_queries = {}
scheduled_queries_executions.refresh()
Expand Down
10 changes: 10 additions & 0 deletions redash/models/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from sqlalchemy.types import TypeDecorator
from sqlalchemy.ext.indexable import index_property
from sqlalchemy.ext.mutable import Mutable
from sqlalchemy_utils import EncryptedType

from redash.utils import json_dumps, json_loads
from redash.utils.configuration import ConfigurationContainer
Expand All @@ -19,6 +20,14 @@ def process_result_value(self, value, dialect):
return ConfigurationContainer.from_json(value)


class EncryptedConfiguration(EncryptedType):
def process_bind_param(self, value, dialect):
return super(EncryptedConfiguration, self).process_bind_param(value.to_json(), dialect)

def process_result_value(self, value, dialect):
return ConfigurationContainer.from_json(super(EncryptedConfiguration, self).process_result_value(value, dialect))


# XXX replace PseudoJSON and MutableDict with real JSON field
class PseudoJSON(TypeDecorator):
impl = db.Text
Expand Down Expand Up @@ -87,6 +96,7 @@ class json_cast_property(index_property):
entity attribute as the specified cast type. Useful
for JSON and JSONB colums for easier querying/filtering.
"""

def __init__(self, cast_type, *args, **kwargs):
super(json_cast_property, self).__init__(*args, **kwargs)
self.cast_type = cast_type
Expand Down
2 changes: 2 additions & 0 deletions redash/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def all_settings():

return settings


REDIS_URL = os.environ.get('REDASH_REDIS_URL', os.environ.get('REDIS_URL', "redis://localhost:6379/0"))
PROXIES_COUNT = int(os.environ.get('REDASH_PROXIES_COUNT', "1"))

Expand Down Expand Up @@ -107,6 +108,7 @@ def all_settings():
JOB_EXPIRY_TIME = int(os.environ.get("REDASH_JOB_EXPIRY_TIME", 3600 * 12))
COOKIE_SECRET = os.environ.get("REDASH_COOKIE_SECRET", "c292a0a3aa32397cdb050e233733900f")
SESSION_COOKIE_SECURE = parse_boolean(os.environ.get("REDASH_SESSION_COOKIE_SECURE") or str(ENFORCE_HTTPS))
SECRET_KEY = os.environ.get('REDASH_SECRET_KEY', COOKIE_SECRET)

LOG_LEVEL = os.environ.get("REDASH_LOG_LEVEL", "INFO")
LOG_STDOUT = parse_boolean(os.environ.get('REDASH_LOG_STDOUT', 'false'))
Expand Down
2 changes: 2 additions & 0 deletions redash/utils/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,6 @@ def __contains__(self, item):

@classmethod
def from_json(cls, config_in_json):
if config_in_json is None:
return cls({})
return cls(json_loads(config_in_json))

0 comments on commit 0a50438

Please sign in to comment.