Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ before_install:
- npm install -g npm@'>=3.9.5'
before_script:
- mysql -e 'drop database if exists caravel; create database caravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci' -u root
- mysql -u root -e "CREATE USER 'mysqluser'@'localhost' IDENTIFIED BY 'mysqluserpassword';"
- mysql -u root -e "GRANT ALL ON caravel.* TO 'mysqluser'@'localhost';"
- psql -c 'create database caravel;' -U postgres
- psql -c "CREATE USER postgresuser WITH PASSWORD 'pguserpassword';" -U postgres
- export PATH=${PATH}:/tmp/hive/bin
install:
- pip install --upgrade pip
Expand Down
6 changes: 6 additions & 0 deletions caravel/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,12 @@ def backend(self):
url = make_url(self.sqlalchemy_uri_decrypted)
return url.get_backend_name()

def set_sqlalchemy_uri(self, uri):
conn = sqla.engine.url.make_url(uri)
self.password = conn.password
conn.password = "X" * 10 if conn.password else None
self.sqlalchemy_uri = str(conn) # hides the password

def get_sqla_engine(self, schema=None):
extra = self.get_extra()
url = make_url(self.sqlalchemy_uri_decrypted)
Expand Down
2 changes: 1 addition & 1 deletion caravel/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def get_or_create_main_db(caravel):
if not dbobj:
dbobj = DB(database_name="main")
logging.info(config.get("SQLALCHEMY_DATABASE_URI"))
dbobj.sqlalchemy_uri = config.get("SQLALCHEMY_DATABASE_URI")
dbobj.set_sqlalchemy_uri(config.get("SQLALCHEMY_DATABASE_URI"))
dbobj.expose_in_sqllab = True
db.session.add(dbobj)
db.session.commit()
Expand Down
16 changes: 7 additions & 9 deletions caravel/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,6 @@ class DatabaseView(CaravelModelView, DeleteMixin): # noqa
}

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
utils.merge_perm(sm, 'database_access', db.perm)

def pre_update(self, db):
Expand Down Expand Up @@ -1252,15 +1248,17 @@ def testconn(self):
try:
uri = request.json.get('uri')
db_name = request.json.get('name')
if db_name and ':XXXXXXXXXX@' in uri:
if db_name:
database = (
db.session()
db.session
.query(models.Database)
.filter_by(database_name=db_name).first()
.filter_by(database_name=db_name)
.first()
)
if database is not None:
if uri == database.safe_sqlalchemy_uri():
# the password-masked uri was passed
# use the URI associated with this database
uri = database.sqlalchemy_uri_decrypted

connect_args = (
request.json
.get('extras', {})
Expand Down
17 changes: 15 additions & 2 deletions tests/core_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,30 @@ def test_misc(self):
assert self.client.get('/ping').data.decode('utf-8') == "OK"

def test_testconn(self):
data = json.dumps({'uri': 'sqlite:////tmp/caravel_unittests.db'})
database = (
db.session
.query(models.Database)
.filter_by(database_name='main')
.first()
)

# validate that the endpoint works with the password-masked sqlalchemy uri
data = json.dumps({
'uri': database.safe_sqlalchemy_uri(),
'name': 'main'
})
response = self.client.post('/caravel/testconn', data=data, content_type='application/json')
assert response.status_code == 200

# validate that the endpoint works with the decrypted sqlalchemy uri
data = json.dumps({
'uri': 'postgresql+psycopg2://foo:XXXXXXXXXX@127.0.0.1/bar',
'uri': database.sqlalchemy_uri_decrypted,
'name': 'main'
})
response = self.client.post('/caravel/testconn', data=data, content_type='application/json')
assert response.status_code == 200


def test_warm_up_cache(self):
slice = db.session.query(models.Slice).first()
resp = self.client.get(
Expand Down
10 changes: 5 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ commands =
[testenv:py27-mysql]
basepython = python2.7
setenv =
CARAVEL__SQLALCHEMY_DATABASE_URI = mysql://root@localhost/caravel
CARAVEL__SQLALCHEMY_DATABASE_URI = mysql://mysqluser:mysqluserpassword@localhost/caravel

[testenv:py34-mysql]
basepython = python3.4
setenv =
CARAVEL__SQLALCHEMY_DATABASE_URI = mysql://root@localhost/caravel
CARAVEL__SQLALCHEMY_DATABASE_URI = mysql://mysqluser:mysqluserpassword@localhost/caravel

[testenv:py35-mysql]
basepython = python3.5
setenv =
CARAVEL__SQLALCHEMY_DATABASE_URI = mysql://root@localhost/caravel
CARAVEL__SQLALCHEMY_DATABASE_URI = mysql://mysqluser:mysqluserpassword@localhost/caravel

[testenv:py27-sqlite]
basepython = python2.7
Expand All @@ -62,12 +62,12 @@ setenv =
[testenv:py27-postgres]
basepython = python2.7
setenv =
CARAVEL__SQLALCHEMY_DATABASE_URI = postgresql+psycopg2://postgres@localhost/caravel
CARAVEL__SQLALCHEMY_DATABASE_URI = postgresql+psycopg2://postgresuser:pguserpassword@localhost/caravel

[testenv:py34-postgres]
basepython = python3.4
setenv =
CARAVEL__SQLALCHEMY_DATABASE_URI = postgresql+psycopg2://postgres@localhost/caravel
CARAVEL__SQLALCHEMY_DATABASE_URI = postgresql+psycopg2://postgresuser:pguserpassword@localhost/caravel

[testenv:javascript]
commands = {toxinidir}/caravel/assets/js_build.sh