I've added the WITH SECURITY_ENFORCED clause to my SOQL query. The query is present at a Rest service for a callback so I am testing it by creating a public site will create a profile (External Users with Guest User license) automatically to do this, I have given the read and edit permissions to the objects. But I'm getting the System.QueryException: Insufficient permissions: secure query included inaccessible field error. My Rest Service is something like below, I've used the SObjectAccessDecision as follows but the System.debug line didn't reach to troubleshoot,
Is there anyway we can short it? I cannot able to assign a PS to the Guest user by giving access to my custom object.
@RestResource(urlMapping='/smsResponse')
global without sharing class Twilio_SMSManager {
@HttpPost
global static void postCallback() {
TwilioConfig__c twilioCustomSetting = TwilioConfig__c.getOrgDefaults();
String expectedSignature = RestContext.request.headers.get('X-Twilio-Signature');
String url = twilioCustomSetting.Status_Callback_URL__c;
Map <String, String> params = RestContext.request.params;
System.debug(LoggingLevel.INFO, '<---Return Response--->' + params);
System.debug(LoggingLevel.INFO, '<---The Host URL--->' + RestContext.request.headers.get('Host'));
System.debug(LoggingLevel.INFO, '<---The Callback URL at the Custom setting--->' + twilioCustomSetting.Status_Callback_URL__c);
//Validate signature.
if (!TwilioAPI.getDefaultClient().validateRequest(expectedSignature, url, params)) {
RestContext.response.statusCode = 403;
RestContext.response.responseBody = Blob.valueOf('Failure! Rcvd '+expectedSignature+'\nURL '+url+'\nHeaders'+RestContext.request.headers);
return;
}
RestContext.response.responseBody = Blob.valueOf('ok');
if(params.size() > 0) {
List<SMS__c> lstSMSToUpsert = new List<SMS__c>();
SMS__c smsDetails = new SMS__c();
smsDetails.Message_SID__c = params.get('MessageSid');
smsDetails.Status__c = params.get('MessageStatus');
lstSMSToUpsert.add(smsDetails);
List<Id> lstUpsertedSMSRecordIds = new List<Id>();
Schema.SObjectField messageSID = SMS__c.Fields.Message_SID__c;
Database.UpsertResult[] upsertResult = Database.upsert(lstSMSToUpsert, messageSID, false);
for (Database.UpsertResult sr : upsertResult) {
if (sr.isSuccess()) {
// Operation was successful
lstUpsertedSMSRecordIds.add(sr.getId());
}
}
System.debug(LoggingLevel.INFO, '<---lstUpsertedSMSRecordIds--->' + lstUpsertedSMSRecordIds);
if(lstUpsertedSMSRecordIds.size() > 0) {
[Options]
}
}
}
}
Option 1 - To find the fields which don't have the access
SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE,
[SELECT Id, Status__c,
Service_Appointment__r.Id, Service_Appointment__r.SA_Dispatched_SMS_Status__c FROM SMS__c WHERE Id IN :lstUpsertedSMSRecordIds limit 1]
);
System.debug('1111111 ' + securityDecision.getRecords()); => 1111111 (SMS__c:{Id=a036D000005HXUsQAO})
System.debug('2222222 ' + securityDecision.getRemovedFields().get('SMS__c')); => 2222222 null
So from the above debug there are no inaccessible fields.
Option 2 - Update the records.
SMS__c upsertSMS = [SELECT Id, Status__c, Service_Appointment__r.Id, Service_Appointment__r.SA_Dispatched_SMS_Status__c FROM SMS__c WHERE Id IN :lstUpsertedSMSRecordIds WITH SECURITY_ENFORCED limit 1];
if(upsertSMS != null && upsertSMS.Service_Appointment__r != null) {
upsertSMS.Service_Appointment__r.SA_Dispatched_SMS_Status__c = upsertSMS.Status__c;
update upsertSMS.Service_Appointment__r;
}
System.QueryException: Insufficient permissions: secure query included inaccessible field
I don't understand the behavior.
Without the WITH SECURITY_ENFORCED I can able to query and update the records.