atoti_plus.user_service_client.roles.roles module#

class atoti_plus.user_service_client.roles.Restrictions#

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 members will be granted.

Example

>>> from typing import List
>>> from atoti_plus import UserServiceClient
>>> 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(authentication=tt.BasicAuthenticationConfig())
>>> user_service_client = UserServiceClient.from_session(session)
>>> 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 name in cube.hierarchies["Geography"].levels:
...     del cube.hierarchies[name]
...
>>> password = "abcdef123456"
>>> user = user_service_client.basic.create_user("john", password=password)

Opening a query session to authenticate as the user just created:

>>> query_session = tt.QuerySession(
...     f"http://localhost:{session.port}",
...     auth=tt.BasicAuthentication(
...         username=user.username, password=password
...     ),
... )
>>> query_cube = query_session.cubes[cube.name]
>>> l, m = query_cube.levels, query_cube.measures

The user initially only has the ROLE_USER:

>>> user_service_client.individual_roles[user.username]
{'ROLE_USER'}

This role has no restrictions so all the countries and currencies are accessible:

>>> query_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:

>>> role_france = user_service_client.create_role(
...     "ROLE_FRANCE",
...     restrictions={("Restrictions example", "Country"): ["France"]},
... )
>>> user_service_client.individual_roles[user.username].add(
...     role_france.name
... )
>>> query_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 members:

>>> role_germany = user_service_client.create_role(
...     "ROLE_GERMANY",
...     restrictions={("Restrictions example", "Country"): ["Germany"]},
... )
>>> user_service_client.individual_roles[user.username].add(
...     role_germany.name
... )
>>> query_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
                  contributors.COUNT
Continent Country
Europe    France                   1
          Germany                  1

Restrictions can grant access to multiple members:

>>> role_nordic = user_service_client.create_role(
...     "ROLE_NORDIC",
...     restrictions={
...         ("Restrictions example", "Country"): ["Norway", "Sweden"]
...     },
... )
>>> user_service_client.individual_roles[user.username].add(
...     role_nordic.name
... )
>>> query_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:

>>> role_asia = user_service_client.create_role(
...     "ROLE_ASIA",
...     restrictions={("Restrictions example", "Continent"): ["Asia"]},
... )
>>> user_service_client.individual_roles[user.username].add(role_asia.name)
>>> query_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:

>>> role_eur = user_service_client.create_role(
...     "ROLE_EUR",
...     restrictions={("Restrictions example", "Currency"): ["EUR"]},
... )
>>> user_service_client.individual_roles[user.username].add(role_eur.name)
>>> query_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:

>>> for role in [role_france, role_germany]:
...     user_service_client.individual_roles[user.username].remove(
...         role.name
...     )
...
>>> query_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
Empty DataFrame
Columns: [contributors.COUNT]
Index: []
class atoti_plus.Role#

A role and its restrictions.

property name: str#
property restrictions: Restrictions#
class atoti_plus.Roles#

All of the roles defined in the session.