Beispiel #1
0
 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 = {}
Beispiel #2
0
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_)