Skip to content

Commit

Permalink
CLI command to reencrypt data source options (#4190)
Browse files Browse the repository at this point in the history
* Script to reencrypt data source options.

* Implement reencrypt sub command under database command.
  • Loading branch information
shinsuke-nara authored and arikfr committed Nov 13, 2019
1 parent cf274d9 commit d5a3f0d
Showing 1 changed file with 47 additions and 1 deletion.
48 changes: 47 additions & 1 deletion redash/cli/database.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import time

from click import argument, option
from flask.cli import AppGroup
from flask_migrate import stamp
import sqlalchemy
from sqlalchemy.exc import DatabaseError
from sqlalchemy.sql import select
from sqlalchemy_utils.types.encrypted.encrypted_type import FernetEngine

manager = AppGroup(help="Manage the database (create/drop tables).")
from redash.models.base import Column
from redash.models.types import EncryptedConfiguration
from redash.utils.configuration import ConfigurationContainer

manager = AppGroup(help="Manage the database (create/drop tables. reencrypt data.).")


def _wait_for_db_connection(db):
Expand Down Expand Up @@ -41,3 +48,42 @@ def drop_tables():

_wait_for_db_connection(db)
db.drop_all()


@manager.command()
@argument('old_secret')
@argument('new_secret')
@option('--show-sql/--no-show-sql', default=False,
help="show sql for debug")
def reencrypt(old_secret, new_secret, show_sql):
"""Reencrypt data encrypted by OLD_SECRET with NEW_SECRET."""
from redash.models import db

_wait_for_db_connection(db)

if show_sql:
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

table_for_select = sqlalchemy.Table('data_sources', sqlalchemy.MetaData(),
Column('id', db.Integer, primary_key=True),
Column('encrypted_options',
ConfigurationContainer.as_mutable(
EncryptedConfiguration(
db.Text, old_secret, FernetEngine))))
table_for_update = sqlalchemy.Table('data_sources', sqlalchemy.MetaData(),
Column('id', db.Integer, primary_key=True),
Column('encrypted_options',
ConfigurationContainer.as_mutable(
EncryptedConfiguration(
db.Text, new_secret, FernetEngine))))

update = table_for_update.update()
data_sources = db.session.execute(select([table_for_select]))
for ds in data_sources:
stmt = update.where(table_for_update.c.id == ds['id']).values(encrypted_options=ds['encrypted_options'])
db.session.execute(stmt)

data_sources.close()
db.session.commit()

0 comments on commit d5a3f0d

Please sign in to comment.