Skip to content

Commit f7b57fa

Browse files
committed
Feature: new permissions system
This is one huge change for the permissions system and related: * (Backward incompatible:) Remove the table based permissions in favour of the new model. * Manage permission to view or query datasources based on groups. * Add the concept of Organization. It's irrelevant for most deployments, but allows for multi-tenant support in re:dash. * Replace ActivityLog with Event based rows (old data in activity_log table is retained). * Enforce permissions on the server-side. There were some permissions that were only enforced on the client side. This is no more. All permissions are enforced by the server. * Added new permission: 'super-admin' to access the status and Flask-Admin interface. * Make sure that html is never cached by the browser - this is to make sure that the browser will always ask for the new Javascript/CSS resources (if such are available).
1 parent 6e32f5b commit f7b57fa

93 files changed

Lines changed: 2430 additions & 1458 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/setup.rst

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ t2.micro should be enough):
2828
- ap-southeast-2: `ami-7559134f <https://console.aws.amazon.com/ec2/home?region=ap-southeast-2#LaunchInstanceWizard:ami=ami-7559134f>`__
2929
- ap-southeast-1: `ami-a0786bf2 <https://console.aws.amazon.com/ec2/home?region=ap-southeast-1#LaunchInstanceWizard:ami=ami-a0786bf2>`__
3030

31+
When launching the instance make sure to use a security grop, that only allows incoming traffic on: port 22 (SSH), 80 (HTTP) and 443 (HTTPS).
3132

3233
Now proceed to `"Setup" <#setup>`__.
3334

@@ -91,10 +92,11 @@ file.
9192
1. Update the cookie secret (important! otherwise anyone can sign new
9293
cookies and impersonate users): change "veryverysecret" in the line:
9394
``export REDASH_COOKIE_SECRET=veryverysecret`` to something else (you
94-
can use ``pwgen 32 -1`` to generate random string).
95+
can run the command ``pwgen 32 -1`` to generate a random string).
9596

9697
2. By default we create an admin user with the password "admin". You
97-
can change this password at: ``/users/me#password``.
98+
can change this password opening the: ``/users/me#password`` page after
99+
logging in as admin.
98100

99101
3. If you want to use Google OAuth to authenticate users, you need to
100102
create a Google Developers project (see :doc:`instructions </misc/google_developers_project>`)
@@ -104,22 +106,29 @@ file.
104106
105107
export REDASH_GOOGLE_CLIENT_ID=""
106108
export REDASH_GOOGLE_CLIENT_SECRET=""
107-
export REDASH_GOOGLE_APPS_DOMAIN=""
108109
109110
111+
4. Configure the domain(s) you want to allow to use with Google Apps, by running the command:
112+
113+
.. code::
114+
115+
cd /opt/redash/current
116+
sudo -u redash bin/run ./manage.py set_google_apps_domains {{domains}}
117+
118+
119+
If you're passing multiple domains, separate them with commas.
110120

111-
``REDASH_GOOGLE_CLIENT_ID`` and ``REDASH_GOOGLE_CLIENT_SECRET`` are the values you get after registering with Google. ``READASH_GOOGLE_APPS_DOMAIN`` is used in case you want to limit access to single Google apps domain (*if you leave it empty anyone with a Google account can access your instance*).
112121

113-
4. Restart the web server to apply the configuration changes:
122+
5. Restart the web server to apply the configuration changes:
114123
``sudo supervisorctl restart redash_server``.
115124

116-
5. Once you have Google OAuth enabled, you can login using your Google
125+
6. Once you have Google OAuth enabled, you can login using your Google
117126
Apps account. If you want to grant admin permissions to some users,
118127
you can do this by editing the user profile and enabling admin
119128
permission for it.
120129

121-
6. If you don't use Google OAuth or just need username/password logins,
122-
you can create additional users at: ``/users/new``.
130+
7. If you don't use Google OAuth or just need username/password logins,
131+
you can create additional users by opening the ``/users/new`` page.
123132

124133
Datasources
125134
-----------

manage.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
from redash import settings, models, __version__
1010
from redash.wsgi import app
11-
from redash.import_export import import_manager
12-
from redash.cli import users, database, data_sources
11+
from redash.cli import users, database, data_sources, organization
1312
from redash.monitor import get_status
1413

