[SalesForce] Run Trigger As A Specific User (or Profile)

Is this possible? I'm not finding help, Google or otherwise, for this.

Situation:

A trigger runs and cycles through groups of Opportunities. Some of these Opportunities are Closed Won, and most users of the system are not allowed to Edit Closed Wons (especially the Sales team). But I need this trigger to be able to touch the Opps (it's fired when the User touches the Account and subsequently a group of Opps under that account gets touched). It is a VALIDATION RULE blocking them.

Ultimately, I may investigate, if no other option, setting a HIDDEN FIELD on the Opp before updating, then clearing if after, and putting bypass code in the Validation rule. This is a backup plan. I'd like to know how to "Run As" a specific profile though.

Anyone have an example of this? I have three profiles out of twelve that can touch Closed Wons…

Best Answer

No, simulating another user/profile is not possible in the scenario you describe (and an undesirable platform feature for 3rd party code security reasons). You should always build backdoors into hard-fail validation rules for this reason. I prefer doing this to enforcing the logic via triggers because then the validation rules are still maintained via clicks admin, and you can do things like add error messages to specific fields.

The pattern I follow for Sys Admin manual overrides is to exclude the privileged profile(s) from the validation rule altogether (a la twamley's note). But that doesn't get you what you need, which is a code-only override.

For situations where only code is allowed to bypass a validation rule, you've mentioned the option of a hidden field but I'd suggest a significant tweak to it. I create a (18,0) numeric field called something like "Apex Updated" that is hidden from page layouts and read-only for FLS for user profiles. In any validation rule you want a code backdoor to, you just add a check for NOT(ISCHANGED(Apex_Updated__c)). Then, in your code, to bypass those validation rules you just set Apex_Updated__c to System.currentTimeMillis(). This has the advantage of not having to reset fields, or worse yet, missing the workflow to reset them and ending up with records that are permanently exempt from validation rules.

You say it's a backup plan, but it's just one custom field, one line of Apex code (to set the field when a bypass is desired), and one line of validation rule modification (to bypass the rule when the field is changed).