Salesforce 開發整理(三)權限共享
Salesforce提供對象的訪問權限可以通過 安全性控制 → 共享設置,可以查看每個對象在系統內部默認的訪問權限
- 共用讀寫:對象的記錄任何用戶都可以進行讀寫操作
- 公用只讀:對象的記錄任何用戶都可以查看,但是只有記錄所有人以及具有權限的用戶可以編輯
- 專用:對應的記錄只有具有權限的用戶才可以進行讀寫操作
- 從父級控制:對象記錄訪問權限跟隨父級
以Movie__c對象為例,此時對象權限為公用讀寫,看到的記錄詳情頁面是這樣的
而在編輯頁面布局上看到“共享按鈕”是被拉出來的狀態
當我們將Movie__c的組織權限修改為專用,則記錄頁面顯示如下
通過共享按鈕可以將記錄共享給其他公用小組/用戶/角色/角色及下屬,訪問級別提供了只讀/讀寫兩種級別。用戶可以通過共享按鈕來將記錄的權限共享給其他用戶用於查看或修改。
但是很多時候,我們更希望做到的是類似於記錄能自動共享給一部分人的情況,比如記錄上有一個查找用戶字段,當記錄被創建時,權限自動共享給該用戶,該用戶被修改後也能把之前的權限給到新用戶並將權限從之前的用戶身上收回。
我們在Movie__c對象上新建一個查找(用戶)的字段,約會人Engagement__c
需求:當Movie__c記錄被創建時,將記錄讀寫權限共享給約會人
實現如下:
1 trigger MovieTrigger on Movie__c (after insert,after update) { 2 //觸發器的實現類 3 MovieTriggerHandler handler = newMovieTriggerHandler(); 4 5 //當記錄新建的時候觸發 6 if(trigger.isAfter && trigger.isInsert){ 7 Set<Id> Set_movieId = new Set<Id>(); 8 for(Movie__c movie:trigger.new){ 9 //記錄約會人!=null 且 記錄約會人!=記錄所有人 10 if(movie.Engagement__c != null && movie.Engagement__c != movie.OwnerId){11 Set_movieId.add(movie.id); 12 } 13 } 14 //判斷是否有符合條件的記錄 15 if(Set_movieId.size() > 0) handler.shareWithPerson(Set_movieId); 16 } 17 }
然後是寫觸發器的實現類
1 public class MovieTriggerHandler{ 2 3 public void shareWithPerson(Set<Id> Set_movieId){ 4 //查詢電影列表的記錄 5 List<Movie__c> list_movie = new List<Movie__c>([select id,OwnerId,Engagement__c from Movie__c where id=:Set_movieId]); 6 7 //存儲共享記錄列表 8 List<Movie__Share> list_share = new List<Movie__Share>(); 9 10 for(Movie__c ml:list_movie){ 11 Movie__Share share = new Movie__Share(); 12 share.UserOrGroupId = ml.Engagement__c;//需要共享給的用戶 or 小組 13 share.ParentId = ml.id;//記錄id 14 share.AccessLevel = ‘edit‘; //edit:讀寫/read:只讀 15 list_share.add(share); 16 } 17 //判斷是否為空 18 if(list_share.size() > 0) insert list_share; 19 } 20 }
寫完代碼後,不要忘記啟用觸發器讓它生效
此時創建一條數據,如果約會人存在且不等於所有人,則再次查看我們的共享列表就能看到類似如下的內容
這也就是通過代碼實現的自動共享操作。
需要註意的有幾個點:
- 1.約會人不能為空
- 2.約會人不能等於記錄所有人
- 3.約會人不能等於系統管理員
- 4.約會人必須是被啟用的用戶
- 5.當記錄所有人被修改,共享過來的用戶都會被清空掉,需要重新共享權限
重點看下第五條,通過共享按鈕共享到的用戶會隨著記錄所有人的變更,從共享列表中被清除,所以我們在觸發器中需要根據這一點做好相關判斷與處理
1 //當記錄修改的時候觸發 2 if(trigger.isAfter && trigger.isUpdate){ 3 Set<Id> Set_movieId = new Set<Id>(); 4 for(Movie__c movie:trigger.new){ 5 Movie__c oldMovie = trigger.oldMap.get(movie.id); 6 //所有人發生變更且新記錄約會人不等於空 7 if(movie.OwnerId != oldMovie.OwnerId && movie.Engagement__c != null){ 8 Set_movieId.add(movie.id); 9 } 10 } 11 //判斷是否又符合條件的記錄 12 if(Set_movieId.size() > 0) handler.shareWithPerson(Set_movieId); 13 }
我們可以同樣使用新建時候的邏輯,傳遞一個滿足條件的Set集合到MovieTriggerHandler中的shareWithPerson方法中去,復用該方法。
這個問題在共享規則中是不存在的,用共享規則共享出去的權限不受記錄所有人變更的影響。
那麽在最後還有一點值得一提的是,如果字段約會人本身發生修改,在觸發器中除了要共享給新的約會人以權限,也需要刪除原約會人的記錄
1 List<Movie__Share> plist = new List<Movie__Share>([select UserOrGroupId,ParentId,AccessLevel 2 from Movie__Share where UserOrGroupId =‘movieId‘ and RowCause =: ‘Manual‘]); //類型:手動共享
查詢原約會人推薦加上對原因類型的判斷,Manual即指代手動共享的類型,來自我們用共享按鈕或Apex類的共享,從而有效避免查詢的用戶會有因其他原因具備查看該記錄的權限結果被我們刪除的情況。
Salesforce提供了相對簡單的權限設置方法,層級的模式下,在共享的時候要盡可能減少能看到記錄的用戶數量,進而保證數據的安全性,最後,如有遺漏歡迎指正,有問題可以在評論區留言。
Salesforce 開發整理(三)權限共享