Пример #1
0
def has_obj_role(user, obj, user_id_field, as_role, *roles):
    from uliweb import functions
    if as_role:
        if as_role not in roles:
            return False, "role '%s' has no permission to access the data" % (
                as_role)
        if not functions.has_role(user, as_role):
            return False, "user has no role '%s'" % (as_role)
        if as_role == "OWNER":
            if not is_obj_owner(user, obj, user_id_field):
                return False, "user is not the owner of data"
        return True, None
    else:
        for role in roles:
            if functions.has_role(user, role):
                if isinstance(role, str):
                    role_name = role
                elif hasattr(role, "name"):
                    role_name = role.name
                else:
                    continue
                if role_name == "OWNER":
                    if is_obj_owner(user, obj, user_id_field):
                        return True, None
                    else:
                        continue
                else:
                    return True, None
        return False, "no role to access the data"
Пример #2
0
    def list(self):
        if request.user:
            role = "ADMIN" if functions.has_role(request.user,
                                                 "ADMIN") else "OWNER"
        else:
            role = "UNKNOWN"
        apijson_tables = functions.get_apijson_tables()

        def _get_model(i):
            model_name = i.model_name
            model = settings.APIJSON_MODELS.get(model_name, {})
            if not i.role:
                roles = model.get("GET", {}).get("roles")
                i.role = roles[0] if isinstance(roles, list) else roles
            return model

        models = [_get_model(i) for i in apijson_tables]

        def _get_request(i):
            request_tag = i.request_tag or i.model_name
            return settings.APIJSON_REQUESTS.get(request_tag, {})

        requests = [_get_request(i) for i in apijson_tables]
        return {
            "apijson_tables_json":
            json_dumps([d.to_dict() for d in apijson_tables]),
            "models_json":
            json_dumps(models),
            "requests_json":
            json_dumps(requests),
            "role":
            role,
        }
Пример #3
0
def default_validators(item, context):
    """
    Check role and permission
    role and permission check result will be cached in context dict
    """
    from uliweb import functions, request

    roles = item.get('roles', [])
    perms = item.get('permissions', [])
    if roles or perms:
        if roles:
            con_roles = context.setdefault('roles', {})
            for x in roles:
                if x in con_roles:
                    flag = con_roles[x]
                else:
                    flag = functions.has_role(request.user, x)
                    con_roles[x] = flag
                if flag:
                    return flag

        if perms:
            con_perms = context.setdefault('permissions', {})
            for x in perms:
                if x in con_perms:
                    flag = con_perms[x]
                else:
                    flag = functions.has_permission(request.user, x)
                    con_perms[x] = flag
            if flag:
                return flag
    else:
        return True
Пример #4
0
def default_validators(item, context):
    """
    Check role and permission
    role and permission check result will be cached in context dict
    """
    from uliweb import functions, request
    
    roles = item.get('roles', [])
    perms = item.get('permissions', [])
    if roles or perms:
        if roles:
            con_roles = context.setdefault('roles', {})
            for x in roles:
                if x in con_roles:
                    flag = con_roles[x]
                else:
                    flag = functions.has_role(request.user, x)
                    con_roles[x] = flag
                if flag:
                    return flag
            
        if perms:
            con_perms = context.setdefault('permissions', {})
            for x in perms:
                if x in con_perms:
                    flag = con_perms[x]
                else:
                    flag = functions.has_permission(request.user, x)
                    con_perms[x] = flag
            if flag:
                return flag
    else:
        return True
Пример #5
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
Пример #6
0
def has_permission(user, *permissions, **role_kwargs):
    """
    Judge if an user has permission, and if it does return role object, and if it doesn't
    return False. role_kwargs will be passed to role functions.
    With role object, you can use role.relation to get Role_Perm_Rel object.
    """
    Role = get_model('role')
    Perm = get_model('permission')
    Role_Perm_Rel = get_model('role_perm_rel')

    if isinstance(user, (unicode, str)):
        User = get_model('user')
        user = User.get(User.c.username == user)

    for name in permissions:
        perm = Perm.get(Perm.c.name == name)
        if not perm:
            continue

        flag = functions.has_role(
            user,
            *list(
                perm.perm_roles.filter(
                    Role_Perm_Rel.c.scheme == None).with_relation().all()),
            **role_kwargs)
        if flag:
            return flag

    return False
