361 if entity.has_eid(): |
361 if entity.has_eid(): |
362 eid = entity.eid |
362 eid = entity.eid |
363 else: |
363 else: |
364 eid = None |
364 eid = None |
365 strict = False |
365 strict = False |
|
366 if permission == 'update': |
|
367 assert section in ('attributes', 'metadata', 'hidden') |
|
368 relpermission = 'add' |
|
369 else: |
|
370 assert section not in ('attributes', 'metadata', 'hidden') |
|
371 relpermission = permission |
366 cw = entity._cw |
372 cw = entity._cw |
367 for rschema, targetschemas, role in eschema.relation_definitions(True): |
373 for rschema, targetschemas, role in eschema.relation_definitions(True): |
368 # check category first, potentially lower cost than checking |
|
369 # permission which may imply rql queries |
|
370 _targetschemas = [] |
374 _targetschemas = [] |
371 for tschema in targetschemas: |
375 for tschema in targetschemas: |
|
376 # check section's tag first, potentially lower cost than |
|
377 # checking permission which may imply rql queries |
372 if not tag in self.etype_get(eschema, rschema, role, tschema): |
378 if not tag in self.etype_get(eschema, rschema, role, tschema): |
373 continue |
379 continue |
374 rdef = rschema.role_rdef(eschema, tschema, role) |
380 rdef = rschema.role_rdef(eschema, tschema, role) |
375 if permission is not None and \ |
381 if rschema.final: |
376 not ((not strict and rdef.has_local_role(permission)) or |
382 if not rdef.has_perm(cw, permission, eid=eid): |
377 rdef.has_perm(cw, permission, fromeid=eid)): |
383 continue |
378 continue |
384 elif strict or not rdef.has_local_role(relpermission): |
|
385 if role == 'subject': |
|
386 if not rdef.has_perm(cw, relpermission, fromeid=eid): |
|
387 continue |
|
388 elif role == 'object': |
|
389 if not rdef.has_perm(cw, relpermission, toeid=eid): |
|
390 continue |
379 _targetschemas.append(tschema) |
391 _targetschemas.append(tschema) |
380 if not _targetschemas: |
392 if not _targetschemas: |
381 continue |
393 continue |
382 targetschemas = _targetschemas |
394 targetschemas = _targetschemas |
383 if permission is not None: |
395 rdef = eschema.rdef(rschema, role=role, targettype=targetschemas[0]) |
384 rdef = eschema.rdef(rschema, role=role, targettype=targetschemas[0]) |
396 # XXX tag allowing to hijack the permission machinery when |
385 # tag allowing to hijack the permission machinery when |
397 # permission is not verifiable until the entity is actually |
386 # permission is not verifiable until the entity is actually |
398 # created... |
387 # created... |
399 if eid is None and '%s_on_new' % permission in permsoverrides.etype_get(eschema, rschema, role): |
388 if eid is None and '%s_on_new' % permission in permsoverrides.etype_get(eschema, rschema, role): |
400 yield (rschema, targetschemas, role) |
389 yield (rschema, targetschemas, role) |
401 continue |
|
402 if not rschema.final and role == 'subject': |
|
403 # on relation with cardinality 1 or ?, we need delete perm as well |
|
404 # if the relation is already set |
|
405 if (relpermission == 'add' |
|
406 and rdef.role_cardinality(role) in '1?' |
|
407 and eid and entity.related(rschema.type, role) |
|
408 and not rdef.has_perm(cw, 'delete', fromeid=eid, |
|
409 toeid=entity.related(rschema.type, role)[0][0])): |
390 continue |
410 continue |
391 if rschema.final: |
411 elif role == 'object': |
392 if not rdef.has_perm(cw, permission, fromeid=eid): |
412 # on relation with cardinality 1 or ?, we need delete perm as well |
393 continue |
413 # if the relation is already set |
394 elif role == 'subject': |
414 if (relpermission == 'add' |
395 # on relation with cardinality 1 or ?, we need delete perm as well |
415 and rdef.role_cardinality(role) in '1?' |
396 # if the relation is already set |
416 and eid and entity.related(rschema.type, role) |
397 if (permission == 'add' |
417 and not rdef.has_perm(cw, 'delete', toeid=eid, |
398 and rdef.role_cardinality(role) in '1?' |
418 fromeid=entity.related(rschema.type, role)[0][0])): |
399 and eid and entity.related(rschema.type, role) |
419 continue |
400 and not rdef.has_perm(cw, 'delete', fromeid=eid, |
|
401 toeid=entity.related(rschema.type, role)[0][0])): |
|
402 continue |
|
403 elif role == 'object': |
|
404 # on relation with cardinality 1 or ?, we need delete perm as well |
|
405 # if the relation is already set |
|
406 if (permission == 'add' |
|
407 and rdef.role_cardinality(role) in '1?' |
|
408 and eid and entity.related(rschema.type, role) |
|
409 and not rdef.has_perm(cw, 'delete', toeid=eid, |
|
410 fromeid=entity.related(rschema.type, role)[0][0])): |
|
411 continue |
|
412 yield (rschema, targetschemas, role) |
420 yield (rschema, targetschemas, role) |
413 |
421 |
414 autoform_section = AutoformSectionRelationTags('autoform_section') |
422 autoform_section = AutoformSectionRelationTags('autoform_section') |
415 |
423 |
416 # relations'field class |
424 # relations'field class |