Skip to content

Commit 3f75150

Browse files
committed
refractor apijson models settings, add apijson style roles
1 parent 7b7ff6a commit 3f75150

File tree

5 files changed

+73
-32
lines changed

5 files changed

+73
-32
lines changed

demo/apps/apijson_demo/dbinit.py

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
Moment = models.moment
1111

1212
user_list = [
13+
{
14+
"username": "admin",
15+
"nickname": "Administrator",
16+
"email": "admin@localhost",
17+
},
1318
{
1419
"username": "usera",
1520
"nickname": "User A",
@@ -101,7 +106,10 @@
101106
print("create user '%s'"%(d["username"]))
102107
u = User(**d)
103108
u.set_password("123")
109+
if d["username"]=="admin":
110+
u.is_superuser = True
104111
u.save()
112+
105113
for d in privacy_list:
106114
user = User.get(User.c.username==d["username"])
107115
if user:

demo/apps/apijson_demo/views.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
@expose('/')
66
def index():
77
if request.user:
8-
user_info = "login as user '%s'"%(request.user)
8+
user_info = "login as user '%s(%s)'"%(request.user.username,request.user)
99
else:
10-
user_info = "not login, you can login with username 'usera/userb/userc', and password '123'"
10+
user_info = "not login, you can login with username 'admin/usera/userb/userc', and password '123'"
1111
request_get = [
1212
{
1313
"label":"Single record query: with id as parameter",
@@ -33,7 +33,7 @@ def index():
3333
}''',
3434
},
3535
{
36-
"label":"Array query",
36+
"label":"Array query: private data",
3737
"value":'''{
3838
"[]":{
3939
"@count":2,

demo/apps/settings.ini

+4-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ INSTALLED_APPS = [
1313
'uliweb.contrib.auth',
1414
'uliweb.contrib.i18n',
1515
'uliweb.contrib.flashmessage',
16+
'uliweb.contrib.rbac',
1617
'uliweb_apps.site',
1718
'uliweb_apps.login',
1819
'uliweb_comui',
@@ -27,14 +28,9 @@ MAINMENU = {
2728
]
2829
}
2930

30-
[APIJSON_MODEL]
31-
#overwrite user table to public for test
32-
user = {
33-
"user_id_field" : "id",
34-
"secret_fields" : ["password"],
35-
"default_filter_by_self" : True
36-
}
37-
3831
[LAYOUT]
3932
logo_lg = "Uliweb"
4033
logo_mini = "U"
34+
35+
[SESSION]
36+
timeout = 36000

uliweb_apijson/apijson/settings.ini

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
[APIJSON_MODEL_CONFIG]
1+
#apijson style role names
2+
[ROLES]
3+
ADMIN = _('APIJSON ADMIN'), 'uliweb.contrib.rbac.superuser', True
4+
UNKNOWN = _('APIJSON UNKNOWN'), 'uliweb.contrib.rbac.anonymous', True
5+
LOGIN = _('APIJSON LOGIN'), 'uliweb.contrib.rbac.trusted', True
6+
#will do more when query in the database
7+
OWNER = _('APIJSON OWNER'), 'uliweb.contrib.rbac.trusted', True
8+
9+
[APIJSON_MODELS]
210
user = {
3-
"public" : False,
411
"user_id_field" : "id",
512
"secret_fields" : ["password"],
6-
"default_filter_by_self" : True
13+
"rbac_get" : {
14+
"roles" : ["ADMIN","OWNER"]
15+
}
716
}

uliweb_apijson/apijson/views.py

+46-18
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,64 @@ def get(self):
2525
if key[-2:]=="[]":
2626
rsp = self._query_array(key)
2727
else:
28-
rsp = self._query_one(key)
28+
rsp = self._get_one(key)
2929
if rsp: return rsp
3030

3131
return json(self.rdict)
3232

33-
def _query_one(self,key):
33+
def _get_one(self,key):
3434
modelname = key
35+
params = self.request_data[key]
36+
3537
try:
3638
model = getattr(models,modelname)
37-
model_setting = settings.APIJSON_MODEL.get(modelname,{})
39+
model_setting = settings.APIJSON_MODELS.get(modelname,{})
3840
except ModelNotFound as e:
3941
log.error("try to find model '%s' but not found: '%s'"%(modelname,e))
4042
return json({"code":400,"msg":"model '%s' not found"%(modelname)})
4143
model_column_set = None
4244
q = model.all()
43-
public = model_setting.get("public",False)
45+
rbac_get = model_setting.get("rbac_get",{})
46+
if not rbac_get:
47+
return json({"code":401,"msg":"'%s' not accessible by apijson"%(modelname)})
48+
49+
roles = rbac_get.get("roles")
50+
perms = rbac_get.get("perms")
51+
params_role = params.get("@role")
52+
permission_check_ok = False
53+
user_role = None
54+
if params_role:
55+
if params_role not in roles:
56+
return json({"code":401,"msg":"'%s' not accessible by role '%s'"%(modelname,params_role)})
57+
if functions.has_role(request.user,params_role):
58+
permission_check_ok = True
59+
user_role = params_role
60+
else:
61+
return json({"code":401,"msg":"user doesn't have role '%s'"%(params_role)})
62+
if not permission_check_ok and roles:
63+
for role in roles:
64+
if functions.has_role(request.user,role):
65+
permission_check_ok = True
66+
user_role = role
67+
break
68+
69+
if not permission_check_ok and perms:
70+
for perm in perms:
71+
if functions.has_permission(request.user,perm):
72+
permission_check_ok = True
73+
break
74+
75+
if not permission_check_ok:
76+
return json({"code":401,"msg":"no permission"})
77+
4478
filtered = False
45-
if not public:
46-
if not request.user:
47-
return json({"code":401,"msg":"'%s' not accessable for unauthorized request"%(modelname)})
79+
80+
if user_role == "OWNER":
4881
owner_filtered,q = self._filter_owner(model,model_setting,q)
49-
if owner_filtered:
50-
filtered = True
51-
else:
52-
return json({"code":401,"msg":"'%s' not accessable because not public"%(modelname)})
82+
if not owner_filtered:
83+
return json({"code":401,"msg":"'%s' cannot filter with owner"%(modelname)})
84+
filtered = True
85+
5386
params = self.request_data[key]
5487
if isinstance(params,dict):
5588
for n in params:
@@ -61,14 +94,9 @@ def _query_one(self,key):
6194
filtered = True
6295
else:
6396
return json({"code":400,"msg":"'%s' have no attribute '%s'"%(modelname,n)})
64-
#default filter
97+
#default filter is trying to filter with owner
6598
if not filtered and request.user:
66-
default_filter_by_self = model_setting.get("default_filter_by_self",False)
67-
if default_filter_by_self:
68-
user_id_field = model_setting.get("user_id_field")
69-
if user_id_field:
70-
q = q.filter(getattr(model.c,user_id_field)==request.user.id)
71-
filtered = True
99+
owner_filtered,q = self._filter_owner(model,model_setting,q)
72100
o = q.one()
73101
if o:
74102
o = o.to_dict()

0 commit comments

Comments
 (0)