示例#1
0
    def _check_GET_permission(self):
        GET = self.setting.get("GET")
        if not GET:
            raise UliwebError("'%s' not accessible by apijson"%(self.name))
    
        roles = GET.get("roles")
        params_role = self.params.get("@role")
        
        if not params_role:
            if hasattr(request,"user"):
                params_role = "LOGIN"
            else:
                params_role = "UNKNOWN"
        elif params_role != "UNKNOWN":
            if not hasattr(request,"user"):
                raise UliwebError("no login user for role '%s'"%(params_role))
        if params_role not in roles:
            raise UliwebError("'%s' not accessible by role '%s'"%(self.name,params_role))
        if params_role == "UNKNOWN":
            self.permission_check_ok = True
        elif functions.has_role(request.user,params_role):
            self.permission_check_ok = True
        else:
            raise UliwebError("user doesn't have role '%s'"%(params_role))

        if not self.permission_check_ok:
            raise UliwebError("no permission")
        
        self.params_role = params_role
示例#2
0
    def _get_array_params(self):
        query_count = self.query_params.get("@count")
        if query_count:
            try:
                query_count = int(query_count)
            except ValueError as e:
                log.error("bad param in '%s': '%s'" %
                          (query_count, self.query_params))
                raise UliwebError("@count should be an int, but get '%s'" %
                                  (query_count))
        self.query_count = query_count

        query_page = self.query_params.get("@page")
        if query_page:
            #@page begin from 0
            try:
                query_page = int(query_page)
            except ValueError as e:
                log.error("bad param in '%s': '%s'" %
                          (query_page, self.query_params))
                raise UliwebError("@page should be an int, but get '%s'" %
                                  (query_page))
            if query_page < 0:
                raise UliwebError("page should >0, but get '%s'" %
                                  (query_page))
        self.query_page = query_page

        #https://github.com/TommyLemon/APIJSON/blob/master/Document.md#32-%E5%8A%9F%E8%83%BD%E7%AC%A6
        query_type = self.query_params.get("@query", 0)
        if query_type not in [0, 1, 2]:
            raise UliwebError("bad param 'query': %s" % (query_type))
        self.query_type = query_type

        #order not in query params but in model params
        self.order = self.params.get("@order")
示例#3
0
    def _check_GET_permission(self):
        GET = self.setting.get("GET")
        if not GET:
            raise UliwebError("'%s' not accessible by apijson" % (self.name))

        roles = GET.get("roles")
        params_role = self.params.get("@role")
        user = getattr(request, "user", None)

        if roles:
            if not params_role:
                if user:
                    params_role = "LOGIN"
                else:
                    params_role = "UNKNOWN"
            elif params_role != "UNKNOWN":
                if not user:
                    raise UliwebError("no login user for role '%s'" %
                                      (params_role))
            if params_role not in roles:
                raise UliwebError("'%s' not accessible by role '%s'" %
                                  (self.name, params_role))
            if params_role == "UNKNOWN":
                self.permission_check_ok = True
            elif functions.has_role(user, params_role):
                self.permission_check_ok = True
            else:
                raise UliwebError("user doesn't have role '%s'" %
                                  (params_role))
        if not self.permission_check_ok:
            perms = GET.get("permissions")
            if perms:
                if params_role:
                    role, msg = functions.has_permission_as_role(
                        user, params_role, *perms)
                    if role:
                        self.permission_check_ok = True
                else:
                    role = functions.has_permission(user, *perms)
                    if role:
                        role_name = getattr(role, "name")
                        if role_name:
                            self.permission_check_ok = True
                            params_role = role_name

        if not self.permission_check_ok:
            raise UliwebError("no permission")

        self.params_role = params_role
