def bootstrap_user_data(user: User, include_perms: bool = False) -> Dict[str, Any]: if user.is_anonymous: payload = {} user.roles = (security_manager.find_role("Public"), ) elif security_manager.is_guest_user(user): payload = { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "isActive": user.is_active, "isAnonymous": user.is_anonymous, } else: payload = { "username": user.username, "firstName": user.first_name, "lastName": user.last_name, "userId": user.id, "isActive": user.is_active, "isAnonymous": user.is_anonymous, "createdOn": user.created_on.isoformat(), "email": user.email, } if include_perms: roles, permissions = get_permissions(user) payload["roles"] = roles payload["permissions"] = permissions return payload
def _store(self, pk, values): from uniset.models import UserProfile from superset import db from flask_appbuilder.security.sqla.models import User created = False datamodel = SQLAInterface(User, db.session) P = SQLAInterface(UserProfile, db.session) u = db.session.query(User).filter_by(email=values['email']).first() if not u: created = True u = User(first_name=values['first_name'], last_name=values['last_name'], email=values['email'], username=values['email'], roles=[self.extra['role']], active=False) datamodel.add(u) else: datamodel.add(u) if u.profiles: profile = u.profiles[0] profile.uuid = values['azure_id'] else: profile = UserProfile(user_id=u.id) profile.uuid = values['azure_id'] P.add(profile) return values, created
def test_serialize(self): user_model = User( first_name="Foo", last_name="Bar", username="******", password="******", email=TEST_EMAIL, created_on=timezone.parse(DEFAULT_TIME), changed_on=timezone.parse(DEFAULT_TIME), ) self.session.add(user_model) self.session.commit() user = self.session.query(User).filter( User.email == TEST_EMAIL).first() deserialized_user = user_schema.dump(user) # No user_id and password in dump assert deserialized_user == { 'roles': [], 'created_on': DEFAULT_TIME, 'email': '*****@*****.**', 'changed_on': DEFAULT_TIME, 'active': None, 'last_login': None, 'last_name': 'Bar', 'fail_login_count': None, 'first_name': 'Foo', 'username': '******', 'login_count': None, }
def test_unsaved_chart_unknown_dataset_id(mocker: MockFixture, app_context: AppContext) -> None: from superset.explore.form_data.utils import check_access with raises(DatasetNotFoundError): mocker.patch(dataset_find_by_id, return_value=None) check_access(dataset_id=1, chart_id=0, actor=User())
def update(self, actor: User, resource_id: int, key: str, value: str) -> Optional[bool]: dashboard = DashboardDAO.get_by_id_or_slug(str(resource_id)) if dashboard: entry: Entry = cache_manager.filter_state_cache.get( cache_key(resource_id, key)) if entry: user_id = actor.get_user_id() if entry["owner"] != user_id: raise KeyValueAccessDeniedError() new_entry: Entry = { "owner": actor.get_user_id(), "value": value } return cache_manager.filter_state_cache.set( cache_key(resource_id, key), new_entry) return False
def create(self, actor: User, resource_id: int, key: str, value: str) -> Optional[bool]: dashboard = DashboardDAO.get_by_id_or_slug(str(resource_id)) if dashboard: entry: Entry = {"owner": actor.get_user_id(), "value": value} return cache_manager.filter_state_cache.set( cache_key(resource_id, key), entry) return False
def test_unsaved_chart_authorized_dataset(mocker: MockFixture, app_context: AppContext) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.form_data.utils import check_access mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) assert check_access(dataset_id=1, chart_id=0, actor=User()) == True
def get_create_pipeline_ids(self, session): from myapp.models.model_job import Pipeline if g.user: pipeline_ids = session.query(Pipeline.id).filter( Pipeline.created_by_fk == User.get_user_id()).all() pipeline_ids = [pipeline_id[0] for pipeline_id in pipeline_ids] return pipeline_ids else: return []
def get_join_projects_id(self, session): from myapp.models.model_team import Project_User if g.user: projects_id = session.query(Project_User.project_id).filter( Project_User.user_id == User.get_user_id()).all() projects_id = [project_id[0] for project_id in projects_id] return projects_id else: return []
def test_saved_chart_unauthorized_dataset(mocker: MockFixture, app_context: AppContext) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.form_data import utils with raises(DatasetAccessDeniedError): mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=False) utils.check_access(dataset_id=1, chart_id=1, actor=User())
def test_saved_chart_unknown_chart_id(mocker: MockFixture, app_context: AppContext) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.form_data.utils import check_access with raises(ChartNotFoundError): mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) mocker.patch(chart_find_by_id, return_value=None) check_access(dataset_id=1, chart_id=1, actor=User())
def test_unsaved_chart_no_dataset_id() -> None: from superset.explore.utils import check_access as check_chart_access with raises(DatasourceNotFoundValidationError): with override_user(User()): check_chart_access( datasource_id=0, chart_id=0, datasource_type=DatasourceType.TABLE, )
def test_unsaved_chart_no_dataset_id(app_context: AppContext) -> None: from superset.explore.utils import check_access as check_chart_access with raises(DatasourceNotFoundValidationError): check_chart_access( datasource_id=0, chart_id=0, actor=User(), datasource_type=DatasourceType.TABLE, )
def test_saved_chart_is_admin(mocker: MockFixture, app_context: AppContext) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.form_data.utils import check_access from superset.models.slice import Slice mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) mocker.patch(is_user_admin, return_value=True) mocker.patch(chart_find_by_id, return_value=Slice()) assert check_access(dataset_id=1, chart_id=1, actor=User()) == True
def test_unsaved_chart_unknown_dataset_id(mocker: MockFixture) -> None: from superset.explore.utils import check_access as check_chart_access with raises(DatasetNotFoundError): mocker.patch(dataset_find_by_id, return_value=None) with override_user(User()): check_chart_access( datasource_id=1, chart_id=0, datasource_type=DatasourceType.TABLE, )
def delete(self, actor: User, resource_id: int, key: str) -> Optional[bool]: dashboard = DashboardDAO.get_by_id_or_slug(str(resource_id)) if dashboard: entry: Entry = cache_manager.filter_state_cache.get( cache_key(resource_id, key)) if entry: if entry["owner"] != actor.get_user_id(): raise KeyValueAccessDeniedError() return cache_manager.filter_state_cache.delete( cache_key(resource_id, key)) return False
def test_unsaved_chart_unknown_query_id(mocker: MockFixture, app_context: AppContext) -> None: from superset.explore.utils import check_access as check_chart_access with raises(QueryNotFoundValidationError): mocker.patch(query_find_by_id, return_value=None) check_chart_access( datasource_id=1, chart_id=0, actor=User(), datasource_type=DatasourceType.QUERY, )
def test_unsaved_chart_authorized_dataset(mocker: MockFixture) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.utils import check_access as check_chart_access mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) with override_user(User()): check_chart_access( datasource_id=1, chart_id=0, datasource_type=DatasourceType.TABLE, )
def test_saved_chart_no_access(mocker: MockFixture, app_context: AppContext) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.form_data.utils import check_access from superset.models.slice import Slice with raises(ChartAccessDeniedError): mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) mocker.patch(is_user_admin, return_value=False) mocker.patch(is_owner, return_value=False) mocker.patch(can_access, return_value=False) mocker.patch(chart_find_by_id, return_value=Slice()) check_access(dataset_id=1, chart_id=1, actor=User())
def test_saved_chart_unknown_chart_id(mocker: MockFixture) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.utils import check_access as check_chart_access with raises(ChartNotFoundError): mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) mocker.patch(chart_find_by_id, return_value=None) with override_user(User()): check_chart_access( datasource_id=1, chart_id=1, datasource_type=DatasourceType.TABLE, )
def _create_users(self, count, roles=None): # create users with defined created_on and changed_on date # for easy testing if roles is None: roles = [] return [ User( first_name=f'test{i}', last_name=f'test{i}', username=f'TEST_USER{i}', email=f'mytest@test{i}.org', roles=roles or [], created_on=timezone.parse(DEFAULT_TIME), changed_on=timezone.parse(DEFAULT_TIME), ) for i in range(1, count + 1) ]
def test_unsaved_chart_unauthorized_dataset( mocker: MockFixture, app_context: AppContext ) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.utils import check_access as check_chart_access with raises(DatasetAccessDeniedError): mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=False) with override_user(User()): check_chart_access( datasource_id=1, chart_id=0, datasource_type=DatasourceType.TABLE, )
def test_saved_chart_is_admin(mocker: MockFixture, app_context: AppContext) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.utils import check_access as check_chart_access from superset.models.slice import Slice mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) mocker.patch(is_admin, return_value=True) mocker.patch(chart_find_by_id, return_value=Slice()) with override_user(User()): check_chart_access( datasource_id=1, chart_id=1, datasource_type=DatasourceType.TABLE, )
def test_saved_chart_no_access(mocker: MockFixture) -> None: from superset.connectors.sqla.models import SqlaTable from superset.explore.utils import check_access as check_chart_access from superset.models.slice import Slice with raises(ChartAccessDeniedError): mocker.patch(dataset_find_by_id, return_value=SqlaTable()) mocker.patch(can_access_datasource, return_value=True) mocker.patch(is_admin, return_value=False) mocker.patch(is_owner, return_value=False) mocker.patch(can_access, return_value=False) mocker.patch(chart_find_by_id, return_value=Slice()) with override_user(User()): check_chart_access( datasource_id=1, chart_id=1, datasource_type=DatasourceType.TABLE, )
def get_owner(user: User) -> Optional[int]: return user.get_user_id() if not user.is_anonymous else None
def user(): from flask_appbuilder.security.sqla.models import User return User(email='*****@*****.**', username='******')
def test_sql_lab_insert_rls( mocker: MockerFixture, session: Session, app_context: None, ) -> None: """ Integration test for `insert_rls`. """ from flask_appbuilder.security.sqla.models import Role, User from superset.connectors.sqla.models import RowLevelSecurityFilter, SqlaTable from superset.models.core import Database from superset.models.sql_lab import Query from superset.security.manager import SupersetSecurityManager from superset.sql_lab import execute_sql_statement from superset.utils.core import RowLevelSecurityFilterType engine = session.connection().engine Query.metadata.create_all(engine) # pylint: disable=no-member connection = engine.raw_connection() connection.execute("CREATE TABLE t (c INTEGER)") for i in range(10): connection.execute("INSERT INTO t VALUES (?)", (i, )) cursor = connection.cursor() query = Query( sql="SELECT c FROM t", client_id="abcde", database=Database(database_name="test_db", sqlalchemy_uri="sqlite://"), schema=None, limit=5, select_as_cta_used=False, ) session.add(query) session.commit() admin = User( first_name="Alice", last_name="Doe", email="*****@*****.**", username="******", roles=[Role(name="Admin")], ) # first without RLS with override_user(admin): superset_result_set = execute_sql_statement( sql_statement=query.sql, query=query, session=session, cursor=cursor, log_params=None, apply_ctas=False, ) assert (superset_result_set.to_pandas_df().to_markdown() == """ | | c | |---:|----:| | 0 | 0 | | 1 | 1 | | 2 | 2 | | 3 | 3 | | 4 | 4 |""".strip()) assert query.executed_sql == "SELECT c FROM t\nLIMIT 6" # now with RLS rls = RowLevelSecurityFilter( filter_type=RowLevelSecurityFilterType.REGULAR, tables=[SqlaTable(database_id=1, schema=None, table_name="t")], roles=[admin.roles[0]], group_key=None, clause="c > 5", ) session.add(rls) session.flush() mocker.patch.object(SupersetSecurityManager, "find_user", return_value=admin) mocker.patch("superset.sql_lab.is_feature_enabled", return_value=True) with override_user(admin): superset_result_set = execute_sql_statement( sql_statement=query.sql, query=query, session=session, cursor=cursor, log_params=None, apply_ctas=False, ) assert (superset_result_set.to_pandas_df().to_markdown() == """ | | c | |---:|----:| | 0 | 6 | | 1 | 7 | | 2 | 8 | | 3 | 9 |""".strip()) assert query.executed_sql == "SELECT c FROM t WHERE (t.c > 5)\nLIMIT 6"
def test_unsaved_chart_no_dataset_id(app_context: AppContext) -> None: from superset.explore.form_data.utils import check_access with raises(DatasetNotFoundError): check_access(dataset_id=0, chart_id=0, actor=User())