1514
manager = Manager(app)
1615
manager.add_command("database", database.manager)
1716
manager.add_command("users", users.manager)
18-
manager.add_command("import", import_manager)
1917
manager.add_command("ds", data_sources.manager)
18+
manager.add_command("org", organization.manager)
19+
2020

2121

2222
@manager.command
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from playhouse.migrate import PostgresqlMigrator, migrate
2+
3+
from redash.models import db
4+
5+
if __name__ == '__main__':
6+
db.connect_db()
7+
migrator = PostgresqlMigrator(db.database)
8+
9+
with db.database.transaction():
10+
migrate(
11+
migrator.drop_column('groups', 'tables')
12+
)
13+
14+
db.close_db(None)
15+
16+
17+
18+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from redash.models import db, Organization, Group
2+
from redash import settings
3+
from playhouse.migrate import PostgresqlMigrator, migrate
4+
5+
if __name__ == '__main__':
6+
migrator = PostgresqlMigrator(db.database)
7+
8+
with db.database.transaction():
9+
Organization.create_table()
10+
11+
default_org = Organization.create(name="Default", settings={
12+
Organization.SETTING_GOOGLE_APPS_DOMAINS: settings.GOOGLE_APPS_DOMAIN
13+
})
14+
15+
column = Group.org
16+
column.default = default_org
17+
18+
migrate(
19+
migrator.add_column('groups', 'org_id', column),
20+
migrator.add_column('events', 'org_id', column),
21+
migrator.add_column('data_sources', 'org_id', column),
22+
migrator.add_column('users', 'org_id', column),
23+
migrator.add_column('dashboards', 'org_id', column),
24+
migrator.add_column('queries', 'org_id', column),
25+
migrator.add_column('query_results', 'org_id', column),
26+
)
27+
28+
# Change the uniqueness constraint on user email to be (org, email):
29+
migrate(
30+
migrator.drop_index('users', 'users_email'),
31+
migrator.add_index('users', ('org_id', 'email'), unique=True)
32+
)
33+
34+
db.close_db(None)
35+

migrations/0018_add_groups_refs.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from collections import defaultdict
2+
from redash.models import db, DataSourceGroup, DataSource, Group, Organization, User
3+
from playhouse.migrate import PostgresqlMigrator, migrate
4+
import peewee
5+
6+
if __name__ == '__main__':
7+
migrator = PostgresqlMigrator(db.database)
8+
9+
with db.database.transaction():
10+
DataSourceGroup.create_table()
11+
12+
# add default to existing data source:
13+
default_org = Organization.get_by_id(1)
14+
default_group = Group.get(Group.name=="default")
15+
for ds in DataSource.all(default_org):
16+
DataSourceGroup.create(data_source=ds, group=default_group)
17+
18+
# change the groups list on a user object to be an ids list
19+
migrate(
20+
migrator.rename_column('users', 'groups', 'old_groups'),
21+
)
22+
23+
migrate(migrator.add_column('users', 'groups', User.groups))
24+
25+
group_map = dict(map(lambda g: (g.name, g.id), Group.select()))
26+
user_map = defaultdict(list)
27+
for user in User.select(User, peewee.SQL('old_groups')):
28+
group_ids = [group_map[group] for group in user.old_groups]
29+
user.update_instance(groups=group_ids)
30+
31+
migrate(migrator.drop_column('users', 'old_groups'))
32+
33+
db.close_db(None)
34+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from redash import models
2+
3+
if __name__ == '__main__':
4+
admin_group = models.Group.get(models.Group.name=='admin')
5+
admin_group.permissions.append('super_admin')
6+
admin_group.save()

migrations/0020_add_group_type.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from redash.models import db, Group
2+
from playhouse.migrate import PostgresqlMigrator, migrate
3+
4+
if __name__ == '__main__':
5+
migrator = PostgresqlMigrator(db.database)
6+
7+
with db.database.transaction():
8+
# change the groups list on a user object to be an ids list
9+
migrate(
10+
migrator.add_column('groups', 'type', Group.type)
11+
)
12+
13+
for name in ['default', 'admin']:
14+
group = Group.get(Group.name==name)
15+
group.type = Group.BUILTIN_GROUP
16+
group.save()
17+
18+
db.close_db(None)
19+

migrations/add_created_at_field.py

Lines changed: 0 additions & 13 deletions
This file was deleted.

migrations/add_global_filters_to_dashboard.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

migrations/add_password_to_users.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)