Skip to content

Instantly share code, notes, and snippets.

@atskimura
Created February 27, 2020 03:11
Show Gist options
  • Save atskimura/479d441ebb937e22739a24424787964b to your computer and use it in GitHub Desktop.
Save atskimura/479d441ebb937e22739a24424787964b to your computer and use it in GitHub Desktop.
public class SecureDML {
public class SecureDMLException extends Exception {}
/**
* CRUD/FLSチェックを行うinsert
*/
public static sObject[] secureInsert(sObject[] records) {
return secureDML(records, AccessType.CREATABLE);
}
/**
* CRUD/FLSチェックを行うinsert
*/
public static sObject[] secureInsert(sObject record) {
if (record == null) return null;
return secureDML(new sObject[] {record}, AccessType.CREATABLE);
}
/**
* CRUD/FLSチェックを行うupdate
*/
public static sObject[] secureUpdate(sObject[] records) {
return secureDML(records, AccessType.UPDATABLE);
}
/**
* CRUD/FLSチェックを行うupdate
*/
public static sObject[] secureUpdate(sObject record) {
if (record == null) return null;
return secureDML(new sObject[] {record}, AccessType.UPDATABLE);
}
/**
* CRUD/FLSチェックを行うupsert
*/
public static sObject[] secureUpsert(sObject[] records) {
return secureDML(records, AccessType.UPSERTABLE);
}
/**
* CRUD/FLSチェックを行うupsert
*/
public static sObject[] secureUpsert(sObject record) {
if (record == null) return null;
return secureDML(new sObject[] {record}, AccessType.UPSERTABLE);
}
/**
* CRUDチェックを行うdelete
*/
public static void secureDelete(sObject[] records) {
if (records == null || records.isEmpty()) return;
if (!records[0].getSObjectType().getDescribe().isDeletable()) {
throw new SecureDMLException('オブジェクトのアクセス権限がありません。');
}
delete records;
}
/**
* CRUDチェックを行うdelete
*/
public static void secureDelete(sObject record) {
if (record == null) return;
secureDelete(new sObject[] {record});
}
/**
* CRUD/FLSチェックを行うinsert/update/upsert
* アクセス権がない場合にInvalidAccessExceptionを投げる。
*/
private static sObject[] secureDML(sObject[] records, AccessType accessType) {
if (records == null || records.isEmpty()) {
return records;
}
SObjectAccessDecision decision;
try {
decision = Security.stripInaccessible(
accessType,
records
);
} catch(NoAccessException e) {
// オブジェクトにアクセス権限がない場合の処理
String objName = records[0].getSObjectType().getDescribe().getName();
throw new SecureDMLException('オブジェクトのアクセス権限がありません。:' + objName, e);
}
Map<String, Set<String>> removedFields = decision.getRemovedFields();
if (!removedFields.keySet().isEmpty()) {
String[] removedFieldNames = new String[] {};
for (String objName : removedFields.keySet()) {
for (String fieldName : removedFields.get(objName)) {
removedFieldNames.add(objName + '.' + fieldName);
}
}
// アクセス権限がない項目が一つでもある場合の処理
throw new SecureDMLException('アクセス権限がない項目があります。:' + String.join(removedFieldNames, ','));
}
// アクセス可能な項目のみのレコードを取得
sObject[] stripedRecords = decision.getRecords();
switch on accessType {
when CREATABLE {
insert stripedRecords;
}
when UPDATABLE {
update stripedRecords;
}
when UPSERTABLE {
upsert stripedRecords;
}
}
return stripedRecords;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment