Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add withUserMode() and withSystemMode() to SObjectSelector and QueryFactory #435

Conversation

chazwatkins
Copy link

@chazwatkins chazwatkins commented Dec 2, 2022

Add withUserMode() and withSystemMode() to fflib_SObjectSelector and fflib_QueryFactory

fflib_QueryFactory

Specify WITH USER_MODE

fflib_QueryFactory qf = new fflib_QueryFactory(Account.SObjectType);

qf.withUserMode();
qf.getFLSEnforcement(); // USER_MODE

// OR

qf.setFLSEnforcement(fflib_QueryFactory.FLSEnforcement.USER_MODE);
qf.getFLSEnforcement(); // USER_MODE

Specify WITH SYSTEM_MODE

Salesforce uses SYSTEM_MODE as the default operation mode when not specified in the query. withSystemMode() allows users to make their queries explicit if desired.

fflib_QueryFactory qf = new fflib_QueryFactory(Account.SObjectType);

qf.withSystemMode();
qf.getFLSEnforcement(); // SYSTEM_MODE

// OR

qf.setFLSEnforcement(fflib_QueryFactory.FLSEnforcement.SYSTEM_MODE);
qf.getFLSEnforcement(); // SYSTEM_MODE

Switch back to LEGACY or NONE

fflib_QueryFactory qf = new fflib_QueryFactory(Account.SObjectType);

qf.withSystemMode();
qf.getFLSEnforcement(); // SYSTEM_MODE

qf.setEnforceFLS(true);
qf.getFLSEnforcement(); // LEGACY

// OR

qf.setEnforceFLS(FLSEnforcement.LEGACY);

// OR

qf.setEnforceFLS(false);
qf.getFLSEnforcement(); // NONE

// OR

qf.setEnforceFLS(FLSEnforcement.NONE);

fflib_SObjectSelector

isEnforcingFLS() and isEnforcingCRUD() now consider the DataAccess to determine their result instead of directly returning the values of m_enforceFLS and m_enforceCRUD. This allows the user to get the correct state from the methods, regardless if they are using legacy enforcement or one of the new operation modes.

Specify USER_MODE

AccountSelector selector = new AccountSelector();

selector.withUserMode();

selector.isEnforcingCRUD(); // true
selector.isEnforcingFLS(); // true

Specify SYSTEM_MODE

AccountSelector selector = new AccountSelector();

selector.withSystemMode();

selector.isEnforcingCRUD(); // false
selector.isEnforcingFLS(); // false

Switch back to LEGACY

AccountSelector selector = new AccountSelector();

selector.withSystemMode();

selector.isEnforcingCRUD(); // false
selector.isEnforcingFLS(); // false
selector.getDataAccess(); // SYSTEM_MODE

selector.enforceFLS();
selector.isEnforcingCRUD(): // true
selector.isEnforcingFLS(); // true
selector.getDataAccess(); // LEGACY

// OR

selector.setDataAccess(fflib_SObjectSelector.DataAccess.LEGACY);
selector.getDataAccess(); // LEGACY

Add

fflib_QueryFactory

  • void withUserMode()
  • void withSystemMode()
  • fflib_QueryFactory.FLSEnforcement getFLSEnforcement()
  • Boolean isEnforcingFLS();

fflib_SObjectSelector

  • void withUserMode()
  • void withSystemMode()

Change

fflib_QueryFactoryTest

  • Replace System asserts with new Assert class

fflib_SObjectSelector

  • Update enforceFLS() to set m_dataAccess to LEGACY
  • Update setDataAccess() to revert m_enforceCRUD to true when m_dataAccess is LEGACY
  • Update isEnforcingFLS() to return true when m_dataAccess is set to USER_MODE
  • Update isEnforcingCRUD() to return true when m_dataAccess is set to USER_MODE

fflib_SObjectSelectorTest

  • Replace System asserts with new Assert class

This change is Reviewable

…eryFactory

## fflib_QueryFactory

When the operation mode is set, the `enforceFLS` is set to false to skip the fflib_SecurityUtils checks.  Alternatively, when you call `setEnforceFLS(true)`, the operation mode is set to null, and fflib_SecurityUtils checks are respected.

### Specify `WITH USER_MODE`
```java
fflib_QueryFactory qf = new fflib_QueryFactory(Account.SObjectType);

qf.withUserMode();
qf.getFLSEnforcement(); // USER_MODE

qf.setFLSEnforcement(fflib_QueryFactory.FLSEnforcement.USER_MODE);
qf.getFLSEnforcement(); // USER_MODE
```

