Fixed dashboard restrictions and added tests.

This commit is contained in:
Seva Gavrilov 2016-03-29 13:27:35 -03:00
parent 5bb1d2757e
commit c98cdef8f2
2 changed files with 107 additions and 14 deletions

View File

@ -886,14 +886,15 @@ class Dashboard(ModelTimestampsMixin, BaseModel, BelongsToOrgMixin):
@classmethod
def all(cls, groups, user_id):
query = cls.select().\
join(Widget, on=(Dashboard.id == Widget.dashboard), join_type=peewee.JOIN_LEFT_OUTER).\
join(Visualization, on=(Widget.visualization == Visualization.id), join_type=peewee.JOIN_LEFT_OUTER).\
join(Query, on=(Visualization.query == Query.id), join_type=peewee.JOIN_LEFT_OUTER).\
join(DataSourceGroup, on=(Query.data_source == DataSourceGroup.data_source), join_type=peewee.JOIN_LEFT_OUTER).\
where(Dashboard.is_archived == False).\
where((DataSourceGroup.group << groups) | (Dashboard.user == user_id) | (Widget.visualization_id is None)).\
join(Widget, peewee.JOIN_LEFT_OUTER, on=(Dashboard.id == Widget.dashboard)). \
join(Visualization, peewee.JOIN_LEFT_OUTER, on=(Widget.visualization == Visualization.id)). \
join(Query, peewee.JOIN_LEFT_OUTER, on=(Visualization.query == Query.id)). \
join(DataSourceGroup, peewee.JOIN_LEFT_OUTER, on=(Query.data_source == DataSourceGroup.data_source)). \
where(Dashboard.is_archived == False). \
where((DataSourceGroup.group << groups) |
(Dashboard.user == user_id) |
(~(Widget.dashboard >> None) & (Widget.visualization >> None))). \
group_by(Dashboard.id)
logging.info('The query is: %s', query.sql())
return query
@classmethod
@ -903,16 +904,18 @@ class Dashboard(ModelTimestampsMixin, BaseModel, BelongsToOrgMixin):
@classmethod
def recent(cls, groups, user_id, for_user=False, limit=20):
query = cls.select().where(Event.created_at > peewee.SQL("current_date - 7")). \
join(Event, on=(Dashboard.id == Event.object_id.cast('integer')), join_type=peewee.JOIN_LEFT_OUTER). \
join(Widget, on=(Dashboard.id == Widget.dashboard), join_type=peewee.JOIN_LEFT_OUTER).\
join(Visualization, on=(Widget.visualization == Visualization.id), join_type=peewee.JOIN_LEFT_OUTER).\
join(Query, on=(Visualization.query == Query.id), join_type=peewee.JOIN_LEFT_OUTER).\
join(DataSourceGroup, on=(Query.data_source == DataSourceGroup.data_source), join_type=peewee.JOIN_LEFT_OUTER).\
where(Event.action << ('edit', 'view')).\
join(Event, peewee.JOIN_LEFT_OUTER, on=(Dashboard.id == Event.object_id.cast('integer'))). \
join(Widget, peewee.JOIN_LEFT_OUTER, on=(Dashboard.id == Widget.dashboard)). \
join(Visualization, peewee.JOIN_LEFT_OUTER, on=(Widget.visualization == Visualization.id)). \
join(Query, peewee.JOIN_LEFT_OUTER, on=(Visualization.query == Query.id)). \
join(DataSourceGroup, peewee.JOIN_LEFT_OUTER, on=(Query.data_source == DataSourceGroup.data_source)). \
where(Event.action << ('edit', 'view')). \
where(~(Event.object_id >> None)). \
where(Event.object_type == 'dashboard'). \
where(Dashboard.is_archived == False). \
where((DataSourceGroup.group << groups) | (Dashboard.user == user_id) | (Widget.visualization_id is None)). \
where((DataSourceGroup.group << groups) |
(Dashboard.user == user_id) |
(~(Widget.dashboard >> None) & (Widget.visualization >> None))). \
group_by(Event.object_id, Dashboard.id). \
order_by(peewee.SQL("count(0) desc"))

View File

