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

feat(dashboard_rbac): add support for related roles #13035

Merged
merged 37 commits into from
Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
014d623
feat: add support for related owners
Feb 9, 2021
9502f3e
chore: pre-commit
Feb 9, 2021
57fe69d
fix: pre-commit
Feb 9, 2021
a326a4c
fix: pylint
Feb 10, 2021
bffcc8e
fix(ci): remove signature requirements for commits to master (#13034)
nytai Feb 9, 2021
50353c1
fix: untranslated text content of Dashboard page (#13024)
cdmikechen Feb 9, 2021
94adcb3
fix: time filter db migration optimization (#13015)
ktmud Feb 9, 2021
373997f
fix(build): black failing on master, add to required checks (#13039)
robdiciuccio Feb 9, 2021
0a9e94c
feat(db engines): add support for Opendistro Elasticsearch (AWS ES) (…
dpgaspar Feb 10, 2021
1da877e
fix: UI toast typo (#13026)
dpgaspar Feb 10, 2021
a2d5196
fix: vertical scroll in query history (#13042)
betodealmeida Feb 10, 2021
90aff84
fix: timeout context manager on Windows (#13041)
betodealmeida Feb 10, 2021
638776c
style: fix typo in documentation (#13063)
dbz10 Feb 10, 2021
390029b
fix: sorting by saved metric (#13059)
villebro Feb 10, 2021
ecf6f87
fix: Disabled state button transition time (#13008)
AAfghahi Feb 11, 2021
0d7639b
fix(explore): pie chart label bugs (#13052)
villebro Feb 11, 2021
0fbc826
feat(style): hide dashboard header by url parameter (#12918)
simcha90 Feb 11, 2021
5fc1f85
fix(ci): multiline regex in change detection (#13075)
villebro Feb 11, 2021
c1316b4
fix: Retroactively add granularity param to charts (#12960)
Feb 11, 2021
230b1fb
add required * indicator to message content/notif method (#12931)
riahk Feb 11, 2021
f1622fa
fix: add config to disable dataset ownership on the old api (#13051)
dpgaspar Feb 11, 2021
7503633
fix: API tests, make them possible to run independently again (#13076)
dpgaspar Feb 11, 2021
86e647e
chore: lock down npm to v6 (#13069)
ktmud Feb 11, 2021
c2ae1a9
Added a note about the ! prefix for breaking changes to CONTRIBUTING.…
garden-of-delete Feb 11, 2021
cb99a4b
Improves RTL configuration (#13079)
michael-s-molina Feb 11, 2021
d8f198d
fix(explore): Enable selecting an option not included in suggestions …
kgabryje Feb 12, 2021
80bdb27
feat(cross-filters): add cross filters (#12662)
simcha90 Feb 12, 2021
1593bc7
Force pod restart on config changes (#13056)
Yann-J Feb 13, 2021
fda1344
feat(native-filters): Time native filter (#12992)
simcha90 Feb 13, 2021
c51dea4
feat(native-filters): add storybook entry for select filter (#13005)
simcha90 Feb 13, 2021
ad1c56f
Update http error code from 400 to 403 (#13061)
duynguyenhoang Feb 13, 2021
cd2feaf
Custom superset_config.py + secret envs (#13096)
Yann-J Feb 13, 2021
5e416e2
fix(native-filters): set currentValue null when empty (#13000)
villebro Feb 13, 2021
5ca1a4d
refactor(native-filters): decouple params from filter config modal (f…
simcha90 Feb 14, 2021
54710cf
fix: make related roles to work with tests
Feb 14, 2021
522c50c
Merge branch 'master' into feat/fetch_roles_for_dashboard
Feb 14, 2021
25d482f
fix: lint
Feb 14, 2021
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
5 changes: 4 additions & 1 deletion superset/dashboards/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
DashboardFavoriteFilter,
DashboardFilter,
DashboardTitleOrSlugFilter,
FilterRelatedRoles,
)
from superset.dashboards.schemas import (
DashboardPostSchema,
Expand Down Expand Up @@ -192,12 +193,14 @@ class DashboardRestApi(BaseSupersetModelRestApi):
order_rel_fields = {
"slices": ("slice_name", "asc"),
"owners": ("first_name", "asc"),
"roles": ("name", "asc"),
}
related_field_filters = {
"owners": RelatedFieldFilter("first_name", FilterRelatedOwners),
"roles": RelatedFieldFilter("name", FilterRelatedRoles),
"created_by": RelatedFieldFilter("first_name", FilterRelatedOwners),
}
allowed_rel_fields = {"owners", "created_by"}
allowed_rel_fields = {"owners", "roles", "created_by"}

openapi_spec_tag = "Dashboards"
""" Override the name set for this collection of endpoints """
Expand Down
32 changes: 26 additions & 6 deletions superset/dashboards/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from typing import Any

# pylint: disable=too-few-public-methods
from typing import Any, Optional

from flask_appbuilder.security.sqla.models import Role
from flask_babel import lazy_gettext as _
Expand All @@ -29,7 +31,7 @@
from superset.views.base_api import BaseFavoriteFilter


class DashboardTitleOrSlugFilter(BaseFilter): # pylint: disable=too-few-public-methods
class DashboardTitleOrSlugFilter(BaseFilter):
name = _("Title or Slug")
arg_name = "title_or_slug"

Expand All @@ -45,9 +47,7 @@ def apply(self, query: Query, value: Any) -> Query:
)


class DashboardFavoriteFilter(
BaseFavoriteFilter
): # pylint: disable=too-few-public-methods
class DashboardFavoriteFilter(BaseFavoriteFilter):
"""
Custom filter for the GET list that filters all dashboards that a user has favored
"""
Expand All @@ -57,7 +57,7 @@ class DashboardFavoriteFilter(
model = Dashboard


class DashboardFilter(BaseFilter): # pylint: disable=too-few-public-methods
class DashboardFilter(BaseFilter):
"""
List dashboards with the following criteria:
1. Those which the user owns
Expand Down Expand Up @@ -138,3 +138,23 @@ def apply(self, query: Query, value: Any) -> Query:
)

return query


class FilterRelatedRoles(BaseFilter):
"""
A filter to allow searching for related roles of a resource.

Use in the api by adding something like:
related_field_filters = {
"roles": RelatedFieldFilter("name", FilterRelatedRoles),
}
"""

name = _("Role")
arg_name = "roles"

def apply(self, query: Query, value: Optional[Any]) -> Query:
role_model = security_manager.role_model
if value:
return query.filter(role_model.name.ilike(f"%{value}%"),)
return query
36 changes: 35 additions & 1 deletion tests/dashboards/api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from sqlalchemy.sql import func

from freezegun import freeze_time
from sqlalchemy import and_, or_
from sqlalchemy import and_
from superset import db, security_manager
from superset.models.dashboard import Dashboard
from superset.models.core import FavStar, FavStarClassName
Expand Down Expand Up @@ -1343,3 +1343,37 @@ def test_import_dashboard_invalid(self):
assert response == {
"message": {"metadata.yaml": {"type": ["Must be equal to Dashboard."]}}
}

def test_get_all_related_roles(self):
"""
API: Test get filter related roles
"""
self.login(username="admin")
uri = f"api/v1/dashboard/related/roles"

rv = self.client.get(uri)
assert rv.status_code == 200
response = json.loads(rv.data.decode("utf-8"))
roles = db.session.query(security_manager.role_model).all()
expected_roles = [str(role) for role in roles]
assert response["count"] == len(roles)

response_roles = [result["text"] for result in response["result"]]
for expected_role in expected_roles:
assert expected_role in response_roles

def test_get_filter_related_roles(self):
"""
API: Test get filter related roles
"""
self.login(username="admin")
argument = {"filter": "alpha"}
uri = f"api/v1/dashboard/related/roles?q={prison.dumps(argument)}"

rv = self.client.get(uri)
assert rv.status_code == 200
response = json.loads(rv.data.decode("utf-8"))
assert response["count"] == 1

response_roles = [result["text"] for result in response["result"]]
assert "Alpha" in response_roles