atoti.security.Security.restrictions#
- property Security.restrictions: MutableMapping[str, Condition[ColumnIdentifier, Literal['eq', 'isin'], Constant, Literal['and'] | None]]#
Mapping from role name to corresponding restriction.
There are reserved roles for which restrictions cannot be declared:
ROLE_USER: gives access the application
ROLE_ADMIN: gives full access (read, write, delete, etc) to the application
The restrictions associated with a role can be modified at any time.
Restrictions apply on table columns and are inherited by all hierarchies based on these columns.
Restrictions on different hierarchies are intersected.
However, if a user has several roles with restrictions on the same hierarchies, access to the union of restricted elements will be granted.
Example
>>> df = pd.DataFrame( ... [ ... ("Asia", "Korea", "KRW"), ... ("Asia", "Japan", "JPY"), ... ("Europe", "France", "EUR"), ... ("Europe", "Germany", "EUR"), ... ("Europe", "Norway", "NOK"), ... ("Europe", "Sweden", "SEK"), ... ], ... columns=["Continent", "Country", "Currency"], ... ) >>> session = tt.Session.start(tt.SessionConfig(security=tt.SecurityConfig())) >>> table = session.read_pandas( ... df, ... keys=["Continent", "Country", "Currency"], ... table_name="Restrictions example", ... ) >>> cube = session.create_cube(table) >>> h, l, m = cube.hierarchies, cube.levels, cube.measures >>> cube.hierarchies["Geography"] = [ ... table["Continent"], ... table["Country"], ... ] >>> for level_name in cube.hierarchies["Geography"]: ... del cube.hierarchies[level_name] >>> username, password = "john", "abcdef123456" >>> session.security.basic_authentication.credentials[username] = password
The user initially has no individual roles:
>>> username in session.security.individual_roles False
Adding ROLE_USER to grant access to the application:
>>> session.security.individual_roles[username] = {"ROLE_USER"}
Authenticating as the user just created:
>>> connected_session = tt.Session.connect( ... session.url, ... authentication=tt.BasicAuthentication(username, password), ... ) >>> cube = connected_session.cubes[cube.name] >>> h, l, m = cube.hierarchies, cube.levels, cube.measures
ROLE_USER has no restrictions so all the countries and currencies are accessible:
>>> cube.query(m["contributors.COUNT"], levels=[l["Country"], l["Currency"]]) contributors.COUNT Continent Country Currency Asia Japan JPY 1 Korea KRW 1 Europe France EUR 1 Germany EUR 1 Norway NOK 1 Sweden SEK 1
Adding a restricting role to the user so that only France is accessible:
>>> session.security.restrictions["ROLE_FRANCE"] = table["Country"] == "France" >>> session.security.individual_roles[username] |= {"ROLE_FRANCE"} >>> cube.query(m["contributors.COUNT"], levels=[l["Country"]]) contributors.COUNT Continent Country Europe France 1
Restrictions on the same hierarchy grant access to the union of the restricted elements:
>>> session.security.restrictions["ROLE_GERMANY"] = ( ... table["Country"] == "Germany" ... ) >>> session.security.individual_roles[username] |= {"ROLE_GERMANY"} >>> cube.query(m["contributors.COUNT"], levels=[l["Country"]]) contributors.COUNT Continent Country Europe France 1 Germany 1
Restrictions can grant access to multiple elements:
>>> session.security.restrictions["ROLE_NORDIC"] = table["Country"].isin( ... "Norway", "Sweden" ... ) >>> session.security.individual_roles[username] |= {"ROLE_NORDIC"} >>> cube.query(m["contributors.COUNT"], levels=[l["Country"]]) contributors.COUNT Continent Country Europe France 1 Germany 1 Norway 1 Sweden 1
Also give access to the Asian countries with a restriction on Continent:
>>> session.security.restrictions["ROLE_ASIA"] = table["Continent"] == "Asia" >>> session.security.individual_roles[username] |= {"ROLE_ASIA"} >>> cube.query(m["contributors.COUNT"], levels=[l["Country"]]) contributors.COUNT Continent Country Asia Japan 1 Korea 1 Europe France 1 Germany 1 Norway 1 Sweden 1
Restrictions on different hierarchies are intersected:
>>> session.security.restrictions["ROLE_EUR"] = table["Currency"] == "EUR" >>> session.security.individual_roles[username] |= {"ROLE_EUR"} >>> cube.query(m["contributors.COUNT"], levels=[l["Country"], l["Currency"]]) contributors.COUNT Continent Country Currency Europe France EUR 1 Germany EUR 1
Removing the roles granting access to France and Germany leaves no remaining accessible countries:
>>> session.security.individual_roles[username] -= { ... "ROLE_FRANCE", ... "ROLE_GERMANY", ... } >>> cube.query(m["contributors.COUNT"], levels=[l["Country"]]) Empty DataFrame Columns: [contributors.COUNT] Index: []