def __init__(self, config_file = None): self._kwargs = {} #DEBUG TEMPLATE IN CONSOLE self.user = None self._cog_ajax = None self._cog_method = None self._cog_ref_oid = None self._cog_fqtn_ = None self._cog_oid_ = None self._cog_cmd = None self.cog_trace = False self.__session = None self._session_key = None self._json_res = {} self.__collorg_path = os.path.dirname(collorg.__file__) self.__repos_path = None self.__now = None self.__db_name = config_file if self.__db_name is None: self.__repos_path, self.__db_name = db_connector.get_cog_infos() if self.__repos_path is None and self.__db_name == 'collorg_db': self.__repos_path = self.__collorg_path self.db = Db(self, *db_connector.ini_connect(self.__db_name)) self.model = self.db if 'charset' in self.db._cog_params: self._charset = self.db._cog_params['charset'] self.__debug = False if 'debug' in self.db._cog_params: Controller._debug = self.db._cog_params['debug'] open("/tmp/cog_sql", "w") try: os.chmod("/tmp/cog_sql", "0777") except: pass if not self._d_actions: if self.db_name != 'collorg_db': self.__set_app_path() self.__get_aa_tasks() self.__get_ca_tasks() self.__load_actions() self.__user_actions = None self.d_auth = {}
class Controller(object): _anonymous = None _visitor = None _cog_aa_tasks = None _cog_ca_tasks = None _charset = None _debug = False __anonymous_role = None __visitor_role = None __d_anonymous_access = {} __d_visitor_access = {} __d_ca_access = {} __d_inh_tree = {} __d_accessible_actions = {} _d_actions = {} _d_actions_by_oid = {} _d_check = {} __app_path = None def __init__(self, config_file = None): self._kwargs = {} #DEBUG TEMPLATE IN CONSOLE self.user = None self._cog_ajax = None self._cog_method = None self._cog_ref_oid = None self._cog_fqtn_ = None self._cog_oid_ = None self._cog_cmd = None self.cog_trace = False self.__session = None self._session_key = None self._json_res = {} self.__collorg_path = os.path.dirname(collorg.__file__) self.__repos_path = None self.__now = None self.__db_name = config_file if self.__db_name is None: self.__repos_path, self.__db_name = db_connector.get_cog_infos() if self.__repos_path is None and self.__db_name == 'collorg_db': self.__repos_path = self.__collorg_path self.db = Db(self, *db_connector.ini_connect(self.__db_name)) self.model = self.db if 'charset' in self.db._cog_params: self._charset = self.db._cog_params['charset'] self.__debug = False if 'debug' in self.db._cog_params: Controller._debug = self.db._cog_params['debug'] open("/tmp/cog_sql", "w") try: os.chmod("/tmp/cog_sql", "0777") except: pass if not self._d_actions: if self.db_name != 'collorg_db': self.__set_app_path() self.__get_aa_tasks() self.__get_ca_tasks() self.__load_actions() self.__user_actions = None self.d_auth = {} def check_visibility(self, obj): if obj.cog_oid_.value and not obj.check_visibility( cog_user=self.user): return False return True def __set_app_path(self): tmp = __import__( 'collorg_app', globals(), locals(), [], -1) Controller.__app_path = "{}/{}".format( tmp.__path__[0], self.__db_name) @property def app_path(self): return self.__app_path @property def collorg_path(self): return self.__collorg_path def clear(self): # open("/tmp/cog_sql", "w") # open("/tmp/cog_trace", "w") self._kwargs = {} self._cog_ajax = None self._cog_method = None self._cog_fqtn_ = None self._cog_oid_ = None self._cog_cmd = None self.__user_actions = None self.db.rollback() self.db.new_cursor() self.__now = datetime.datetime.now() def __load_actions(self): actions = self.db.table('collorg.application.action') for action in actions: self._d_actions[( action.name_.value, action.data_type_.value)] = action self._d_actions_by_oid[action.cog_oid_.value] = action check = self.db.table('collorg.application.check') check.cog_light = True for elt in check: if not elt.requires_ in self._d_check: self._d_check[elt.requires_] = [] self._d_check[elt.requires_].append(elt.required_) def get_action(self, obj, method_name): fqtn = obj.fqtn if not (method_name, obj.fqtn) in self._d_actions: for pfqtn in obj.parents_fqtns(): if (method_name, pfqtn) in self._d_actions: fqtn = pfqtn break if not (method_name, fqtn) in self._d_actions: raise RuntimeError("{} {} not found\n{}\n".format( fqtn, method_name, self._d_actions)) return None return self._d_actions[(method_name, fqtn)] def check_action(self, obj, method): """ """ if (obj.fqtn, method) in self.__d_accessible_actions: return True action = self.db.table('collorg.application.action') action.name_.value = method action.data_type_.value = obj.fqtn for in_obj in self._cog_inherits(obj): action.data_type_ += (in_obj.fqtn, '=') try: assert not action.is_empty() except: raise RuntimeError("{}.{} not accessible<br>{}".format( obj.fqtn, method, action.select(just_return_sql = True))) self.__d_accessible_actions[(obj.fqtn, method)] = True @property def _d_anonymous_access(self): return self.__d_anonymous_access @property def _d_visitor_access(self): return self.__d_visitor_access @property def _session(self): return self.__session @property def db_name(self): return self.__db_name @property def app_module(self): db_name = self.db_name if db_name == "collorg_db": return "collorg" return "collorg_app.{}".format(db_name) @property def repos_path(self): return self.__repos_path def process(self): raise NotImplementedError def __get_aa_tasks(self): """ Loads the anonymous and authenticated tasks once for all. """ if Controller._cog_aa_tasks is not None: return view = self.db.table('collorg.access.view.access_aa') view.cog_light = True view.goal_name_.value = "Anonymous navigation" view.goal_name_ += ("Authenticated navigation", "=") #view.in_menu_.value = True view._cog_order_by = [view.task_name_] Controller._cog_aa_tasks = view.select().dict_by( view.fqtn_, view.goal_name_) for key, val in Controller._cog_aa_tasks.items(): if key[1] == 'Anonymous navigation': d_elt = {} for elt in val: d_elt[elt.name_] = (elt.cog_from_, elt.cog_to_) Controller.__d_anonymous_access[key] = d_elt if key[1] == 'Authenticated navigation': d_elt = {} for elt in val: d_elt[elt.name_] = (elt.cog_from_, elt.cog_to_) Controller.__d_visitor_access[key] = d_elt def __get_ca_tasks(self): """ Loads the "Collorg actor" tasks once for all. """ if Controller._cog_ca_tasks is not None: return view = self.db.table('collorg.access.view.access_ca') view.cog_light = True view._cog_order_by = [view.task_name_] Controller._cog_ca_tasks = view.select( fields=(view.name_, view.fqtn_, view.cog_from_, view.cog_to_) ).dict_by(view.fqtn_) for key, val in Controller._cog_ca_tasks.items(): d_elt = {} for elt in val: d_elt[elt.name_] = (elt.cog_from_, elt.cog_to_) Controller.__d_ca_access[key[0]] = d_elt # open("/tmp/xxx_ca", "w").write("{}".format(Controller.__d_ca_access)) def __check(self, session_key, l_data_oid, obj, action): method_name = action.name_.value av = self.db.table('collorg.access.view.access') av.cog_light = True for data_oid in l_data_oid: av.data_oid_ += (data_oid, '=') av.name_.value = method_name av.session_key_.value = session_key return not av.is_empty() def _cog_inherits(self, obj): # pb with table._cog_inherits if obj.fqtn in self.__d_inh_tree: return self.__d_inh_tree[obj.fqtn] inh_tree = [] for elt in type.mro(type(obj)): if elt is Table: break inh_tree.append(elt(obj.db)) self.__d_inh_tree[obj.fqtn] = inh_tree return inh_tree def check_required(self, action, **kwargs): """ The execution of an action can be constained by the result of another action (the check action). The constraint is considered ok if the "check action" returns an empty string. This mecanism is used to display write icons in the header only if a user has write access to the data. """ action_oid = action.cog_oid_.value ok = True if action_oid in self._d_check: required = self._d_check[action_oid] for elt in required: check_action = self._d_actions_by_oid[elt] res = eval("kwargs['env'].{}(**kwargs)".format( check_action.name_)).strip() if not res: ok = False return ok def __in_interval(self, interval): cog_from, cog_to = interval return ((cog_from == None or cog_from < self.__now) and (cog_to == None or cog_to > self.__now)) def __check_da_dv(self, obj, method_name, func, dav): for elt in self._cog_inherits(obj): akey = (elt.fqtn, func) if akey in dav and method_name in dav[akey]: interval = dav[akey][method_name] if interval == (None, None): return True else: return self.__in_interval(interval) return False def __check_ca(self, obj, action): """ The action is granted to the user if and only if there is a granted access between obj and the action. """ assert action.write_.value is not None method_name = action.name_.value oa = self.db.table('collorg.core.oid_table') oa.cog_oid_.value = obj.cog_oid_.value dca = Controller.__d_ca_access if not self.user.has_access(oa, action.write_.value): return False for fqtn in obj.parents_fqtns(): if(fqtn in dca and method_name in dca[fqtn]): interval = dca[fqtn][method_name] if interval == (None, None): return True else: return self.__in_interval(interval) return False def check(self, obj, func): """ @returns True if access is granted, False otherwise. Anonymous and visitors accesses have been loaded once for all """ action = self.get_action(obj, func.func_name) method_name = action.name_.value if self.__check_da_dv( obj, method_name, "Anonymous navigation", Controller.__d_anonymous_access): return True if self.user is None: return False else: if self.__check_da_dv( obj, method_name, "Authenticated navigation", Controller.__d_visitor_access): return True elif self.__check_ca(obj, action): return True else: # access is granted return self.__check( self._session_key, [obj.cog_oid_.value], obj, action) def _unicode(self, str_): if type(str_) is not unicode: return unicode("%s" % str_, self._charset) return str_ def add_json_res(self, dict_): """shouldn't we call this method set_json_res""" for key, val in dict_.items(): self._json_res[key] = self._unicode(val) def _get_tasks_menu(self, data_oid): av = self.db.table('collorg.access.view.access') av.data_oid_.value = data_oid av.session_key_.value = self._session_key av.in_menu_.value = True av._cog_order_by = [av.task_name_] return av.select().dict_by(av.fqtn_, av.goal_name_)