关于Profile的部署

去年有人问了我一个问题————为什么清理干净的Profile部署到新环境会多出很多东西。比如说Custom Application Setting, Tab Settings与Object Permissions。明明在源环境相关权限都已经移除,结果到了新环境又阴魂不散的出现了。

这个问题确实略为复杂,这也是为何拖了一年才动笔讨论这个问题。

众所周知,Metadata的部署有两种行为模式,一种是覆盖,一种增量。本文这里不做展开。
相对的,Metadata的取得也有两种模式,一种是独立内容,一种是关联内容。独立内容是指在package.xml中只包含元素自己的时候能将所有内容取出;关联内容是指在package.xml中除了元素本身之外,必须包含关联元素,才能将与其他元素有所关联的内容取出。独立内容的典型代表为ApexClass,CustomField;关联内容的典型代表Object与Profile。如此同时,这两种Metadata也同时存在独立内容。
具体来说,Profile的Metadata内容可以一分为二,第一种是Profile独立内容;第二种是与其他Metadata关联的内容。
✳️具体哪些内容是独立内容,哪些是关联内容,以及关联内容的Retrieve方法参考此思维导图。

部分信息表格版如下:

Category Source Metadata Type Support *?
Profile Basic Infomation Profile Include N/A
Page Layouts Assignment RecordType+Layout Yes+Yes
Field-Level Security CustomField Yes
Custom App Settings CustomApplication Yes
Connected App Access ConnectedApp Yes
Tab Settings CustomTab+CustomObject Custom Yes
Record Type Settings RecordType Yes
Permissions Profile Include N/A
Object Permissions CustomObject Custom Yes
Session Settings Independent Metadata Type => ProfileSessionSetting Yes
Password Policies Independent Metadata Type => ProfilePasswordPolicy Yes
Login Hours Profile Include N/A
Login IP Ranges Profile Include N/A
Apex Class Access ApexClass Yes
Visualforce Page Access ApexPage Yes

所以如果package.xml中只包含profile本身的话,那么在profile metadata中仅能取出profile基本信息,权限信息,ip range等有限信息。只有将其余关联metadata都包含进package.xml才能取出完整的profile metadata内容。不过,这时候喜欢动手实践的同学会发现,就算是把关联的metadata添加完整,仍然有些profile信息是取不下来的,比如没有任何增删改查的Object Permission。你只能取下来有访问权限的部分,application部分同理。这也是部署到新环境之后希望杀死的权限又死灰复燃的原因之一。
那么有些同学会有疑问,就算是没能将无权限的部分取得下来,那么部署到新环境的时候作为新建的profile,权限是怎么出现的呢?这个默认值是哪里出现的?
所谓实践出真知,如果设计下列实验,就很容易得到答案:
1. 随便找一个环境。
2. package.xml中只包含profile「Minimum Access – Salesforce」。因为此profile为官方提供的权限最少的profile。
3. 取得步骤2的profile,拷贝metadata文件,并改成其他名字,将文件中的false改成true,保存。
4. 将package.xml中的profile名称改为步骤3新建profile的名字,部署。如果使用的是vscode,可以在profile上直接右键deploy。
5. 在环境中打开新建的profile与「Minimum Access – Salesforce」。肉眼可见,在object permissio部分非常不同。
6. 新建的profile与「Standard User」进行对比,发现object permission部分完全相同。
7. 修改「Standard User」的Object Permission,重复步骤1到4再新建一个profile,取得后再次与「Standard User」进行对比,会发现新建的profile与修改后的「Standard User」相同。

由以上实验可以得出结论,通过部署方式新建profile的时候,对标手动创建时必须选择参照哪个profile的流程,系统会默认以「Standard User」作为新建模版,将部署的metadata内容以增量的方式作用到新profile上。未指定的部分以目标系统的「Standard User」设定为准。

那么原因知道了,该如何解决这个问题呢?
目前方式有三。
1. 擒贼先擒王,先人工干掉目标环境的「Standard User」上面所有的权限,让「Standard User」变成「Minimum Access – Salesforce」。这时候再部署的话就不会有额外的权限。
2. 打铁还须自身硬。会被「Standard User」影响本质上还是因为自己没有全面的指定好所有的权限,让它钻了空子。如果能够在profile metadata文件中人工编辑所有未取得的内容,也不会有问题。
3. 中庸方案,人工去目标环境新建好profile,参照profile选择「Minimum Access – Salesforce」,然后再部署。这样既不会影响「Standard User」,也不需要手动编辑profile metadata文件,又保持了新建profile的洁净。不过由于「Minimum Access – Salesforce」也不是绝对的Mininum,比如Custom Application Permission仍然带上了全部的app,所以针对此部分还是要在1与2中进行选择。

有同学又有疑问了,部署的方式有很多种,如果我用changeset还会有相同的问题吗?
答案是一样的,好奇的同学可以自己设计一个实验试一下。