### Specify `WITH SYSTEM_MODE`
Salesforce uses `SYSTEM_MODE` as the default operation mode when not specified in the query.  `withSystemMode()` allows users to make their queries explicit if desired.

```java
fflib_QueryFactory qf = new fflib_QueryFactory(Account.SObjectType);

qf.withSystemMode();

qf.getFLSEnforcement(); // SYSTEM_MODE
// SELECT Id FROM Account WITH SYSTEM_MODE

qf.setFLSEnforcement(fflib_QueryFactory.FLSEnforcement.SYSTEM_MODE);
qf.getFLSEnforcement(); // SYSTEM_MODE
```

### Switch back to `LEGACY` or `NONE`

```java
fflib_QueryFactory qf = new fflib_QueryFactory(Account.SObjectType);

qf.withSystemMode();
qf.getFLSEnforcement(); // SYSTEM_MODE

qf.setEnforceFLS(true);
qf.getFLSEnforcement(); // LEGACY

// OR

qf.setEnforceFLS(FLSEnforcement.LEGACY);

// OR

qf.setEnforceFLS(false);
qf.getFLSEnforcement(); // NONE

// OR

qf.setEnforceFLS(FLSEnforcement.NONE);
```

## fflib_SObjectSelector

`isEnforcingFLS()` and `isEnforcingCRUD()` now consider the `DataAccess` to determine their result instead of directly returning the values of `m_enforceFLS` and `m_enforceCRUD`.  This allows the user to get the correct state from the methods, regardless if they are using legacy enforcement or one of the new operation modes.

### Specify `USER_MODE`

```java
AccountSelector selector = new AccountSelector();

selector.withUserMode();

selector.isEnforcingCRUD(); // true
selector.isEnforcingFLS(); // true
```

### Specify `SYSTEM_MODE`

```java
AccountSelector selector = new AccountSelector();

selector.withSystemMode();

selector.isEnforcingCRUD(); // false
selector.isEnforcingFLS(); // false
```

### Switch back to `LEGACY`

```java
AccountSelector selector = new AccountSelector();

selector.withSystemMode();

selector.isEnforcingCRUD(); // false
selector.isEnforcingFLS(); // false
selector.getDataAccess(); // SYSTEM_MODE

selector.enforceFLS();
selector.isEnforcingCRUD(): // true
selector.isEnforcingFLS(); // true
selector.getDataAccess(); // LEGACY

// OR

selector.setDataAccess(fflib_SObjectSelector.DataAccess.LEGACY);
selector.getDataAccess(); // LEGACY
```

## Add

### fflib_QueryFactory

- void withUserMode()
- void withSystemMode()
- fflib_QueryFactory.FLSEnforcement getFLSEnforcement()
- Boolean isEnforcingFLS();

### fflib_SObjectSelector

- void withUserMode()
- void withSystemMode()

## Change

### fflib_QueryFactoryTest

- Replace System asserts with new Assert class

### fflib_SObjectSelector

- Update `enforceFLS()` to set `m_dataAccess` to `LEGACY`
- Update `setDataAccess()` to revert `m_enforceCRUD` to true when `m_dataAccess` is `LEGACY`
- Update `isEnforcingFLS()` to return true when `m_dataAccess` is set to `USER_MODE`
- Update `isEnforcingCRUD()` to return true when `m_dataAccess` is set to `USER_MODE`

### fflib_SObjectSelectorTest

- Replace System asserts with new Assert class
@chazwatkins
Copy link
Author

@daveespo As requested, I incorporated the changes from #434 into #419. Let me know if you have any questions.

@daveespo daveespo deleted the branch apex-enterprise-patterns:419-user-mode-proposal January 11, 2023 23:55
@daveespo daveespo closed this Jan 11, 2023
@chazwatkins
Copy link
Author

Hi @daveespo - Should I update this pull request to include the builder style methods in master? Or has it been decided to not include them in the API?

@daveespo
Copy link
Contributor

Hi @chazwatkins -- I didn't explicitly close out this PR -- it was implicitly closed when I merged the branch it targeted. Can you reopen it and target it at master? There is some good stuff in here I'd like to merge. I'm not sure if the withSystemMode and withUserMode convenience methods are going to make it but there are some other things in here that need to come over (i.e. getFLSEnforcement() on QueryFactory, etc.)

Don't go changing anything in this branch yet. First, we want to get PR #437 and your #436 merged in .. and those will create merge conflicts with this branch .. let's sort out what we want to keep and what should get removed on this PR after those other two PRs are merged

@chazwatkins
Copy link
Author

Sounds good. I'll wait for the other PRs to get merged and submit this one to master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants