django-restit 4.2.89__py3-none-any.whl → 4.2.91__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
account/rpc/group.py CHANGED
@@ -121,7 +121,7 @@ def rest_on_group_stats(request):
121
121
  if not group:
122
122
  return rv.restPermissionDenied(request)
123
123
  if not request.member.hasPerm(["view_all_groups", "manage_groups"]):
124
- if not request.member.hasGroupPerm(group, ["reports"]):
124
+ if not request.member.hasGroupPerm(group, ["reports", "reporting"]):
125
125
  return rv.restPermissionDenied(request)
126
126
  qset = group.getAllChildren(True, True, True).filter(is_active=True)
127
127
  out = rh.countOccurences(qset, "kind")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.2.89
3
+ Version: 4.2.91
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -42,7 +42,7 @@ account/periodic.py,sha256=-u0n-7QTJgDOkasGhBAPwHAwjpqWGA-MZLEFkVTqCGU,874
42
42
  account/rpc/__init__.py,sha256=SGF0M_-H0dKh3b1apSX29BotNWAvITYccGQVC0MIjL8,336
43
43
  account/rpc/auth.py,sha256=p62tyihWvSY2zn7eaVxKcCG9qLnnZBIkwdRH81sS5_Y,16615
44
44
  account/rpc/device.py,sha256=mB14a6qvJIBnCa9ivLhPXwEt5Gk2foyqsKBtZxC506k,3070
45
- account/rpc/group.py,sha256=Bs9O69xHXtFT-fykPXPzRtLI9C0Oj967N2hJklv3wZ4,4916
45
+ account/rpc/group.py,sha256=riymUK6ttv8G6SG6K-v7UCvM40WQy3HaGSeF_sEiaU0,4929
46
46
  account/rpc/member.py,sha256=VNRSD38mmTUCbq3cCSy3qRyquzeVEwW_8zzrtS0-vAA,1817
47
47
  account/rpc/notify.py,sha256=Q2YWejP36egeF060Hih5uX4Psv_B8NWlLLPi7iDYlIw,3344
48
48
  account/rpc/oauth.py,sha256=ISLVsR5HvKALANokaOFRvF4FTRxWtXPvVnZAYANKxpo,2864
@@ -404,9 +404,9 @@ rest/middleware/request.py,sha256=JchRNy5L-bGd-7h-KFYekGRvREe2eCkZXKOYqIkP2hI,41
404
404
  rest/middleware/session.py,sha256=zHSoQpIzRLmpqr_JvW406wzpvU3W3gDbm5JhtzLAMlE,10240
405
405
  rest/middleware/session_store.py,sha256=1nSdeXK8PyuYgGgIufqrS6j6QpIrQ7zbMNT0ol75e6U,1901
406
406
  rest/models/__init__.py,sha256=M8pvFDq-WCF-QcM58X7pMufYYe0aaQ3U0PwGe9TKbbY,130
407
- rest/models/base.py,sha256=bPcTeCX7KvhkcVMKEyLmu9eYc7ccJGkIP1n3cctJPVE,69675
407
+ rest/models/base.py,sha256=-NUKed_67o3eCZCknndQixSHU4pR-Lm2wxsb_h4rjVQ,70652
408
408
  rest/models/cacher.py,sha256=eKz8TINVhWEqKhJGMsRkKZTtBUIv5rN3NHbZwOC56Uk,578
409
- rest/models/metadata.py,sha256=65GvfFbc26_7wJz8qEAzU7fEOZWVz0ttO5j5m_gs4hk,12860
409
+ rest/models/metadata.py,sha256=1nQ7CYo9bJHoaXE_hVNaj1-Y7yqhHlf2ZlaD1IfTzic,12904
410
410
  rest/net.py,sha256=LcB2QV6VNRtsSdmiQvYZgwQUDwOPMn_VBdRiZ6OpI-I,2974
411
411
  rest/regexes.yaml,sha256=VoGb4E-P_K9f82Yzcpltgzekpt9usRtwu9PYlo46nUw,149463
412
412
  rest/requestex.py,sha256=N56056vV3zWkAP-QrYsCu7SdpPzE5kLuPoxGIuZAKt0,16127
@@ -506,7 +506,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
506
506
  ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
507
507
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
508
508
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
509
- django_restit-4.2.89.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
510
- django_restit-4.2.89.dist-info/METADATA,sha256=oUQ-GYEwBbLeQLyb9if2FDKwacmHQN7cLrFtJFsdD80,7645
511
- django_restit-4.2.89.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
512
- django_restit-4.2.89.dist-info/RECORD,,
509
+ django_restit-4.2.91.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
510
+ django_restit-4.2.91.dist-info/METADATA,sha256=Wb9wxvC6pdi9MBkBlC65WcJNqzcfB-tvS65E5rAc-1c,7645
511
+ django_restit-4.2.91.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
512
+ django_restit-4.2.91.dist-info/RECORD,,
rest/models/base.py CHANGED
@@ -19,6 +19,7 @@ from .metadata import MetaDataBase, MetaDataModel
19
19
  DB_ROUTING_MAPS = settings.get("DB_ROUTING_MAPS", {})
20
20
  TWO_DECIMAL_PLACES = Decimal(10) ** -2
21
21
  EXCEPTION_ON_LIST_PERM_DENIED = settings.get("EXCEPTION_ON_LIST_PERM_DENIED", True)
22
+ ALLOW_BATCHING = settings.get("ALLOW_BATCHING", False)
22
23
 
23
24
  GRAPH_HELPERS = objict()
24
25
  GRAPH_HELPERS.restGet = None
@@ -1177,32 +1178,47 @@ class RestModel(object):
1177
1178
  @classmethod
1178
1179
  def on_rest_batch(cls, request, action):
1179
1180
  # this method is called when rest_batch='somme action'
1181
+ if not ALLOW_BATCHING or not getattr(cls.RestMeta, "CAN_BATCH", True):
1182
+ return GRAPH_HELPERS.restStatus(request, False, error="model does not allow batch actions")
1180
1183
  cls._boundRest()
1184
+ # if not request.member.hasPerm("can_batch_update"):
1185
+ # raise re.PermissionDeniedException(f"batch updated not allowed by user")
1186
+ if action == "create":
1187
+ return cls.on_rest_batch_create(request)
1181
1188
  batch_ids = request.DATA.getlist("batch_ids", [])
1182
1189
  batch_id_field = request.DATA.get("batch_id_field", "pk")
1183
- q = {}
1184
1190
  if batch_ids:
1191
+ q = {}
1185
1192
  q["{}__in".format(batch_id_field)] = batch_ids
1186
- batch_query = request.DATA.get("batch_query", None)
1187
- if batch_query:
1188
- # we ignore ids when doing a query
1189
- q.update(batch_query)
1193
+ qset = cls.on_rest_list_query(request, cls.rw_objects().filter(**q))
1194
+ else:
1195
+ qset = cls.on_rest_list_query(request, cls.rw_objects().all())
1190
1196
  if action == "delete":
1191
1197
  can_delete = getattr(cls.RestMeta, "CAN_DELETE", False)
1192
1198
  if not can_delete:
1193
- return GRAPH_HELPERS.restStatus(request, False, error="deletion not allowed via rest for this model.")
1194
- qset = cls.rw_objects().filter(**q)
1199
+ raise re.PermissionDeniedException(f"deletion not allowed for {cls.get_class_name()}", 438)
1195
1200
  count = qset.delete()
1196
1201
  return GRAPH_HELPERS.restStatus(request, True, error="delete {} items".format(count))
1197
1202
  elif action == "update":
1198
- qset = cls.rw_objects().filter(**q)
1199
1203
  update_fields = request.DATA.get(["batch_data", "batch_update"])