@ -519,3 +519,93 @@ class TestWidgetDeleteInstance(BaseTestCase):
widget2.delete_instance()
self.assertEquals("[]", widget.dashboard.layout)
def _set_up_dashboard_test(d):
d.g1 = d.factory.create_group(name='First')
d.g2 = d.factory.create_group(name='Second')
d.ds1 = d.factory.create_data_source()
d.ds2 = d.factory.create_data_source()
d.u1 = d.factory.create_user(groups=[d.g1.id])
d.u2 = d.factory.create_user(groups=[d.g2.id])
models.DataSourceGroup.create(group=d.g1, data_source=d.ds1, permissions=['create', 'view'])
models.DataSourceGroup.create(group=d.g2, data_source=d.ds2, permissions=['create', 'view'])
d.q1 = d.factory.create_query(data_source=d.ds1)
d.q2 = d.factory.create_query(data_source=d.ds2)
d.v1 = d.factory.create_visualization(query=d.q1)
d.v2 = d.factory.create_visualization(query=d.q2)
d.w1 = d.factory.create_widget(visualization=d.v1)
d.w2 = d.factory.create_widget(visualization=d.v2)
class TestDashboardAll(BaseTestCase):
def setUp(self):
super(TestDashboardAll, self).setUp()
_set_up_dashboard_test(self)
def test_requires_group_or_user_id(self):
d1 = self.factory.create_dashboard()
self.assertNotIn(d1, models.Dashboard.all(d1.user.groups, None))
self.assertIn(d1, models.Dashboard.all([0], d1.user.id))
def test_returns_dashboards_based_on_groups(self):
self.assertIn(self.w1.dashboard, models.Dashboard.all(self.u1.groups, None))
self.assertIn(self.w2.dashboard, models.Dashboard.all(self.u2.groups, None))
self.assertNotIn(self.w1.dashboard, models.Dashboard.all(self.u2.groups, None))
self.assertNotIn(self.w2.dashboard, models.Dashboard.all(self.u1.groups, None))
def test_returns_dashboards_created_by_user(self):
d1 = self.factory.create_dashboard(user=self.u1)
self.assertIn(d1, models.Dashboard.all(self.u1.groups, self.u1.id))
self.assertIn(d1, models.Dashboard.all([0], self.u1.id))
self.assertNotIn(d1, models.Dashboard.all(self.u2.groups, self.u2.id))
def test_returns_dashboards_with_text_widgets(self):
w1 = self.factory.create_widget(visualization=None)
self.assertIn(w1.dashboard, models.Dashboard.all(self.u1.groups, None))
self.assertIn(w1.dashboard, models.Dashboard.all(self.u2.groups, None))
class TestDashboardRecent(BaseTestCase):
def setUp(self):
super(TestDashboardRecent, self).setUp()
_set_up_dashboard_test(self)
def test_returns_recent_dashboards_basic(self):
models.Event.create(org=self.factory.org, user=self.u1, action="view",
object_type="dashboard", object_id=self.w1.dashboard.id)
self.assertIn(self.w1.dashboard, models.Dashboard.recent(self.u1.groups, None))
self.assertNotIn(self.w2.dashboard, models.Dashboard.recent(self.u1.groups, None))
self.assertNotIn(self.w1.dashboard, models.Dashboard.recent(self.u2.groups, None))
def test_returns_recent_dashboards_created_by_user(self):
d1 = self.factory.create_dashboard(user=self.u1)
models.Event.create(org=self.factory.org, user=self.u1, action="view",
object_type="dashboard", object_id=d1.id)
self.assertIn(d1, models.Dashboard.recent([0], self.u1.id))
self.assertNotIn(self.w2.dashboard, models.Dashboard.recent([0], self.u1.id))
self.assertNotIn(d1, models.Dashboard.recent([0], self.u2.id))
def test_returns_recent_dashboards_with_no_visualizations(self):
w1 = self.factory.create_widget(visualization=None)
models.Event.create(org=self.factory.org, user=self.u1, action="view",
object_type="dashboard", object_id=w1.dashboard.id)
self.assertIn(w1.dashboard, models.Dashboard.recent([0], self.u1.id))
self.assertNotIn(self.w2.dashboard, models.Dashboard.recent([0], self.u1.id))
def test_restricts_dashboards_for_user(self):
models.Event.create(org=self.factory.org, user=self.u1, action="view",
object_type="dashboard", object_id=self.w1.dashboard.id)
models.Event.create(org=self.factory.org, user=self.u2, action="view",
object_type="dashboard", object_id=self.w2.dashboard.id)
self.assertIn(self.w1.dashboard, models.Dashboard.recent(self.u1.groups, self.u1.id, for_user=True))
self.assertIn(self.w2.dashboard, models.Dashboard.recent(self.u2.groups, self.u2.id, for_user=True))
self.assertNotIn(self.w1.dashboard, models.Dashboard.recent(self.u2.groups, self.u2.id, for_user=True))
self.assertNotIn(self.w2.dashboard, models.Dashboard.recent(self.u1.groups, self.u1.id, for_user=True))