Permalink
Browse files

[security] improving the security scheme (#1587)

* [security] improving the security scheme

* Addressing comments

* improving docs

* Creating security module to organize things

* Moving CLI to its own module

* perms

* Materializung perms

* progrss

* Addressing comments, linting
  • Loading branch information...
1 parent aad9744 commit bce02e3f518237c03273e3ed4d9d1a13d9f8f6a9 @mistercrunch mistercrunch committed on GitHub Nov 17, 2016
View
@@ -8,6 +8,7 @@ changelog.sh
_build
_static
_images
+_modules
superset/bin/supersetc
env_py3
.eggs
View
@@ -7,8 +7,19 @@ FAB provides authentication, user management, permissions and roles.
Provided Roles
--------------
-Superset ships with 3 roles that are handled by Superset itself. You can
-assume that these 3 roles will stay up-to-date as Superset evolves.
+Superset ships with a set of roles that are handled by Superset itself.
+You can assume that these roles will stay up-to-date as Superset evolves.
+Even though it's possible for ``Admin`` usrs to do so, it is not recommended
+that you alter these roles in any way by removing
+or adding permissions to them as these roles will be re-synchronized to
+their original values as you run your next ``superset init`` command.
+
+Since it's not recommended to alter the roles described here, it's right
+to assume that your security strategy should be to compose user access based
+on these base roles and roles that you create. For instance you could
+create a role ``Financial Analyst`` that would be made of set of permissions
+to a set of data sources (tables) and/or databases. Users would then be
+granted ``Gamma``, ``Financial Analyst``, and perhaps ``sql_lab``.
Admin
"""""
@@ -33,6 +44,12 @@ mostly content consumers, though they can create slices and dashboards.
Also note that when Gamma users look at the dashboards and slices list view,
they will only see the objects that they have access to.
+sql_lab
+"""""""
+The ``sql_lab`` role grants access to SQL Lab. Note that while ``Admin``
+users have access to all databases by default, both ``Alpha`` and ``Gamma``
+users need to be given access on a per database basis.
+
Managing Gamma per data source access
-------------------------------------
@@ -23,6 +23,8 @@
app = Flask(__name__)
app.config.from_object(CONFIG_MODULE)
+conf = app.config
+
if not app.debug:
# In production mode, add log handler to sys.stderr.
app.logger.addHandler(logging.StreamHandler())
@@ -158,7 +158,7 @@ export function setNetworkStatus(networkOn) {
export function addAlert(alert) {
const o = Object.assign({}, alert);
o.id = shortid.generate();
- return { type: ADD_ALERT, o };
+ return { type: ADD_ALERT, alert: o };
}
export function removeAlert(alert) {
@@ -2,6 +2,13 @@ const $ = window.$ = require('jquery');
import React from 'react';
import Select from 'react-select';
+const propTypes = {
+ onChange: React.PropTypes.func,
+ actions: React.PropTypes.object,
+ databaseId: React.PropTypes.number,
+ valueRenderer: React.PropTypes.func,
+};
+
class DatabaseSelect extends React.PureComponent {
constructor(props) {
super(props);
@@ -23,6 +30,12 @@ class DatabaseSelect extends React.PureComponent {
const options = data.result.map((db) => ({ value: db.id, label: db.database_name }));
this.setState({ databaseOptions: options, databaseLoading: false });
this.props.actions.setDatabases(data.result);
+ if (data.result.length === 0) {
+ this.props.actions.addAlert({
+ bsStyle: 'danger',
+ msg: "It seems you don't have access to any database",
+ });
+ }
});
}
render() {
@@ -43,11 +56,6 @@ class DatabaseSelect extends React.PureComponent {
}
}
-DatabaseSelect.propTypes = {
- onChange: React.PropTypes.func,
- actions: React.PropTypes.object,
- databaseId: React.PropTypes.number,
- valueRenderer: React.PropTypes.func,
-};
+DatabaseSelect.propTypes = propTypes;
export default DatabaseSelect;
View
@@ -4,156 +4,7 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
-import logging
-import celery
-from celery.bin import worker as celery_worker
-from datetime import datetime
-from subprocess import Popen
-
-from flask_migrate import MigrateCommand
-from flask_script import Manager
-
-import superset
-from superset import app, ascii_art, db, data, utils
-
-config = app.config
-
-manager = Manager(app)
-manager.add_command('db', MigrateCommand)
-
-
-@manager.option(
- '-d', '--debug', action='store_true',
- help="Start the web server in debug mode")
-@manager.option(
- '-a', '--address', default=config.get("SUPERSET_WEBSERVER_ADDRESS"),
- help="Specify the address to which to bind the web server")
-@manager.option(
- '-p', '--port', default=config.get("SUPERSET_WEBSERVER_PORT"),
- help="Specify the port on which to run the web server")
-@manager.option(
- '-w', '--workers', default=config.get("SUPERSET_WORKERS", 2),
- help="Number of gunicorn web server workers to fire up")
-@manager.option(
- '-t', '--timeout', default=config.get("SUPERSET_WEBSERVER_TIMEOUT"),
- help="Specify the timeout (seconds) for the gunicorn web server")
-def runserver(debug, address, port, timeout, workers):
- """Starts a Superset web server"""
- debug = debug or config.get("DEBUG")
- if debug:
- app.run(
- host='0.0.0.0',
- port=int(port),
- threaded=True,
- debug=True)
- else:
- cmd = (
- "gunicorn "
- "-w {workers} "
- "--timeout {timeout} "
- "-b {address}:{port} "
- "--limit-request-line 0 "
- "--limit-request-field_size 0 "
- "superset:app").format(**locals())
- print("Starting server with command: " + cmd)
- Popen(cmd, shell=True).wait()
-
-@manager.command
-def init():
- """Inits the Superset application"""
- utils.init(superset)
-
-@manager.option(
- '-v', '--verbose', action='store_true',
- help="Show extra information")
-def version(verbose):
- """Prints the current version number"""
- s = (
- "\n{boat}\n\n"
- "-----------------------\n"
- "Superset {version}\n"
- "-----------------------").format(
- boat=ascii_art.boat, version=config.get('VERSION_STRING'))
- print(s)
- if verbose:
- print("[DB] : " + "{}".format(db.engine))
-
-@manager.option(
- '-t', '--load-test-data', action='store_true',
- help="Load additional test data")
-def load_examples(load_test_data):
- """Loads a set of Slices and Dashboards and a supporting dataset """
- print("Loading examples into {}".format(db))
-
- data.load_css_templates()
-
- print("Loading energy related dataset")
- data.load_energy()
-
- print("Loading [World Bank's Health Nutrition and Population Stats]")
- data.load_world_bank_health_n_pop()
-
- print("Loading [Birth names]")
- data.load_birth_names()
-
- print("Loading [Random time series data]")
- data.load_random_time_series_data()
-
- print("Loading [Random long/lat data]")
- data.load_long_lat_data()
-
- print("Loading [Multiformat time series]")
- data.load_multiformat_time_series_data()
-
- print("Loading [Misc Charts] dashboard")
- data.load_misc_dashboard()
-
- if load_test_data:
- print("Loading [Unicode test data]")
- data.load_unicode_test_data()
-
-@manager.option(
- '-d', '--datasource',
- help=(
- "Specify which datasource name to load, if omitted, all "
- "datasources will be refreshed"))
-def refresh_druid(datasource):
- """Refresh druid datasources"""
- session = db.session()
- from superset import models
- for cluster in session.query(models.DruidCluster).all():
- try:
- cluster.refresh_datasources(datasource_name=datasource)
- except Exception as e:
- print(
- "Error while processing cluster '{}'\n{}".format(
- cluster, str(e)))
- logging.exception(e)
- cluster.metadata_last_refreshed = datetime.now()
- print(
- "Refreshed metadata from cluster "
- "[" + cluster.cluster_name + "]")
- session.commit()
-
-
-@manager.command
-def worker():
- """Starts a Superset worker for async SQL query execution."""
- # celery -A tasks worker --loglevel=info
- print("Starting SQL Celery worker.")
- if config.get('CELERY_CONFIG'):
- print("Celery broker url: ")
- print(config.get('CELERY_CONFIG').BROKER_URL)
-
- application = celery.current_app._get_current_object()
- c_worker = celery_worker.worker(app=application)
- options = {
- 'broker': config.get('CELERY_CONFIG').BROKER_URL,
- 'loglevel': 'INFO',
- 'traceback': True,
- }
- c_worker.run(**options)
-
+from superset.cli import manager
if __name__ == "__main__":
manager.run()
Oops, something went wrong.

0 comments on commit bce02e3

Please sign in to comment.