1200
1204
  if not isinstance(update_fields, dict):
1201
1205
  return GRAPH_HELPERS.restStatus(request, False, error="batch_update should be key/values")
1202
- count = qset.update(**update_fields)
1206
+ if {"id", "pk", "created", "password"} & update_fields.keys():
1207
+ return GRAPH_HELPERS.restStatus(request, False, error="field/s not allowed")
1208
+ has_meta = False
1209
+ for key in update_fields:
1210
+ if key.startswith("metadata"):
1211
+ has_meta = True
1212
+ break
1213
+ if has_meta or not request.member.is_superuser:
1214
+ count = 0
1215
+ for obj in qset:
1216
+ obj.checkPermsAndSave(request, update_fields)
1217
+ count += 1
1218
+ else:
1219
+ # only super users can do this
1220
+ count = qset.update(**update_fields)
1203
1221
  return GRAPH_HELPERS.restStatus(request, True, error="updated {} items".format(count))
1204
- elif action == "create":
1205
- cls.on_rest_batch_create(request)
1206
1222
  return GRAPH_HELPERS.restStatus(request, False, error="not implemented")
1207
1223
 
1208
1224
  @classmethod
@@ -1213,6 +1229,8 @@ class RestModel(object):
1213
1229
  if isinstance(batch_data, dict):
1214
1230
  if "data" in batch_data:
1215
1231
  batch_data = batch_data["data"]
1232
+ if isinstance(batch_data, dict):
1233
+ batch_data = [batch_data]
1216
1234
  items = []
1217
1235
  for item in batch_data:
1218
1236
  obj = cls.createFromBatch(item)
@@ -1223,15 +1241,14 @@ class RestModel(object):
1223
1241
  @classmethod
1224
1242
  def createFromBatch(cls, item, request=None):
1225
1243
  obj = None
1226
- try:
1227
- rh.debug("batch item", item)
1228
- item_filter = cls.getRestBatchCreateFilter(item)
1229
- rh.debug("batch filters", item_filter)
1230
- obj = cls.ro_objects().filter(**item_filter).last()
1231
- if obj is None:
1232
- obj = cls.createFromDict(request, item)
1233
- except Exception:
1234
- rh.log_exception(item)
1244
+ item_filter = cls.getRestBatchCreateFilter(item)
1245
+ if not item_filter:
1246
+ raise Exception("requires item filter")
1247
+ rh.debug("createFromBatch", item_filter)
1248
+ obj = cls.ro_objects().filter(**item_filter).last()
1249
+ if obj is None:
1250
+ obj = cls()
1251
+ obj.checkPermsAndSave(request, item)
1235
1252
  return obj
1236
1253
 
1237
1254
  @classmethod
rest/models/metadata.py CHANGED
@@ -115,7 +115,7 @@ class MetaDataModel(object):
115
115
  if not isinstance(values, dict):
116
116
  raise Exception("invalid metadata: {}".format(values))
117
117
 
118
- for key, value in list(values.items()):
118
+ for key, value in values.items():
119
119
  cat = None
120
120
  if "." in key:
121
121
  cat, key = key.split('.')
@@ -230,15 +230,17 @@ class MetaDataModel(object):
230
230
  request = rh.getActiveRequest()
231
231
  self.__initFieldProps()
232
232
 
233
+ if "." in key:
234
+ category, key = key.split('.')
235
+
233
236
  if isinstance(value, dict):
234
- return self.setProperties(value, key)
237
+ if category is None:
238
+ return self.setProperties(value, key)
235
239
  username = "root"
236
240
  if request and request.member:
237
241
  username = request.member.username
238
242
  prop = None
239
243
 
240
- if "." in key:
241
- category, key = key.split('.')
242
244
  if category:
243
245
  # delete any keys with this category name
244
246
  full_key = "{}.{}".format(category, key)