示例#4
0
 def install_exposes(self):
     #EXPOSES format
     #endpoint = topic              #bind_name will be the same with function
     #expose_name = topic, func        
     #expose_name = topic, func, {args}
     d = settings.get('EXPOSES', {})
     for name, args in d.items():
         if not args:
             continue
         is_wrong = False
         if isinstance(args, (tuple, list)):
             if len(args) == 2:
                 expose(args[0], name=name)(args[1])
             elif len(args) == 3:
                 if not isinstance(args[2], dict):
                     is_wrong = True
                 else:
                     expose(args[0], name=name, **args[2])(args[1])
             else:
                 is_wrong = True
         elif isinstance(args, (str, unicode)):
             expose(args)(name)
         else:
             is_wrong = True
         if is_wrong:
             log.error('EXPOSES definition should be "endpoint=url" or "name=url, endpoint" or "name=url, endpoint, {"args":value1,...}"')
             raise UliwebError('EXPOSES definition [%s=%r] is not right' % (name, args))
示例#5
0
    def __init__(self, name, params, parent, key):
        self.name = name
        self.params = params
        self.parent = parent
        self.key = key
        self.query_params = self.parent.request_data[key]

        try:
            self.model = getattr(models, name)
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'" % (name, e))
            raise UliwebError("model '%s' not found" % (name))

        self.setting = settings.APIJSON_MODELS.get(name, {})
        self.secret_fields = self.setting.get("secret_fields")
        self.column = params.get("@column")
        if self.column:
            self.column_set = set(self.column.split(","))
            if self.secret_fields:
                self.column_set -= set(self.secret_fields)
            self.column_set &= set(self.model.columns.keys())
        else:
            self.column_set = None

        self.permission_check_ok = False
示例#6
0
 def _conver():
     nonlocal v
     if v and col.type.python_type == datetime:
         _v = v
         v = to_datetime(v, tzinfo=getattr(request, "tzinfo", None))
         if v == None:
             raise UliwebError("'%s' cannot convert to datetime" % (_v))
示例#7
0
 def install_binds(self):
     #process DISPATCH hooks
     #BINDS format
     #func = topic              #bind_name will be the same with function
     #bind_name = topic, func        
     #bind_name = topic, func, {args}
     d = settings.get('BINDS', {})
     for bind_name, args in d.items():
         if not args:
             continue
         is_wrong = False
         if isinstance(args, (tuple, list)):
             if len(args) == 2:
                 dispatch.bind(args[0])(args[1])
             elif len(args) == 3:
                 if not isinstance(args[2], dict):
                     is_wrong = True
                 else:
                     dispatch.bind(args[0], **args[2])(args[1])
             else:
                 is_wrong = True
         elif isinstance(args, (str, unicode)):
             dispatch.bind(args)(bind_name)
         else:
             is_wrong = True
         if is_wrong:
             log.error('BINDS definition should be "function=topic" or "bind_name=topic, function" or "bind_name=topic, function, {"args":value1,...}"')
             raise UliwebError('BINDS definition [%s=%r] is not right' % (bind_name, args))
示例#8
0
 def sort_middlewares(self, middlewares):
     #middleware process
     #middleware can be defined as
     #middleware_name = middleware_class_path[, order]
     #middleware_name = <empty> will be skip
     m = []
     for v in middlewares:
         if not v:
             continue
         
         order = None
         if isinstance(v, (list, tuple)):
             if len(v) > 2:
                 raise UliwebError('Middleware %r difinition is not right' % v)
             middleware_path = v[0]
             if len(v) == 2:
                 order = v[1]
         else:
             middleware_path = v
         cls = import_attr(middleware_path)
         
         if order is None:
             order = getattr(cls, 'ORDER', 500)
         m.append((order, cls))
     
     m.sort(cmp=lambda x, y: cmp(x[0], y[0]))
         
     return [x[1] for x in m]
示例#9
0
 def __getattr__(self, name):
     if name in self.__objects:
         return self.__objects[name]
     if name not in settings[self.__section]:
         raise UliwebError("Object %s is not existed!" % name)
     obj = import_attr(settings[self.__section].get(name))
     self.__objects[name] = obj
     return obj
示例#10
0
def function(fname, *args, **kwargs):
    func = settings.get_var('FUNCTIONS/'+fname)
    if func:
        if args or kwargs:
            return import_attr(func)(*args, **kwargs)
        else:
            return import_attr(func)
    else:
        raise UliwebError("Can't find the function [%s] in settings" % fname)
