Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check for SSL certificate and add form validators #9436

Merged
merged 2 commits into from Apr 2, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 2 additions & 4 deletions superset/views/database/mixins.py
Expand Up @@ -204,10 +204,8 @@ def _pre_add_update(self, database):
check_sqlalchemy_uri(database.sqlalchemy_uri)
self.check_extra(database)
self.check_encrypted_extra(database)
utils.parse_ssl_cert(database.server_cert)
database.server_cert = (
database.server_cert.strip() if database.server_cert else ""
)
if database.server_cert:
utils.parse_ssl_cert(database.server_cert)
database.set_sqlalchemy_uri(database.sqlalchemy_uri)
security_manager.add_permission_view_menu("database_access", database.perm)
# adding a new database we always want to force refresh schema list
Expand Down
22 changes: 21 additions & 1 deletion superset/views/database/validators.py
Expand Up @@ -15,14 +15,16 @@
# specific language governing permissions and limitations
# under the License.

from typing import Type
from typing import Optional, Type

from flask_babel import lazy_gettext as _
from marshmallow import ValidationError
from sqlalchemy.engine.url import make_url
from sqlalchemy.exc import ArgumentError

from superset import security_manager
from superset.exceptions import CertificateException
from superset.utils.core import parse_ssl_cert


def sqlalchemy_uri_validator(
Expand Down Expand Up @@ -53,3 +55,21 @@ def schema_allows_csv_upload(database, schema):
security_manager.database_access(database)
or security_manager.all_datasource_access()
)


def certificate_validator(
certificate: Optional[str], exception: Type[ValidationError] = ValidationError
) -> None:
if certificate:
try:
parse_ssl_cert(certificate)
except CertificateException:
dpgaspar marked this conversation as resolved.
Show resolved Hide resolved
raise exception(
_(
"Invalid certificate. <br>"
"Please make sure the certificate begins with<br>"
"-----BEGIN CERTIFICATE-----<br>"
"and ends with<br>"
"-----END CERTIFICATE-----"
)
)
18 changes: 16 additions & 2 deletions superset/views/database/views.py
Expand Up @@ -34,7 +34,11 @@

from .forms import CsvToDatabaseForm
from .mixins import DatabaseMixin
from .validators import schema_allows_csv_upload, sqlalchemy_uri_validator
from .validators import (
certificate_validator,
schema_allows_csv_upload,
sqlalchemy_uri_validator,
)

if TYPE_CHECKING:
from werkzeug.datastructures import FileStorage # pylint: disable=unused-import
Expand All @@ -50,6 +54,13 @@ def sqlalchemy_uri_form_validator(_, field: StringField) -> None:
sqlalchemy_uri_validator(field.data, exception=ValidationError)


def certificate_form_validator(_, field: StringField) -> None:
"""
Check if user has submitted a valid SQLAlchemy URI
"""
certificate_validator(field.data, exception=ValidationError)


def upload_stream_write(form_file_field: "FileStorage", path: str):
chunk_size = app.config["UPLOAD_CHUNK_SIZE"]
with open(path, "bw") as file_description:
Expand All @@ -68,7 +79,10 @@ class DatabaseView(

add_template = "superset/models/database/add.html"
edit_template = "superset/models/database/edit.html"
validators_columns = {"sqlalchemy_uri": [sqlalchemy_uri_form_validator]}
validators_columns = {
"sqlalchemy_uri": [sqlalchemy_uri_form_validator],
"server_cert": [certificate_form_validator],
}

yaml_dict_key = "databases"

Expand Down