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"
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, }
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
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
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
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
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()
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()
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
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('你不是超级用户不能进行这项操作!')
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
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, }
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"
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
def _can_edit_tutorial(self, obj): from uliweb import request return (obj.authors.has(request.user) or functions.has_role(request.user, 'superuser'))
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
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
def __begin__(self): functions.require_login() if not functions.has_role(request.user, 'superuser'): error("你没有权限访问此页面")
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
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
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
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
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
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