Encrypting the passwords out of connection strings
This commit is contained in:
parent
d8c79cd26e
commit
85227912b3
|
|
@ -0,0 +1,28 @@
|
|||
"""Add encrypted password field
|
||||
|
||||
Revision ID: 289ce07647b
|
||||
Revises: 2929af7925ed
|
||||
Create Date: 2015-11-21 11:18:00.650587
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '289ce07647b'
|
||||
down_revision = '2929af7925ed'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy_utils.types.encrypted import EncryptedType
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column(
|
||||
'dbs',
|
||||
sa.Column(
|
||||
'password',
|
||||
EncryptedType(sa.String(1024)),
|
||||
nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column('dbs', 'password')
|
||||
|
|
@ -6,13 +6,14 @@ from flask.ext.appbuilder.models.mixins import AuditMixin
|
|||
from pandas import read_sql_query
|
||||
from pydruid import client
|
||||
from pydruid.utils.filters import Dimension, Filter
|
||||
import sqlalchemy as sqla
|
||||
from sqlalchemy import (
|
||||
Column, Integer, String, ForeignKey, Text, Boolean, DateTime)
|
||||
from sqlalchemy import Table
|
||||
from sqlalchemy import create_engine, MetaData, desc, select, and_
|
||||
Column, Integer, String, ForeignKey, Text, Boolean, DateTime,
|
||||
Table, create_engine, MetaData, desc, select, and_)
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import table, literal_column, text
|
||||
from sqlalchemy.sql.elements import ColumnClause
|
||||
from sqlalchemy_utils import EncryptedType
|
||||
|
||||
from copy import deepcopy, copy
|
||||
from collections import namedtuple
|
||||
|
|
@ -187,12 +188,16 @@ class Database(Model, AuditMixinNullable):
|
|||
id = Column(Integer, primary_key=True)
|
||||
database_name = Column(String(250), unique=True)
|
||||
sqlalchemy_uri = Column(String(1024))
|
||||
password = Column(EncryptedType(String(1024), config.get('SECRET_KEY')))
|
||||
|
||||
def __repr__(self):
|
||||
return self.database_name
|
||||
|
||||
def get_sqla_engine(self):
|
||||
return create_engine(self.sqlalchemy_uri)
|
||||
return create_engine(self.sqlalchemy_uri_decrypted)
|
||||
|
||||
def safe_sqlalchemy_uri(self):
|
||||
return self.sqlalchemy_uri
|
||||
|
||||
def get_table(self, table_name):
|
||||
meta = MetaData()
|
||||
|
|
@ -201,6 +206,12 @@ class Database(Model, AuditMixinNullable):
|
|||
autoload=True,
|
||||
autoload_with=self.get_sqla_engine())
|
||||
|
||||
@property
|
||||
def sqlalchemy_uri_decrypted(self):
|
||||
conn = sqla.engine.url.make_url(self.sqlalchemy_uri)
|
||||
conn.password = self.password
|
||||
return str(conn)
|
||||
|
||||
|
||||
class SqlaTable(Model, Queryable, AuditMixinNullable):
|
||||
type = "table"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from flask.ext.appbuilder.models.sqla.interface import SQLAInterface
|
|||
from flask.ext.appbuilder.security.decorators import has_access
|
||||
from pydruid.client import doublesum
|
||||
from sqlalchemy import create_engine
|
||||
import sqlalchemy as sqla
|
||||
from wtforms.validators import ValidationError
|
||||
|
||||
from panoramix import appbuilder, db, models, viz, utils, app, sm, ascii_art
|
||||
|
|
@ -105,6 +106,7 @@ class DatabaseView(PanoramixModelView, DeleteMixin):
|
|||
datamodel = SQLAInterface(models.Database)
|
||||
list_columns = ['database_name', 'created_by', 'created_on']
|
||||
add_columns = ['database_name', 'sqlalchemy_uri']
|
||||
search_exclude_columns = ('password',)
|
||||
edit_columns = add_columns
|
||||
add_template = "panoramix/models/database/add.html"
|
||||
edit_template = "panoramix/models/database/edit.html"
|
||||
|
|
@ -114,6 +116,14 @@ class DatabaseView(PanoramixModelView, DeleteMixin):
|
|||
"to structure your URI here: "
|
||||
"http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html")
|
||||
}
|
||||
def pre_add(self, db):
|
||||
conn = sqla.engine.url.make_url(db.sqlalchemy_uri)
|
||||
db.password = conn.password
|
||||
conn.password = "X" * 10 if conn.password else None
|
||||
db.sqlalchemy_uri = str(conn) # hides the password
|
||||
|
||||
def pre_update(self, db):
|
||||
self.pre_add(db)
|
||||
|
||||
appbuilder.add_view(
|
||||
DatabaseView,
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -18,6 +18,7 @@ setup(
|
|||
scripts=['panoramix/bin/panoramix'],
|
||||
install_requires=[
|
||||
'alembic>=0.7.7, <0.8.0',
|
||||
'cryptography>=1.1.1, <2.0.0',
|
||||
'flask>=0.10.1, <1.0.0',
|
||||
'flask-appbuilder>=1.4.5, <2.0.0',
|
||||
'flask-login==0.2.11',
|
||||
|
|
@ -33,6 +34,7 @@ setup(
|
|||
'python-dateutil>=2.4.2, <3.0.0',
|
||||
'requests>=2.7.0, <3.0.0',
|
||||
'sqlparse>=0.1.16, <0.2.0',
|
||||
'sqlalchemy-utils>=0.31.3, <0.32.0',
|
||||
'sqlalchemy==1.0.8',
|
||||
'flask-sqlalchemy==2.0',
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in New Issue