atoti_plus.security module¶
- class atoti_plus.security.BasicSecurity(_java_api, users)¶
Manage basic authentication on the session.
Note
This requires
AuthenticationConfig
to be configured.- create_user(username, *, password=None, roles=())¶
Add a user able to authenticate against the session using Basic Authentication.
The roles and password of the user can be changed at any time.
Example
>>> session = tt.create_session( ... "tesla", config={"authentication": {"basic": {}}} ... ) >>> list(session.security.basic.users) [] >>> elon = session.security.basic.create_user("elon", password="X Æ A-12") >>> list(session.security.basic.users) ['elon'] >>> # The special ROLE_USER role is automatically added >>> elon.roles {'ROLE_USER'} >>> # Change the password >>> elon.password = "AE A-XII" >>> # Revoke access >>> del session.security.basic.users["elon"] >>> list(session.security.basic.users) []
- Return type
- users: BasicUsers¶
- class atoti_plus.security.BasicUsers(_java_api)¶
- class atoti_plus.security.IndividualRoles(_java_api)¶
The roles given to users on top of the ones that can be added by authentication providers.
Users without the ROLE_USER will not be able to access the session.
Example
>>> session = tt.create_session( ... name="roles", config={"authentication": {"basic": {}}} ... ) >>> elon = session.security.basic.create_user("John", password="X Æ A-12") >>> elon.roles {'ROLE_USER'} >>> session.security.individual_roles[elon.username].add("ROLE_USA") >>> sorted(elon.roles) ['ROLE_USA', 'ROLE_USER'] >>> session.security.individual_roles[elon.username].remove("ROLE_USA") >>> elon.roles {'ROLE_USER'} >>> # Removing all the roles will prevent the user from accessing the session: >>> del session.security.individual_roles[elon.username] >>> list(elon.roles) []
- update(__m: Mapping[str, Union[Collection[str], atoti_plus.security._UserRoles]], **kwargs: Union[Collection[str], atoti_plus.security._UserRoles]) None ¶
- update(__m: Iterable[Tuple[str, Union[Collection[str], atoti_plus.security._UserRoles]]], **kwargs: Union[Collection[str], atoti_plus.security._UserRoles]) None
- update(**kwargs: Union[Collection[str], atoti_plus.security._UserRoles]) None
Update the mapping.
- Return type
- class atoti_plus.security.KerberosSecurity(_java_api, users)¶
Manage Kerberos authentication on the session. .. note:: This requires
KerberosConfig
to be configured.- create_user(username, *, roles=())¶
Add a user able to authenticate against the session using Kerberos. The roles of the user can be changed at any time. Users without the role ROLE_USER will not have access to the application. .. seealso::
create_user()
for a similar usage example.- Return type
- users: KerberosUsers¶
- class atoti_plus.security.KerberosUsers(_java_api)¶
- class atoti_plus.security.LdapSecurity(_java_api, role_mapping)¶
Allows mapping roles granted by the authentication provider to the roles to use in the session.
Users who do not have the ROLE_USER session role will not be able to access the session.
Note
This requires
LdapConfig
to be configured.- Example
>>> session = tt.create_session( ... config={ ... "authentication": { ... "ldap": { ... "url": "ldap://ldap.forumsys.com:389/", ... "base_dn": "dc=example,dc=com", ... "user_search_filter": "(uid={0})", ... "group_search_filter": "(uniqueMember={0})", ... }, ... }, ... } ... ) >>> mathematicians_role = session.security.create_role( ... "ROLE_MATHS", restrictions={"City": ["Paris"]} ... )
Roles from the authentication provider can be mapped to roles in the session.
>>> session.security.ldap.role_mapping["MATHEMATICIANS"] = [ ... "ROLE_MATHS", ... "ROLE_USER", ... ] >>> sorted(session.security.ldap.role_mapping["MATHEMATICIANS"]) ['ROLE_MATHS', 'ROLE_USER']
- role_mapping: RoleMapping¶
- class atoti_plus.security.OidcSecurity(_java_api, role_mapping)¶
Allows mapping roles granted by the authentication provider’s ID Token to the roles to use in the session.
Users who do not have the ROLE_USER session role will not be able to access the session.
Note
This requires
OidcConfig
to be configured.Example
>>> import os >>> session = tt.create_session( ... "OpenID", ... config={ ... "authentication": { ... "oidc": { ... "provider_id": "auth0", ... "issuer_url": os.environ["AUTH0_ISSUER"], ... "client_id": os.environ["AUTH0_CLIENT_ID"], ... "client_secret": os.environ["AUTH0_CLIENT_SECRET"], ... "scopes": ["email", "profile", "username"], ... "name_claim": "email", ... "roles_claims": ["https://activeviam:eu:auth0:com/roles"], ... }, ... }, ... "port": 1234, ... }, ... ) >>> france_role = session.security.create_role( ... "ROLE_FRANCE", restrictions={"Country": "France"} ... )
Roles from the authentication provider’s ID Token can be mapped to roles in the session:
>>> session.security.oidc.role_mapping.update( ... {"atoti user": ["ROLE_USER"], "France": [france_role.name]} ... ) >>> session.security.oidc.role_mapping {'atoti user': {'ROLE_USER'}, 'France': {'ROLE_FRANCE'}}
- role_mapping: RoleMapping¶
- class atoti_plus.security.Restrictions(*, _java_api, _role, _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 >>> 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.create_session( ... config={"authentication": {"basic": {}}} ... ) >>> 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 = "BYXV$9P_rEr4" >>> user = session.security.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.roles {'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 = session.security.create_role( ... "ROLE_FRANCE", restrictions={"Country": ["France"]} ... ) >>> session.security.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 = session.security.create_role( ... "ROLE_GERMANY", restrictions={"Country": ["Germany"]} ... ) >>> session.security.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 = session.security.create_role( ... "ROLE_NORDIC", restrictions={"Country": ["Norway", "Sweden"]} ... ) >>> session.security.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 = session.security.create_role( ... "ROLE_ASIA", restrictions={"Continent": ["Asia"]} ... ) >>> session.security.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 = session.security.create_role( ... "ROLE_EUR", restrictions={"Currency": ["EUR"]} ... ) >>> session.security.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]: ... session.security.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.security.Role(name, *, restrictions, _java_api)¶
A role and its restrictions.
- restrictions: Restrictions¶
- class atoti_plus.security.RoleMapping(_java_api, _type)¶
Mapping between roles or usernames comming from the authentication provider to those to use in the session.
- update(__m: Mapping[str, Union[Iterable[str], atoti_plus.security._MappedRoles]], **kwargs: Union[Iterable[str], atoti_plus.security._MappedRoles]) None ¶
- update(__m: Iterable[Tuple[str, Union[Iterable[str], atoti_plus.security._MappedRoles]]], **kwargs: Union[Iterable[str], atoti_plus.security._MappedRoles]) None
- update(**kwargs: Union[Iterable[str], atoti_plus.security._MappedRoles]) None
Update the mapping.
- Return type
- class atoti_plus.security.Roles(_java_api)¶
All of the roles defined in the session.
- class atoti_plus.security.Security(*, java_api)¶
Security management for the current session.
- basic: BasicSecurity¶
- create_role(name, *, restrictions={})¶
Create a role with the given restrictions.
There are special roles which cannot be redefined:
ROLE_USER: required to access the application
ROLE_ADMIN: gives full access (read, write, delete, etc) to the application
- Return type
- individual_roles: IndividualRoles¶
- kerberos: KerberosSecurity¶
- ldap: LdapSecurity¶
- oidc: OidcSecurity¶