apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
906 stars 515 forks source link

fflib_SecurityUtilsTest failures in Spring '21 Scratch Orgs #315

Closed tfuda closed 3 years ago

tfuda commented 3 years ago

I created a Spring '21 "Preview" scratch org today and ran our application's Apex unit tests. Our apps include fflib-apex-common. I observed three failures in fflib_SecurityUtilsTest of the following nature:

Apex log for fflib_SecurityUtilsTest.readonly_field_access
==========================================================
47.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
02:58:51.2 (2784413)|EXECUTION_STARTED
02:58:51.2 (2810336)|CODE_UNIT_STARTED|[EXTERNAL]|01pR0000009SXYy|fflib_SecurityUtilsTest.readonly_field_access()
02:58:51.2 (11760463)|SOQL_EXECUTE_BEGIN|[38]|Aggregations:0|SELECT id, Name FROM Profile WHERE Name = :tmpVar1
02:58:51.2 (16871071)|SOQL_EXECUTE_END|[38]|Rows:0
02:58:51.2 (17496051)|FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject

Class.fflib_SecurityUtilsTest.setupTestUser: line 38, column 1
Class.fflib_SecurityUtilsTest.readonly_field_access: line 56, column 1
02:58:51.2 (17526956)|FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject

Class.fflib_SecurityUtilsTest.setupTestUser: line 38, column 1
Class.fflib_SecurityUtilsTest.readonly_field_access: line 56, column 1

It turns out that Salesforce decided that, starting in Spring '21, they will no longer include the "Read Only" Profile in new orgs: https://help.salesforce.com/articleView?id=release-notes.rn_profiles_and_perms_read_only_new.htm&release=230&type=5. The new Profile they are providing is called "Minimum Access - Salesforce", but, unfortunately it cannot be used as a direct substitute for "Read Only", because it doesn't grant "Read" permission to any standard objects.

Here's a perfect example of why people dislike developing on this platform. This Profile has been present in orgs for the past 10 years, and many of us have probably written unit tests that rely on this in order to satisfy Salesforce's requirement that your code enforce CRUD perms. Suddenly, they decide to remove it. So, we've got to come up with a new way of running tests as a User that lacks the C, U and D perms in CRUD. I'll work on a PR. I'm thinking I'll will have to programmatically create a Permission Set that grants Account "Read" permission in a method annotated with the TestSetup annotation and then modify the setupTestUser method to assign this if the "Read Only" Profile is not present (the tests in fflib_SecurityUtilsTest are all based on trying to perform CRUD operations on Account).

ImJohnMDaniel commented 3 years ago

G'day @tfuda. Thanks for reporting this one. We will get into it soon.

tfuda commented 3 years ago

So, I am trying to work out a solution for this one. I have to, because we've forked fflib-apex-common for use within our applications, plus I have other unrelated unit tests that also relied on the "Read Only" Profile. Seriously, sometimes the folks at Salesforce just don't think about the consequences of their actions on existing integrations / partners. They've been telling us for years that we're responsible for enforcing CRUD and FLS ourselves, instead of the platform doing it natively. So, we write tests to verify we're enforcing security, as required, and then then go and do this. This is an unnecessary time suck.

ImJohnMDaniel commented 3 years ago

@tfuda Understood. Look forward to seeing a PR from you with a fix for this.

stohn777 commented 3 years ago

Hi @tfuda Echoing JD's comments, thanks for highlighting this core issue, and please at-mention me on the PR and I'll expedite it.

Thanks.

cropredyHelix commented 3 years ago

@tfuda - thanks so much for addressing this. During a period of dead time, I was going through the Critical Updates and whoa - tests that rely on Profile = ReadOnly will fail for orgs created as of Spring 21. Lifetime employment for devs across thousands of orgs