Пример #7
0
    def _head(self,key):
        modelname = key
        params = self.request_data[key]
        params_role = params.get("@role")

        try:
            model = getattr(models,modelname)
            model_setting = settings.APIJSON_MODELS.get(modelname,{})
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
            return json({"code":400,"msg":"model '%s' not found"%(modelname)})

        q = model.all()

        HEAD = model_setting.get("HEAD")
        if not HEAD:
            return json({"code":400,"msg":"'%s' not accessible"%(modelname)})
        
        roles = HEAD.get("roles")
        permission_check_ok = False
        if not params_role:
            if request.user:
                params_role = "LOGIN"
            else:
                params_role = "UNKNOWN"
        if params_role not in roles:
            return json({"code":400,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
        if params_role == "UNKNOWN":
            permission_check_ok = True
        elif functions.has_role(request.user,params_role):
            permission_check_ok = True
        else:
            return json({"code":400,"msg":"user doesn't have role '%s'"%(params_role)})
        if not permission_check_ok:
            return json({"code":400,"msg":"no permission"})

        if params_role=="OWNER":
            owner_filtered,q = self._filter_owner(model,model_setting,q)
            if not owner_filtered:
                return  json({"code":400,"msg":"'%s' cannot filter with owner"%(modelname)})
        for n in params:
            if n[0]=="@":
                pass
            else:
                param = params[n]
                if not hasattr(model.c,n):
                    return  json({"code":400,"msg":"'%s' don't have field '%s'"%(modelname,n)})
                q = model.filter(getattr(model.c,n)==param)
        rdict = {
            "code":200,
            "msg":"success",
            "count":q.count(),
        }

        self.rdict[key] = rdict
Пример #8
0
    def edit(self, id):
        """
        编辑分类
        """
        obj = self.model.get_or_notfound(int(id))

        if not functions.has_role(request.user, 'superuser'):
            flash("你无权修改教程", 'error')
            return redirect(url_for(TutorialcateView.read, id=id))

        view = functions.EditView(self.model, ok_url=url_for(TutorialcateView.read, id=id), obj=obj)
        return view.run()
Пример #9
0
    def delete(self, id):
        """
        删除分类
        """
        obj = self.model.get_or_notfound(int(id))

        if not functions.has_role(request.user, 'superuser'):
            flash("你无权删除分类", 'error')
            return redirect(url_for(TutorialcateView.read, id=id))

        view = functions.DeleteView(self.model, ok_url="/tutorial", obj=obj)
        return view.run()
Пример #10
0
    def delete(self, id):
        """
        删除分类
        """
        obj = self.model.get_or_notfound(int(id))

        if not functions.has_role(request.user, 'superuser'):
            flash("你无权删除分类", 'error')
            return redirect(url_for(TutorialcateView.read, id=id))

        view = functions.DeleteView(self.model, ok_url="/tutorial",
            obj=obj)
        return view.run()
Пример #11
0
    def edit(self, id):
        """
        编辑分类
        """
        obj = self.model.get_or_notfound(int(id))

        if not functions.has_role(request.user, 'superuser'):
            flash("你无权修改教程", 'error')
            return redirect(url_for(TutorialcateView.read, id=id))

        view = functions.EditView(self.model,
                                  ok_url=url_for(TutorialcateView.read, id=id),
                                  obj=obj)
        return view.run()
Пример #12
0
 def _get_list_view(self):
     from uliweb.utils.generic import ListView
     
     if functions.has_role(request.user, 'superuser'):
         condition = None
     else:
         condition = self.model.teachers.in_(request.user.id)
     
     view = ListView(self.model, pagination=False, 
         condition=condition,
         order_by=[self.model.c.order.desc(), self.model.c.create_date.desc()],
         fields_convert_map={'link':self.convert_link}
     )
     return view
Пример #13
0
    def __begin__(self):
        from uliweb import settings, functions
        roles = settings.get_var('REDBREAST/MonitorRoles', None)
        if roles and not request.user.is_superuser:
            passed = False
            for role in roles:
                if functions.has_role(request.user, role):
                    passed = True

            if passed == False:
                error('你没有权限访问这个链接!')
        else:
            if not request.user.is_superuser:
                error('你不是超级用户不能进行这项操作!')
Пример #14
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
Пример #15
0
 def list(self):
     table_keys = settings.APIJSON_MODELS.keys()
     if request.user:
         if functions.has_role(request.user, "ADMIN"):
             role = "ADMIN"
         else:
             role = "OWNER"
     else:
         role = "UNKNOWN"
     apijson_tables = functions.get_apijson_tables(role)
     return {
         "table_keys_json": json_dumps(table_keys),
         "apijson_tables_json": json_dumps(apijson_tables),
         "role": role,
     }
Пример #16
0
def has_permission_as_role(user, as_role, *perms):
    from uliweb import functions, models

    Role = models.role
    Perm = models.permission

    flag = functions.has_role(user, as_role)
    if not flag:
        return False, "user has no role '%s'" % (as_role)

    for name in perms:
        perm = Perm.get(Perm.c.name == name)
        if not perm:
            continue
        for role in perm.perm_roles.with_relation().all():
            if role.name == as_role:
                return role, None
    return False, "no permission"
Пример #17
0
def has_permission(user, *permissions, **role_kwargs):
    """
    Judge if an user has permission, and if it does return role object, and if it doesn't
    return False. role_kwargs will be passed to role functions.
    With role object, you can use role.relation to get Role_Perm_Rel object.
    """
    Role = get_model('role')
    Perm = get_model('permission')
    Role_Perm_Rel = get_model('role_perm_rel')

    if isinstance(user, (unicode, str)):
        User = get_model('user')
        user = User.get(User.c.username==user)

    for name in permissions:
        perm = Perm.get(Perm.c.name==name)
        if not perm:
            continue

        flag = functions.has_role(user, *list(perm.perm_roles.filter(Role_Perm_Rel.c.scheme==None).with_relation().all()), **role_kwargs)
        if flag:
            return flag

    return False
Пример #18
0
    def _can_edit_tutorial(self, obj):
        from uliweb import request

        return (obj.authors.has(request.user)
                or functions.has_role(request.user, 'superuser'))
Пример #19
0
 def _find_permissions(self, perms, acl=None, user=None, check_default=True, pagename=''):
     """
     Check permission of one page, or just get default acl
     
     perms can be single value or a list value
     """
     from uliweb import request, settings
     from uliweb.utils.common import import_attr
     
     if check_default:
         _acl = self._get_default_acl
     else:
         _acl = []
     if isinstance(acl, (str, unicode)):
         page_acl, acl_lines, i = find_acl(acl, settings.WIKI_ACL_ALIAS)
     elif isinstance(acl, dict):
         page_acl = acl
     else:
         page_acl = []
     
     if not user:
         user = request.user
         
     if isinstance(perms, (tuple, list)):
         p = set(perms)
     elif isinstance(perms, set):
         p = perms.copy()
     else:
         p = set([perms])
         
     #perms result
     result = {}
     for d in page_acl + _acl:
         find = False
         if not p:
             break
         if d['type'] == 'user':
             if d['name'] == 'All':
                 find = True
             else:
                 if user and user.username == d['name']:
                     find = True
         elif d['type'] == 'role':
             if functions.has_role(user, d['name']):
                 find = True
         #add other type extention
         else:
             if d['type'] in settings.get_var('WIKI/WIKI_ACL_TYPES', {}):
                 func = import_attr(settings.get_var('WIKI/WIKI_ACL_TYPES')[d['type']])
                 if func(user, d['name']):
                     find = True
                 
         if find:
             f_perms = p.intersection(d['perms'])
             if f_perms:
                 p.difference_update(f_perms)
                 for x in f_perms:
                     #if mode is not '-', then think it's enable
                     #otherwise disable
                     result[x] = d['mode'] != '-'
             if p and d['mode'] in ('+', '-'):
                 continue
             else:
                 #set not found perm to False
                 for x in p:
                     result[x] = False
                 p = set()
                 break
     if user:
         username = user.username
     else:
         username = '******'
     log.debug("ACL check: perms=%r, user=%s, result=%r, rest=%r, pagename=%s, acl=%s", perms, username, result, p, pagename, acl)
     return result, p
Пример #20
0
    def _get_one(self, key):
        model_name = key
        params = self.request_data[key]
        params_role = params.get("@role")

        try:
            model = getattr(models, model_name)
            model_setting = settings.APIJSON_MODELS.get(model_name, {})
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'" %
                      (model_name, e))
            return json({
                "code": 400,
                "msg": "model '%s' not found" % (model_name)
            })
        model_column_set = None
        q = model.all()

        GET = model_setting.get("GET")
        if not GET:
            return json({
                "code": 400,
                "msg": "'%s' not accessible" % (model_name)
            })

        user = getattr(request, "user", None)
        roles = GET.get("roles")
        permission_check_ok = False
        if roles:
            if not params_role:
                params_role = "LOGIN" if user else "UNKNOWN"
            elif params_role != "UNKNOWN":
                if not user:
                    return json({
                        "code":
                        400,
                        "msg":
                        "no login user for role '%s'" % (params_role)
                    })
            if params_role not in roles:
                return json({
                    "code":
                    400,
                    "msg":
                    "'%s' not accessible by role '%s'" %
                    (model_name, params_role)
                })
            if params_role == "UNKNOWN":
                permission_check_ok = True
            elif functions.has_role(user, params_role):
                permission_check_ok = True
            else:
                return json({
                    "code": 400,
                    "msg": "user doesn't has role '%s'" % (params_role)
                })
        if not 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:
                        permission_check_ok = True
                else:
                    role = functions.has_permission(user, *perms)
                    if role:
                        role_name = getattr(role, "name")
                        if role_name:
                            permission_check_ok = True
                            params_role = role_name
        if not permission_check_ok:
            return json({
                "code": 400,
                "msg": "no permission to access the data"
            })

        if params_role == "OWNER":
            owner_filtered, q = self._filter_owner(model, model_setting, q)
            if not owner_filtered:
                return json({
                    "code":
                    400,
                    "msg":
                    "'%s' cannot filter with owner" % (model_name)
                })

        params = self.request_data[key]
        if isinstance(params, dict):
            #update reference,example: {"id@": "moment/user_id"} -> {"id": 2}
            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._ref_get(path, context=self.rdict)
            for i in ref_fields:
                del params[i]
            params.update(refs)

            for n in params:
                if n[0] == "@":
                    if n == "@column":
                        model_column_set = set(params[n].split(","))
                elif hasattr(model, n):
                    q = q.filter(getattr(model.c, n) == params[n])
                else:
                    return json({
                        "code":
                        400,
                        "msg":
                        "'%s' have no attribute '%s'" % (model_name, n)
                    })
        o = q.one()
        if o:
            o = o.to_dict()
            secret_fields = model_setting.get("secret_fields")
            if secret_fields:
                for k in secret_fields:
                    del o[k]
            if model_column_set:
                keys = list(o.keys())
                for k in keys:
                    if k not in model_column_set:
                        del o[k]
        self.rdict[key] = o
Пример #21
0
 def __begin__(self):
     functions.require_login()
     if not functions.has_role(request.user, 'superuser'):
         error("你没有权限访问此页面")
Пример #22
0
    def _delete_one(self,key,tag):
        modelname = key
        params = self.request_data[key]
        params_role = params.get("@role")

        try:
            model = getattr(models,modelname)
            model_setting = settings.APIJSON_MODELS.get(modelname,{})
            user_id_field = model_setting.get("user_id_field")
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
            return json({"code":400,"msg":"model '%s' not found"%(modelname)})
        
        request_tag = settings.APIJSON_REQUESTS.get(tag,{})
        _model_name = request_tag.get("@model_name") or tag
        request_tag_config = request_tag.get(_model_name,{})
        if not request_tag_config:
            return json({"code":400,"msg":"tag '%s' not found"%(tag)})
        tag_DELETE =  request_tag_config.get("DELETE",{})
        ADD = tag_DELETE.get("ADD")
        if ADD:
            ADD_role = ADD.get("@role")
            if ADD_role and not params_role:
                params_role = ADD_role

        try:
            id_ = params.get("id")
            if not id_:
                return json({"code":400,"msg":"id param needed"})
            id_ = int(id_)
        except ValueError as e:
            return json({"code":400,"msg":"id '%s' cannot convert to integer"%(params.get("id"))})
        obj = model.get(id_)
        if not obj:
            return json({"code":400,"msg":"cannot find record id '%s'"%(id_)})

        permission_check_ok = False
        DELETE = model_setting.get("DELETE")
        if DELETE:
            roles = DELETE.get("roles")
            if params_role:
                if not params_role in roles:
                    return json({"code":400,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
                roles = [params_role]
            if roles:
                for role in roles:
                    if role == "OWNER":
                        if request.user:
                            if user_id_field:
                                if obj.to_dict().get(user_id_field)==request.user.id:
                                    permission_check_ok = True
                                    break
                        else:
                            return json({"code":400,"msg":"need login user"})
                    elif role == "UNKNOWN":
                        permission_check_ok = True
                        break
                    else:
                        if functions.has_role(request.user,role):
                            permission_check_ok = True
                            break

        if not permission_check_ok:
            return json({"code":400,"msg":"no permission"})

        try:
            obj.delete()
            ret = True
        except Exception as e:
            log.error("remove %s %s fail"%(modelname,id_))
            ret = False

        obj_dict = {"id":id_}
        if ret:
            obj_dict["code"] = 200
            obj_dict["message"] = "success"
            obj_dict["count"] = 1
        else:
            obj_dict["code"] = 400
            obj_dict["message"] = "fail"
            obj_dict["count"] = 0
            self.rdict["code"] = 400
            self.rdict["message"] = "fail"
        self.rdict[key] = obj_dict
Пример #23
0
    def _get_one(self,key):
        modelname = key
        params = self.request_data[key]
        params_role = params.get("@role")

        try:
            model = getattr(models,modelname)
            model_setting = settings.APIJSON_MODELS.get(modelname,{})
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
            return json({"code":400,"msg":"model '%s' not found"%(modelname)})
        model_column_set = None
        q = model.all()

        GET = model_setting.get("GET")
        if not GET:
            return json({"code":400,"msg":"'%s' not accessible"%(modelname)})

        roles = GET.get("roles")
        permission_check_ok = False
        if not params_role:
            if request.user:
                params_role = "LOGIN"
            else:
                params_role = "UNKNOWN"
        if params_role not in roles:
            return json({"code":400,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
        if params_role == "UNKNOWN":
            permission_check_ok = True
        elif functions.has_role(request.user,params_role):
            permission_check_ok = True
        else:
            return json({"code":400,"msg":"user doesn't have role '%s'"%(params_role)})
        if not permission_check_ok:
            return json({"code":400,"msg":"no permission"})

        if params_role=="OWNER":
            owner_filtered,q = self._filter_owner(model,model_setting,q)
            if not owner_filtered:
                return  json({"code":400,"msg":"'%s' cannot filter with owner"%(modelname)})

        params = self.request_data[key]
        if isinstance(params,dict):
            for n in params:
                if n[0]=="@":
                    if n=="@column":
                        model_column_set = set(params[n].split(","))
                elif hasattr(model,n):
                    q = q.filter(getattr(model.c,n)==params[n])
                else:
                    return json({"code":400,"msg":"'%s' have no attribute '%s'"%(modelname,n)})
        o = q.one()
        if o:
            o = o.to_dict()
            secret_fields = model_setting.get("secret_fields")
            if secret_fields:
                for k in secret_fields:
                    del o[k]
            if model_column_set:
                keys = list(o.keys())
                for k in keys:
                    if k not in model_column_set:
                        del o[k]
        self.rdict[key] = o
Пример #24
0
    def _put_one(self,key,tag):
        modelname = key
        params = self.request_data[key]
        params_role = params.get("@role")

        try:
            model = getattr(models,modelname)
            model_setting = settings.APIJSON_MODELS.get(modelname,{})
            user_id_field = model_setting.get("user_id_field")
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
            return json({"code":400,"msg":"model '%s' not found"%(modelname)})
        
        APIJSON_REQUESTS = settings.APIJSON_REQUESTS or {}
        request_tag = APIJSON_REQUESTS.get(tag,{})
        _model_name = request_tag.get("@model_name") or tag
        request_tag_config = request_tag.get(_model_name,{})
        if not request_tag_config:
            return json({"code":400,"msg":"tag '%s' not found"%(tag)})
        tag_PUT = request_tag_config.get("PUT",{})
        ADD = tag_PUT.get("ADD")
        if ADD:
            ADD_role = ADD.get("@role")
            if ADD_role and not params_role:
                params_role = ADD_role

        try:
            id_ = params.get("id")
            if not id_:
                return json({"code":400,"msg":"id param needed"})
            id_ = int(id_)
        except ValueError as e:
            return json({"code":400,"msg":"id '%s' cannot convert to integer"%(params.get("id"))})
        obj = model.get(id_)
        if not obj:
            return json({"code":400,"msg":"cannot find record id '%s'"%(id_)})

        permission_check_ok = False
        PUT = model_setting.get("PUT")
        if PUT:
            roles = PUT.get("roles")
            if params_role:
                if not params_role in roles:
                    return json({"code":400,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
                roles = [params_role]
            if roles:
                for role in roles:
                    if role == "OWNER":
                        if request.user:
                            if user_id_field:
                                if obj.to_dict().get(user_id_field)==request.user.id:
                                    permission_check_ok = True
                                    break
                        else:
                            return json({"code":400,"msg":"need login user"})
                    elif role == "UNKNOWN":
                        permission_check_ok = True
                        break
                    else:
                        if functions.has_role(request.user,role):
                            permission_check_ok = True
                            break

        if not permission_check_ok:
            return json({"code":400,"msg":"no permission"})
        
        kwargs = {}
        for k in params:
            if k=="id":
                continue
            elif hasattr(obj,k):
                kwargs[k] = params[k]
            else:
                return json({"code":400,"msg":"'%s' don't have field '%s'"%(modelname,k)})
        obj.update(**kwargs)
        ret = obj.save()
        obj_dict = {"id":id_}
        if ret:
            obj_dict["code"] = 200
            obj_dict["msg"] = "success"
            obj_dict["count"] = 1
        else:
            obj_dict["code"] = 400
            obj_dict["msg"] = "failed when updating, maybe no change"
            obj_dict["count"] = 0
            self.rdict["code"] = 400
            self.rdict["msg"] = "failed when updating, maybe no change"
        self.rdict[key] = obj_dict
Пример #25
0
    def _post_one(self,key,tag):
        modelname = key
        params = self.request_data[key]
        params_role = params.get("@role")

        try:
            model = getattr(models,modelname)
            model_setting = settings.APIJSON_MODELS.get(modelname,{})
            user_id_field = model_setting.get("user_id_field")
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
            return json({"code":400,"msg":"model '%s' not found"%(modelname)})

        request_tag = settings.APIJSON_REQUESTS.get(tag,{})
        _model_name = request_tag.get("@model_name") or tag
        request_tag_config = request_tag.get(_model_name,{})
        if not request_tag_config:
            return json({"code":400,"msg":"tag '%s' not found"%(tag)})
        tag_POST =  request_tag_config.get("POST",{})
        ADD = tag_POST.get("ADD")
        if ADD:
            ADD_role = ADD.get("@role")
            if ADD_role and not params_role:
                params_role = ADD_role

        permission_check_ok = False
        POST = model_setting.get("POST")
        if POST:
            roles = POST.get("roles")
            if params_role:
                if not params_role in roles:
                    return json({"code":400,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
                roles = [params_role]

            if roles:
                for role in roles:
                    if role == "OWNER":
                        if request.user:
                            permission_check_ok = True
                            if user_id_field:
                                params[user_id_field] = request.user.id
                            else:
                                #need OWNER, but don't know how to set user id
                                return json({"code":400,"msg":"no permission"})
                            break
                    elif role == "UNKNOWN":
                        permission_check_ok = True
                        break
                    else:
                        if functions.has_role(request.user,role):
                            permission_check_ok = True
                            break
        if not permission_check_ok:
            return json({"code":400,"msg":"no permission"})

        DISALLOW = POST.get("DISALLOW")
        if DISALLOW:
            for field in DISALLOW:
                if field in params:
                    log.error("request '%s' disallow '%s'"%(tag,field))
                    return json({"code":400,"msg":"request '%s' disallow '%s'"%(tag,field)})

        NECESSARY = POST.get("NECESSARY")
        if NECESSARY:
            for field in NECESSARY:
                if field not in params:
                    log.error("request '%s' don't have necessary field '%s'"%(tag,field))
                    return json({"code":400,"msg":"request '%s' don't have necessary field '%s'"%(tag,field)})

        obj = model(**params)
        ret = obj.save()
        obj_dict = obj.to_dict(convert=False)
        secret_fields = model_setting.get("secret_fields")
        if secret_fields:
            for k in secret_fields:
                del obj_dict[k]

        if ret:
            obj_dict["code"] = 200
            obj_dict["message"] = "success"
        else:
            obj_dict["code"] = 400
            obj_dict["message"] = "fail"
            self.rdict["code"] = 400
            self.rdict["message"] = "fail"

        self.rdict[key] = obj_dict
Пример #26
0
    def _get_array(self,key):
        params = self.request_data[key]
        modelname = None
        model_param = None
        model_column_set = None

        query_count = params.get("@count")
        if query_count:
            try:
                query_count = int(query_count)
            except ValueError as e:
                log.error("bad param in '%s': '%s'"%(n,params))
                return json({"code":400,"msg":"@count should be an int, now '%s'"%(params[n])})

        query_page = 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'"%(n,params))
                return json({"code":400,"msg":"@page should be an int, now '%s'"%(params[n])})
            if query_page<0:
                return json({"code":400,"msg":"page should >0, now is '%s'"%(query_page)})

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

        for n in params:
            if n[0]!="@":
                # TODO: support join in the future, now only support 1 model
                modelname = n
                break

        if not modelname:
            return json({"code":400,"msg":"no model found in array query"})

        #model settings
        model_setting = settings.APIJSON_MODELS.get(modelname,{})
        secret_fields = model_setting.get("secret_fields")
        
        #model params
        #column
        model_param = params[n]
        model_column = model_param.get("@column")
        if model_column:
            model_column_set = set(model_column.split(","))
        try:
            model = getattr(models,modelname)
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
            return json({"code":400,"msg":"model '%s' not found"%(modelname)})
        #order
        model_order = model_param.get("@order")

        q = model.all()

        GET = model_setting.get("GET")
        if not GET:
            return json({"code":400,"msg":"'%s' not accessible by apijson"%(modelname)})

        roles = GET.get("roles")
        params_role = model_param.get("@role")
        permission_check_ok = False
        if not params_role:
            if request.user:
                params_role = "LOGIN"
            else:
                params_role = "UNKNOWN"
        if params_role not in roles:
            return json({"code":400,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
        if params_role == "UNKNOWN":
            permission_check_ok = True
        elif functions.has_role(request.user,params_role):
            permission_check_ok = True
        else:
            return json({"code":400,"msg":"user doesn't have role '%s'"%(params_role)})

        if not permission_check_ok:
            return json({"code":400,"msg":"no permission"})

        if params_role == "OWNER":
            owner_filtered,q = self._filter_owner(model,model_setting,q)
            if not owner_filtered:
                return  json({"code":400,"msg":"'%s' cannot filter with owner"%(modelname)})

        for n in model_param:
            if n[0]!="@":
                if n[-1]=="$":
                    name = n[:-1]
                    if hasattr(model,name):
                        q = q.filter(getattr(model.c,name).like(model_param[n]))
                elif n[-1]=="}" and n[-2]=="{":
                    name = n[:-2]
                    if hasattr(model,name):
                        # TODO
                        pass
                elif hasattr(model,n):
                    q = q.filter(getattr(model.c,n)==model_param[n])

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

        if query_type in [0,2]:
            if query_count:
                if query_page:
                    q = q.offset(query_page*query_count)
                q = q.limit(query_count)
            if model_order:
                for k in model_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"
                    column = getattr(model.c,sort_key)
                    q = q.order_by(getattr(column,sort_order)())

            def _get_info(i):
                d = i.to_dict()
                if secret_fields:
                    for k in secret_fields:
                        del d[k]
                if model_column_set:
                    keys = list(d.keys())
                    for k in keys:
                        if k not in model_column_set:
                            del d[k]
                return d
            l = [_get_info(i) for i in q]
            self.rdict[key] = l
Пример #27
0
 def _can_edit_tutorial(self, obj):
     from uliweb import request
     
     return (obj.authors.has(request.user) or 
         functions.has_role(request.user, 'superuser'))
Пример #28
0
    def _get_array(self, key):
        params = self.request_data[key]
        query_count = None
        query_page = None
        modelname = None
        model_param = None
        model_column_set = None
        for n in params:
            if n[0] == "@":
                if not query_count and n == "@count":
                    try:
                        query_count = int(params[n])
                    except ValueError as e:
                        log.error("bad param in '%s': '%s'" % (n, params))
                        return json({
                            "code":
                            400,
                            "msg":
                            "@count should be an int, now '%s'" % (params[n])
                        })
                    if query_count <= 0:
                        return json({
                            "code":
                            400,
                            "msg":
                            "count should >0, now is '%s' " % (query_count)
                        })
                elif not query_page and n == "@page":
                    #@page begin from 0
                    try:
                        query_page = int(params[n])
                    except ValueError as e:
                        log.error("bad param in '%s': '%s'" % (n, params))
                        return json({
                            "code":
                            400,
                            "msg":
                            "@page should be an int, now '%s'" % (params[n])
                        })
                    if query_page < 0:
                        return json({
                            "code":
                            400,
                            "msg":
                            "page should >0, now is '%s' " % (query_page)
                        })

            # TODO: support join in the future, now only support 1 model
            elif not modelname:
                modelname = n

        if not modelname:
            return json({"code": 400, "msg": "no model found in array query"})

        #model settings
        model_setting = settings.APIJSON_MODELS.get(modelname, {})
        secret_fields = model_setting.get("secret_fields")

        #model params
        #column
        model_param = params[n]
        model_column = model_param.get("@column")
        if model_column:
            model_column_set = set(model_column.split(","))
        try:
            model = getattr(models, modelname)
        except ModelNotFound as e:
            log.error("try to find model '%s' but not found: '%s'" %
                      (modelname, e))
            return json({
                "code": 400,
                "msg": "model '%s' not found" % (modelname)
            })
        #order
        model_order = model_param.get("@order")

        q = model.all()

        #rbac check begin
        GET = model_setting.get("GET", {})
        if not GET:
            return json({
                "code": 401,
                "msg": "'%s' not accessible by apijson" % (modelname)
            })

        roles = GET.get("roles")
        perms = GET.get("perms")
        params_role = params.get("@role")
        permission_check_ok = False
        user_role = None
        if params_role:
            if params_role not in roles:
                return json({
                    "code":
                    401,
                    "msg":
                    "'%s' not accessible by role '%s'" %
                    (modelname, params_role)
                })
            if functions.has_role(request.user, params_role):
                permission_check_ok = True
                user_role = params_role
            else:
                return json({
                    "code":
                    401,
                    "msg":
                    "user doesn't have role '%s'" % (params_role)
                })
        if not permission_check_ok and roles:
            for role in roles:
                if functions.has_role(request.user, role):
                    permission_check_ok = True
                    user_role = role
                    break

        if not permission_check_ok and perms:
            for perm in perms:
                if functions.has_permission(request.user, perm):
                    permission_check_ok = True
                    break

        if not permission_check_ok:
            return json({"code": 401, "msg": "no permission"})
        #rbac check end

        if user_role == "OWNER":
            owner_filtered, q = self._filter_owner(model, model_setting, q)
            if not owner_filtered:
                return json({
                    "code":
                    401,
                    "msg":
                    "'%s' cannot filter with owner" % (modelname)
                })

        if query_count:
            if query_page:
                q = q.offset(query_page * query_count)
            q = q.limit(query_count)
        if model_order:
            for k in model_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"
                column = getattr(model.c, sort_key)
                q = q.order_by(getattr(column, sort_order)())

        def _get_info(i):
            d = i.to_dict()
            if secret_fields:
                for k in secret_fields:
                    del d[k]
            if model_column_set:
                keys = list(d.keys())
                for k in keys:
                    if k not in model_column_set:
                        del d[k]
            return d

        l = [_get_info(i) for i in q]
        self.rdict[key] = l
Пример #29
0
    def __begin__(self):
        functions.require_login()

        if not functions.has_role(request.user, 'superuser'):
            error("你没有权限访问此页面")