diff --git a/demo/apps/apijson_demo/settings.ini b/demo/apps/apijson_demo/settings.ini index fdf8f1a..78e636f 100644 --- a/demo/apps/apijson_demo/settings.ini +++ b/demo/apps/apijson_demo/settings.ini @@ -6,36 +6,39 @@ moment = 'apijson_demo.models.Moment' [APIJSON_MODELS] moment = { "user_id_field" : "user_id", - "rbac_get" : { + "GET" : { "roles" : ["OWNER"] }, - "rbac_post" : { - "roles" : ["OWNER"] - } + } comment = { "user_id_field" : "user_id", - "rbac_get" : { + "GET" : { "roles" : ["OWNER"] }, - "rbac_post" : { - "roles" : ["OWNER"] - } } [APIJSON_REQUESTS] moment = { - "moment": { - "ADD" :{"@role": ["OWNER"]}, - "DISALLOW" : ["id"], - "NECESSARY" : ["content"] - } + "moment": { + "POST" :{ + "ADD":{"roles": ["OWNER"]}, + "DISALLOW" : ["id"], + "NECESSARY" : ["content"], + }, + "PUT" :{ + "ADD":{"roles": ["OWNER"]}, + "NECESSARY" : ["content"], + }, + } } comment = { - "comment": { - "ADD" :{"@role": ["OWNER"]}, - "DISALLOW" : ["id"], - "NECESSARY" : ["content"] + "comment": { + "POST" :{ + "ADD" :{"roles": ["OWNER"]}, + "DISALLOW" : ["id"], + "NECESSARY" : ["content"] + } } } diff --git a/demo/apps/apijson_demo/templates/index.html b/demo/apps/apijson_demo/templates/index.html index bc5a16e..9452c28 100644 --- a/demo/apps/apijson_demo/templates/index.html +++ b/demo/apps/apijson_demo/templates/index.html @@ -45,6 +45,19 @@ + + PUT URL + + + + apijson put request examples + + + { item.label } + + + + request data @@ -62,13 +75,15 @@ data: { request_get : {{=request_get_json}}, request_post : {{=request_post_json}}, + request_put : {{=request_put_json}}, request_data : "", can_post : true, response_data : "", tab_current : "tab_get", tab2url : { "tab_get":"{{=url_for('uliweb_apijson.apijson.views.ApiJson.get')}}", - "tab_post":"{{=url_for('uliweb_apijson.apijson.views.ApiJson.post')}}" + "tab_post":"{{=url_for('uliweb_apijson.apijson.views.ApiJson.post')}}", + "tab_put":"{{=url_for('uliweb_apijson.apijson.views.ApiJson.put')}}" } }, methods: { @@ -102,6 +117,9 @@ else if (n=="tab_post") { vm.request_data = vm.request_post[0].value } + else if (n=="tab_put") { + vm.request_data = vm.request_put[0].value + } vm.response_data = "" } } diff --git a/demo/apps/apijson_demo/views.py b/demo/apps/apijson_demo/views.py index 6c9ca5c..88fe8ba 100644 --- a/demo/apps/apijson_demo/views.py +++ b/demo/apps/apijson_demo/views.py @@ -84,8 +84,22 @@ def index(): }, ] + request_put = [ + { + "label":"Modify moment", + "value":'''{ + "moment": { + "id": 1, + "content": "modify moment content" + }, + "tag": "moment" +}''', + }, + ] + return { "user_info":user_info, "request_get_json":dumps(request_get), "request_post_json":dumps(request_post), + "request_put_json":dumps(request_put), } diff --git a/uliweb_apijson/apijson/settings.ini b/uliweb_apijson/apijson/settings.ini index 8cf9018..7b7668b 100644 --- a/uliweb_apijson/apijson/settings.ini +++ b/uliweb_apijson/apijson/settings.ini @@ -10,7 +10,7 @@ OWNER = _('APIJSON OWNER'), 'uliweb.contrib.rbac.trusted', True user = { "user_id_field" : "id", "secret_fields" : ["password"], - "rbac_get" : { + "GET" : { "roles" : ["ADMIN","OWNER"] } } diff --git a/uliweb_apijson/apijson/views.py b/uliweb_apijson/apijson/views.py index 8b27021..7cceeac 100644 --- a/uliweb_apijson/apijson/views.py +++ b/uliweb_apijson/apijson/views.py @@ -44,12 +44,12 @@ def _get_one(self,key): q = model.all() #rbac check begin - rbac_get = model_setting.get("rbac_get",{}) - if not rbac_get: + GET = model_setting.get("GET",{}) + if not GET: return json({"code":401,"msg":"'%s' not accessible by apijson"%(modelname)}) - roles = rbac_get.get("roles") - perms = rbac_get.get("perms") + roles = GET.get("roles") + perms = GET.get("perms") params_role = params.get("@role") permission_check_ok = False user_role = None @@ -169,12 +169,12 @@ def _get_array(self,key): q = model.all() #rbac check begin - rbac_get = model_setting.get("rbac_get",{}) - if not rbac_get: + GET = model_setting.get("GET",{}) + if not GET: return json({"code":401,"msg":"'%s' not accessible by apijson"%(modelname)}) - roles = rbac_get.get("roles") - perms = rbac_get.get("perms") + roles = GET.get("roles") + perms = GET.get("perms") params_role = params.get("@role") permission_check_ok = False user_role = None @@ -277,38 +277,135 @@ def _post_one(self,key,tag): 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_setting = request_setting_tag.get(modelname,{}) - ADD = request_setting.get("ADD") + request_setting_model = request_setting_tag.get(modelname,{}) + request_setting_POST = request_setting_model.get("POST",{}) + ADD = request_setting_POST.get("ADD") permission_check_ok = False if ADD: - _role = ADD.get("@role") - if _role: - for r in _role: + roles = ADD.get("roles") + if roles: + for r in roles: if r == "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"}) if not permission_check_ok: return json({"code":400,"msg":"no permission"}) - DISALLOW = request_setting.get("DISALLOW") + DISALLOW = request_setting_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 = request_setting_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 put(self): + tag = self.request_data.get("@tag") + for key in self.request_data: + if key[0]!="@": + rsp = self._put_one(key,tag) + if rsp: + return rsp + else: + #only accept one table + return json(self.rdict) + + return json(self.rdict) + + def _put_one(self,key,tag): + tag = tag or key + modelname = key + params = self.request_data[key] + + try: + model = getattr(models,modelname) + model_setting = settings.APIJSON_MODELS.get(modelname,{}) + request_setting_tag = settings.APIJSON_REQUESTS.get(tag,{}) + 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_setting_model = request_setting_tag.get(modelname,{}) + request_setting_PUT = request_setting_model.get("PUT",{}) + ADD = request_setting_PUT.get("ADD") + permission_check_ok = False + + 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 ADD: + roles = ADD.get("roles") + if roles: + for r in roles: + if r == "OWNER": + if request.user: + if user_id_field: + if getattr(obj,user_id_field)!=request.user.id: + permission_check_ok = True + else: + return json({"code":400,"msg":"need login user"}) + if not permission_check_ok: + return json({"code":400,"msg":"no permission"}) + + if not obj: + return json({"code":400,"msg":"cannot find record id '%s'"%(id_)}) + 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["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