11# pylint: disable=missing-module-docstring
22import logging
3- import os
43
54from http .client import HTTPException
65from typing import List , Optional , Tuple
7- from cachetools import cached , TTLCache
6+ from cachetools import cachedmethod , TTLCache
87from flask import current_app , g
98from flask_appbuilder .security .sqla .models import (
109 Role ,
@@ -18,6 +17,26 @@ class OpaSupersetSecurityManager(SupersetSecurityManager):
1817 """
1918 Custom security manager that syncs user-role mappings from Open Policy Agent to Superset.
2019 """
20+ AUTH_OPA_CACHE_MAXSIZE_DEFAULT = 1000
21+ AUTH_OPA_CACHE_TTL_IN_SEC_DEFAULT = 30
22+ AUTH_OPA_REQUEST_URL_DEFAULT = 'http://opa:8081/'
23+
24+ def __init__ (self , appbuilder ):
25+ self .appbuilder = appbuilder
26+ super ().__init__ (self .appbuilder )
27+ config = self .appbuilder .get_app .config
28+ self .opa_cache = self .opa_cache = TTLCache (
29+ maxsize = config .get (
30+ 'AUTH_OPA_CACHE_MAXSIZE' ,
31+ self .AUTH_OPA_CACHE_MAXSIZE_DEFAULT
32+ ),
33+ ttl = config .get (
34+ 'AUTH_OPA_CACHE_TTL_IN_SEC' ,
35+ self .AUTH_OPA_CACHE_TTL_IN_SEC_DEFAULT
36+ ),
37+ )
38+
39+
2140 def get_user_roles (self , user : Optional [User ] = None ) -> List [Role ]:
2241 """
2342 Retrieves a user's roles from an Open Policy Agent instance updating the
@@ -51,10 +70,7 @@ def get_user_roles(self, user: Optional[User] = None) -> List[Role]:
5170 return user .roles
5271
5372
54- @cached (cache = TTLCache (
55- maxsize = 1024 ,
56- ttl = int (os .getenv ('STACKABLE_OPA_CACHE_TTL' , '10' ))
57- ))
73+ @cachedmethod (lambda self : self .opa_cache )
5874 def get_opa_user_roles (self , username : str ) -> set [str ]:
5975 """
6076 Queries an Open Policy Agent instance for the roles of a given user.
@@ -86,7 +102,7 @@ def resolve_opa_base_url(self) -> Tuple[str, int, bool]:
86102
87103 :returns: Hostname, port and protocol (http/https).
88104 """
89- opa_base_path = current_app .config .get ('STACKABLE_OPA_BASE_URL' )
105+ opa_base_path = current_app .config .get ('STACKABLE_OPA_BASE_URL' , self . AUTH_OPA_REQUEST_URL_DEFAULT )
90106 [protocol , host , port ] = opa_base_path .split (":" )
91107 # remove any path be appended to the base url
92108 port = int (port .split ('/' )[0 ])
0 commit comments