@@ -406,27 +406,52 @@ namespace db0::python
406406 }
407407
408408 template <typename MemoImplT>
409- PyObject *checkProtectedFieldReadAccess (MemoImplT *memo_obj, const db0::object_model::MemberLoc &member_loc)
409+ bool checkProtectedFieldAccess (MemoImplT *memo_obj, db0::object_model::FieldMaskOptions access_option,
410+ const db0::object_model::MemberLoc &member_loc, const char *field_name = nullptr )
410411 {
412+ auto &memo_type = memo_obj->ext ().getType ();
413+ if (!memo_type.isProtectFields ()) {
414+ return true ;
415+ }
416+
411417 const db0::object_model::Class *type = nullptr ;
412418 std::shared_ptr<DataMaskingState> masking_state;
413419 long long account_id = 0 ;
414420 if (!getProtectedFieldAccessContext (memo_obj, type, masking_state, account_id)) {
415- return nullptr ;
421+ return ! PyErr_Occurred () ;
416422 }
417423
418- bool canRead = false ;
419- if (account_id == -1 || account_id == -2 ) {
420- canRead = masking_state->mode == DataMaskingMode::DEBUG ;
421- } else if (account_id >= 0 ) {
422- auto mask = type->tryGetFieldAccess (static_cast <std::uint64_t >(account_id), member_loc);
423- canRead = mask && (*mask)[db0::object_model::FieldMaskOptions::READ ];
424+ if (masking_state->mode == DataMaskingMode::DEBUG ) {
425+ if (account_id == -2 ) {
426+ return true ;
427+ }
428+ if (account_id == -1 ) {
429+ return access_option == db0::object_model::FieldMaskOptions::READ ;
430+ }
424431 }
425432
426- if (canRead) {
433+ if (account_id < 0 ) {
434+ return false ;
435+ }
436+
437+ auto mask = type->tryGetFieldAccess (static_cast <std::uint64_t >(account_id), member_loc);
438+ if (!mask && field_name) {
439+ mask = type->tryGetFieldAccess (static_cast <std::uint64_t >(account_id), field_name);
440+ }
441+ return mask && (*mask)[access_option];
442+ }
443+
444+ template <typename MemoImplT>
445+ PyObject *checkProtectedFieldReadAccess (MemoImplT *memo_obj, const db0::object_model::MemberLoc &member_loc)
446+ {
447+ if (checkProtectedFieldAccess (memo_obj, db0::object_model::FieldMaskOptions::READ , member_loc)) {
448+ return nullptr ;
449+ }
450+ if (PyErr_Occurred ()) {
427451 return nullptr ;
428452 }
429453
454+ auto masking_state = memo_obj->ext ().getFixture ()->getMaskingState ();
430455 if (masking_state->hasMissingValuePlaceholder ) {
431456 Py_INCREF (masking_state->missingValuePlaceholder );
432457 return masking_state->missingValuePlaceholder ;
@@ -444,28 +469,15 @@ namespace db0::python
444469 return true ;
445470 }
446471
447- const db0::object_model::Class *type = nullptr ;
448- std::shared_ptr<DataMaskingState> masking_state;
449- long long account_id = 0 ;
450- if (!getProtectedFieldAccessContext (memo_obj, type, masking_state, account_id)) {
451- return !PyErr_Occurred ();
452- }
453-
454- bool canCreate = false ;
455- if (account_id == -2 ) {
456- canCreate = masking_state->mode == DataMaskingMode::DEBUG ;
457- } else if (account_id >= 0 ) {
458- auto member_loc = type->findField (field_name);
459- auto mask = type->tryGetFieldAccess (static_cast <std::uint64_t >(account_id), member_loc);
460- if (!mask) {
461- mask = type->tryGetFieldAccess (static_cast <std::uint64_t >(account_id), field_name);
462- }
463- canCreate = mask && (*mask)[db0::object_model::FieldMaskOptions::CREATE ];
464- }
465-
466- if (canCreate) {
472+ auto member_loc = memo_type.findField (field_name);
473+ if (checkProtectedFieldAccess (
474+ memo_obj, db0::object_model::FieldMaskOptions::CREATE , member_loc, field_name
475+ )) {
467476 return true ;
468477 }
478+ if (PyErr_Occurred ()) {
479+ return false ;
480+ }
469481
470482 PyErr_SetString (PyExc_PermissionError, " data masking denies create access to protected field" );
471483 return false ;
0 commit comments