プロファイルと同期した公開グループを作成する

By | March 5, 2022

前書き

ユーザの作成時・プロファイル更新時に、プロファイルに1:1で対応する公開グループにユーザを割り当てる。

※全体的に雑なので、適宜修正をお願い致します。

大きな方針

ユーザの作成時:「グループメンバー」レコードをINSERT

ユーザの更新時:既存の「グループメンバー」レコードをDELETE&新規「グループメンバー」レコードをINSERT

プロファイルと公開グループが事前に定義されていて、それらが将来的に増減する可能性がゼロの場合

①下記のいずれかでプロファイルIDと公開グループIDの対応関係を定義

  • カスタム設定(※数が少ない場合)←本記事ではこちらをベースに例を提示
  • カスタムメタデータ(※数が多い場合)

※プロファイルやロールにカスタム項目は作成できない

②ユーザ作成時にプロファイルに応じて公開グループのグループメンバーに割り当てる処理をApexで記述

※グループメンバーは共にSetupオブジェクトであるため、非同期処理化しないと’Mixed DML Operation’エラーが発生する。

■Apex Trigger

trigger UserTrigger on User (after insert) {
	UserTriggerHandler.onAfterInsert(trigger.new);
}

■Apex Class


public class UserTriggerHandler {
    public static void onAfterInsert(list<User> userList){
        list<groupMember> groumMemberListToInsert = new list<groupMember>();
        for(User u : userList){ 
            if(u.UserType == 'PowerPartner'){
                //公開グループに割り当て
                createBpGroupMember(u.Id, u.profileId);
             
            }           
        }  
    }
    
    @future
    public static void createBpGroupMember(Id userId,Id profileId) {
        Ids_PartnerPortal__c ids = Ids_PartnerPortal__c.getOrgDefaults();
        Id PROFILEID_BP = Id.valueOf(ids.Id_BpProfile__c);
        Id PUBLICGROUPID_BP = Id.valueOf(ids.PublicGroup_Bp__c);
        groupMember gp = new groupMember(); 
        gp.UserOrGroupId = userId;
        if(profileId == PROFILEID_BP){
            gp.groupId = PUBLICGROUPID_BP;
            insert gp;
        }
        else{
            return;
        }       
    }

}

■Test Class

@isTest
public class UserTriggerTest {
    @testSetup
    static void setup() {
        //プロファイル
        Id p1 = [select id from profile where name='Partner Community User'].id;
        //公開グループ
        Group gp1 = new Group(Name ='Test1');
        insert gp1;
        //カスタム設定
        Ids_PartnerPortal__c setting = new Ids_PartnerPortal__c();
        setting.Id_BpProfile__c = p1;
        setting.PublicGroup_Bp__c = gp1.Id;
        insert setting;   
    }
    
    @isTest
    static void testMethod1(){
        //ランダム変数準備
        String orgId = UserInfo.getOrganizationId();
        String dateString = String.valueof(Datetime.now()).replace(' ','').replace(':','').replace('-','');       
        Integer randomInt = Integer.valueOf(math.rint(math.random()*1000000));
        String uniqueName = orgId + dateString + randomInt;
        //取引先・取引先責任者・ユーザの作成
        Account acc1 = new Account (
            Name = 'newAcc1'
        );  
        insert acc1;
        Contact con1 = new Contact (
            AccountId = acc1.id,
            LastName = 'portalTestUser1'
        );
        insert con1;
        Id p1 = [select id from profile where name='Partner Community User'].id;
        User user1 = new User(alias = 'test123', email='test123@noemail.com',
                              emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',
                              localesidkey='en_US', profileid = p1, country='United States',IsActive =true,
                              timezonesidkey='America/Los_Angeles', Username = uniqueName + '@test1' + orgId + '.org',
                              contactId = con1.id); 
        Test.startTest();
        insert user1;
        Test.stopTest();
    }
}

③ユーザのプロファイル更新時に既存の公開グループへの割り当てを削除し、更新後のプロファイルに対応する公開グループのグループメンバーに割り当てる処理を記述

※この処理はフローとApexのどちらでもよい

プロファイルの新規作成時に自動で公開グループが作成し、その後のユーザ作成・ユーザのプロファイル更新時に自動で適切な公開グループが割り当てられるようにする。

以下、コメント

・プロファイルやロールはApex Triggerの起点となり得ない

・しかしながら、ユーザの作成・更新時にプロファイルと公開グループの対応関係が定義されているか確認し、未定義の場合に、公開グループを作成したうえでカスタムメタデータに対応関係を定義したレコードをINSERTするといった処理は可能

・とはいえ、①通常プロファイルへのユーザ割り当ては「公開グループ」に関連する諸々の設定の完了後である②プロファイルの新規作成は軽々しく行われるべきではない(=手動運用の負荷が少ない)という二点を考慮すると、敢えて完全に自動化する必要のあるユースケースは少ないと思われる。