示例#11
0
文件: common.py 项目: limodou/uliweb3
def get_configrable_object(key, section, cls=None):
    """
    if obj is a class, then check if the class is subclass of cls
    or it should be object path, and it'll be imported by import_attr
    """
    from uliweb import UliwebError, settings
    import inspect

    if inspect.isclass(key) and cls and issubclass(key, cls):
        return key
    elif isinstance(key, string_types):
        path = settings[section].get(key)
        if path:
            _cls = import_attr(path)
            return _cls
        else:
            raise UliwebError("Can't find section name %s in settings" % section)
    else:
        raise UliwebError("Key %r should be subclass of %r object or string path format!" % (key, cls))
示例#12
0
def get_form(formcls):
    """
    get form class according form class path or form class object
    """
    from uliweb.form import Form
    import inspect

    if inspect.isclass(formcls) and issubclass(formcls, Form):
        return formcls
    elif isinstance(formcls, (str, unicode)):
        path = settings.FORMS.get(formcls)
        if path:
            _cls = import_attr(path)
            return _cls
        else:
            raise UliwebError("Can't find formcls name %s in settings.FORMS" %
                              formcls)
    else:
        raise UliwebError(
            "formcls should be Form class object or string path format, but %r found!"
            % formcls)
示例#13
0
 def _filter_owner(self,q):
     owner_filtered = False
     if hasattr(self.model,"owner_condition"):
         q = q.filter(self.model.owner_condition(request.user.id))
         owner_filtered = True
     if not owner_filtered:
         user_id_field = self.setting.get("user_id_field")
         if user_id_field:
             q = q.filter(getattr(self.model.c,user_id_field)==request.user.id)
             owner_filtered = True
     if not owner_filtered:
         raise UliwebError("'%s' cannot filter with owner"%(self.name))
     return q
示例#14
0
 def _ref_get(self, path, context=None):
     if context == None:
         context = {}
     if path[0] == "/":
         #relative path
         c = context
         for i in path.split("/"):
             if i:
                 if isinstance(c, dict):
                     c = c.get(i)
                 elif isinstance(c, list):
                     try:
                         c = c[int(i)]
                     except Exception as e:
                         raise UliwebError(
                             "bad path item '%s' in path '%s', error: %s" %
                             (i, path, e))
                 else:
                     raise UliwebError("cannot get '%s' from '%s'" % (i, c))
         return c
     else:
         #absolute path
         c = self.rdict
         for i in path.split("/"):
             if i:
                 if isinstance(c, dict):
                     c = c.get(i)
                 elif isinstance(c, list):
                     try:
                         c = c[int(i)]
                     except Exception as e:
                         raise UliwebError(
                             "bad path item '%s' in path '%s', error: %s" %
                             (i, path, e))
                 else:
                     raise UliwebError("bad path item '%s' in path '%s'" %
                                       (i, path))
         return c
示例#15
0
    def query_array(self):
        self._check_GET_permission()
        self._get_array_params()
        params = self.params.copy()

        #update reference
        ref_fields = []
        refs = {}
        for n in params:
            if n[-1] == "@":
                ref_fields.append(n)
                col_name = n[:-1]
                path = params[n]
                refs[col_name] = self.parent._ref_get(path)
        if ref_fields:
            for i in ref_fields:
                del params[i]
            params.update(refs)

        q = self._get_array_q(params)

        if self.query_type in [1, 2]:
            self.parent.vars["/%s/total" % (self.key)] = q.count()

        if self.query_type in [0, 2]:
            if self.query_count:
                if self.query_page:
                    q = q.offset(self.query_page * self.query_count)
                q = q.limit(self.query_count)
            if self.order:
                for k in self.order.split(","):
                    if k[-1] == "+":
                        sort_key = k[:-1]
                        sort_order = "asc"
                    elif k[-1] == "-":
                        sort_key = k[:-1]
                        sort_order = "desc"
                    else:
                        sort_key = k
                        sort_order = "asc"
                    try:
                        column = getattr(self.model.c, sort_key)
                    except AttributeError as e:
                        raise UliwebError("'%s' doesn't have column '%s'" %
                                          (self.name, sort_key))
                    q = q.order_by(getattr(column, sort_order)())
            l = [self._get_info(i, True) for i in q]
            self.parent.rdict[self.key] = l
示例#16
0
 def _expr(self, model, model_param, model_expr):
     if not isinstance(model_expr, list):
         raise UliwebError("only accept array in @expr, but get '%s'" %
                           (model_expr))
     num = len(model_expr)
     if (num < 2 or num > 3):
         raise UliwebError(
             "only accept 2 or 3 items in @expr, but get '%s'" %
             (model_expr))
     op = model_expr[-2]
     if op == '&':
         if num != 3:
             raise UliwebError(
                 "'&'(and) expression need 3 items, but get '%s'" %
                 (model_expr))
         c1 = self._get_filter_condition(model,
                                         model_param,
                                         model_expr[0],
                                         expr=True)
         c2 = self._get_filter_condition(model,
                                         model_param,
                                         model_expr[2],
                                         expr=True)
         return and_(c1, c2)
     elif op == '|':
         if num != 3:
             raise UliwebError(
                 "'|'(or) expression need 3 items, but get '%s'" %
                 (model_expr))
         c1 = self._get_filter_condition(model,
                                         model_param,
                                         model_expr[0],
                                         expr=True)
         c2 = self._get_filter_condition(model,
                                         model_param,
                                         model_expr[2],
                                         expr=True)
         return or_(c1, c2)
     elif op == '!':
         if num != 2:
             raise UliwebError(
                 "'!'(not) expression need 2 items, but get '%s'" %
                 (model_expr))
         return not_(
             self._get_filter_condition(model,
                                        model_param,
                                        model_expr[1],
                                        expr=True))
     else:
         raise UliwebError("unknown operator: '%s'" % (op))
示例#17
0
    def _get_filter_condition_from_str(self, col, cond_str):
        cond_str = cond_str.strip()
        c1, c2 = cond_str[0], cond_str[1]
        v = None

        def _conver():
            nonlocal v
            if v and col.type.python_type == datetime:
                _v = v
                v = to_datetime(v, tzinfo=getattr(request, "tzinfo", None))
                if v == None:
                    raise UliwebError("'%s' cannot convert to datetime" % (_v))

        if c1 == '>':
            if c2 == "=":
                v = cond_str[2:]
                _conver()
                return col >= v
            else:
                v = cond_str[1:]
                _conver()
                return col > cond_str[1:]
        elif c1 == '<':
            if c2 == "=":
                v = cond_str[2:]
                _conver()
                return col <= v
            else:
                v = cond_str[1:]
                _conver()
                return col < v
        elif c1 == "=":
            v = cond_str[1:]
            _conver()
            return col == v
        elif c1 == "!" and c2 == "=":
            v = cond_str[2:]
            _conver()
            return col != v
        raise UliwebError("not support '%s'" % (cond_str))
示例#18
0
 def set_log(self):
     import logging
     
     s = self.settings
     
     def _get_level(level):
         return getattr(logging, level.upper())
     
     #get basic configuration
     config = {}
     for k, v in s.LOG.items():
         if k in ['format', 'datefmt', 'filename', 'filemode']:
             config[k] = v
             
     if s.get_var('LOG/level'):
         config['level'] = _get_level(s.get_var('LOG/level'))
     logging.basicConfig(**config)
     
     if config.get('filename'):
         Handler = 'logging.FileHandler'
         if config.get('filemode'):
             _args =(config.get('filename'), config.get('filemode'))
         else:
             _args = (config.get('filename'),)
     else:
         Handler = 'logging.StreamHandler'
         _args = ()
     
     #process formatters
     formatters = {}
     for f, v in s.get_var('LOG.Formatters', {}).items():
         formatters[f] = logging.Formatter(v)
         
     #process handlers
     handlers = {}
     for h, v in s.get_var('LOG.Handlers', {}).items():
         handler_cls = v.get('class', Handler)
         handler_args = v.get('args', _args)
         
         handler = import_attr(handler_cls)(*handler_args)
         if v.get('level'):
             handler.setLevel(_get_level(v.get('level')))
         
         format = v.get('format')
         if format in formatters:
             handler.setFormatter(formatters[format])
         elif format:
             fmt = logging.Formatter(format)
             handler.setFormatter(fmt)
             
         handlers[h] = handler
         
     #process loggers
     for logger_name, v in s.get_var('LOG.Loggers', {}).items():
         if logger_name == 'ROOT':
             log = logging.getLogger('')
         else:
             log = logging.getLogger(logger_name)
             
         if v.get('level'):
             log.setLevel(_get_level(v.get('level')))
         if 'propagate' in v:
             log.propagate = v.get('propagate')
         if 'handlers' in v:
             for h in v['handlers']:
                 if h in handlers:
                     log.addHandler(handlers[h])
                 else:
                     raise UliwebError("Log Handler %s is not defined yet!")
                     sys.exit(1)
         elif 'format' in v:
             if v['format'] not in formatters:
                 fmt = logging.Formatter(v['format'])
             else:
                 fmt = formatters[v['format']]
             _handler = import_attr(Handler)(*_args)
             _handler.setFormatter(fmt)
             log.addHandler(_handler)
示例#19
0
    def _get_filter_condition(self, model, model_param, item, expr=False):
        #item can be param key, or expr which expected to be a list
        if isinstance(item, list):
            if expr:
                return self._expr(model, model_param, model_expr=item)
            else:
                #current implementation won't run here, but keep for safe
                raise UliwebError("item can be list only in @expr: '%s'" %
                                  (item))
        if not isinstance(item, string_types):
            #current implementation won't run here, but keep for safe
            raise UliwebError("item should be array or string: '%s'" % (item))
        n = item
        if n[0] == "@":
            #current implementation won't run here, but keep for safe
            raise UliwebError("param key should not begin with @: '%s'" % (n))
        if n[-1] == "$":
            name = n[:-1]
            if hasattr(model, name):
                return getattr(model.c, name).like(model_param[n])
            else:
                raise UliwebError("model does not have column: '%s'" % (name))
        elif n[-1] == "}" and n[-2] == "{":
            if n[-3] in ["&", "|", "!"]:
                operator = n[-3]
                name = n[:-3]
            else:
                operator = None
                name = n[:-2]

            if not hasattr(model, name):
                raise UliwebError("model does not have column: '%s'" % (name))

            # https://github.com/APIJSON/APIJSON/blob/master/Document.md#32-%E5%8A%9F%E8%83%BD%E7%AC%A6
            # https://vincentcheng.github.io/apijson-doc/zh/grammar.html#%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97-%E7%AD%9B%E9%80%89
            col = getattr(model.c, name)
            cond = model_param[n]
            if isinstance(cond, list):
                fcond = col.in_(cond)
                if operator == "!":
                    fcond = not_(fcond)
                return fcond
            elif isinstance(cond, str):
                cond_list = cond.strip().split(",")
                if len(cond_list) == 1:
                    fcond = self._get_filter_condition_from_str(
                        col, cond_list[0])
                    if operator == "!":
                        fcond = not_(fcond)
                    return fcond
                elif len(cond_list) > 1:
                    fcond = self._get_filter_condition_from_str(
                        col, cond_list[0])
                    for c in cond_list[1:]:
                        fc = self._get_filter_condition_from_str(col, c)
                        if operator == "&":
                            fcond = and_(fcond, fc)
                        elif operator == "|" or operator == None:
                            fcond = or_(fcond, fc)
                        else:
                            raise UliwebError(
                                "'%s' not supported in condition list" %
                                (operator))
                    return fcond

            raise UliwebError("not support '%s':'%s'" % (n, cond))
        elif hasattr(model, n):
            return getattr(model.c, n) == model_param[n]
        else:
            raise UliwebError("non-existent column or not support item: '%s'" %
                              (item))