From fc88a139d258a504e8903fe14ecec19adf375c23 Mon Sep 17 00:00:00 2001 From: Piotr PG Gajek Date: Mon, 17 Jun 2024 14:59:23 +0200 Subject: [PATCH 1/2] user mode and API Update Signed-off-by: Piotr PG Gajek --- force-app/main/default/classes/SOQL.cls | 21 +++++++++++++++-- .../main/default/classes/SOQL.cls-meta.xml | 2 +- force-app/main/default/classes/SOQL_Test.cls | 23 +++++++++++++++++++ .../default/classes/SOQL_Test.cls-meta.xml | 2 +- .../example/ExampleController.cls-meta.xml | 2 +- .../classes/example/SOQL_Account.cls-meta.xml | 2 +- .../classes/example/SOQL_Contact.cls-meta.xml | 2 +- .../example/SOQL_Opportunity.cls-meta.xml | 2 +- 8 files changed, 48 insertions(+), 8 deletions(-) diff --git a/force-app/main/default/classes/SOQL.cls b/force-app/main/default/classes/SOQL.cls index 530e557..a9bb09a 100644 --- a/force-app/main/default/classes/SOQL.cls +++ b/force-app/main/default/classes/SOQL.cls @@ -132,6 +132,7 @@ public virtual inherited sharing class SOQL implements Queryable { Queryable forUpdate(); Queryable allRows(); // FIELD-LEVEL SECURITY + Queryable userMode(); Queryable systemMode(); Queryable stripInaccessible(); Queryable stripInaccessible(AccessType accessType); @@ -661,6 +662,11 @@ public virtual inherited sharing class SOQL implements Queryable { return this; } + public SOQL userMode() { + executor.userMode(); + return this; + } + public SOQL systemMode() { executor.systemMode(); return this; @@ -1808,8 +1814,8 @@ public virtual inherited sharing class SOQL implements Queryable { } private inherited sharing class Executor { - private AccessLevel accessMode = AccessLevel.USER_MODE; // The object permissions, field-level security, sharing rules are enforced. - private DatabaseQuery sharingExecutor = new InheritedSharing(); + private DatabaseQuery sharingExecutor; + private AccessLevel accessMode; private AccessType accessType; private String mockId; private String ofObject; @@ -1818,6 +1824,13 @@ public virtual inherited sharing class SOQL implements Queryable { public Executor(String ofObject, QueryBuilder builder) { this.ofObject = ofObject; this.builder = builder; + + userMode(); + inheritedSharing(); + } + + public void inheritedSharing() { + sharingExecutor = new InheritedSharing(); } public void withSharing() { @@ -1832,6 +1845,10 @@ public virtual inherited sharing class SOQL implements Queryable { accessType = type; } + public void userMode() { // The object permissions, field-level security, sharing rules are enforced. + accessMode = AccessLevel.USER_MODE; + } + public void systemMode() { // The object permissions, field-level permissions are ignored, sharing rules are controlled by the sharingMode. accessMode = AccessLevel.SYSTEM_MODE; } diff --git a/force-app/main/default/classes/SOQL.cls-meta.xml b/force-app/main/default/classes/SOQL.cls-meta.xml index f5e18fd..651b172 100644 --- a/force-app/main/default/classes/SOQL.cls-meta.xml +++ b/force-app/main/default/classes/SOQL.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 61.0 Active diff --git a/force-app/main/default/classes/SOQL_Test.cls b/force-app/main/default/classes/SOQL_Test.cls index ffa847e..0db1db6 100644 --- a/force-app/main/default/classes/SOQL_Test.cls +++ b/force-app/main/default/classes/SOQL_Test.cls @@ -2223,6 +2223,29 @@ private class SOQL_Test { } } + @IsTest + static void userMode() { + // Setup + insert new Task(Subject = 'Test', Type = 'Other'); + + System.runAs(minimumAccessUser()) { + // Test + Exception queryException = null; + + try { + Task task = (Task) SOQL.of(Task.SObjectType) + .with(Task.Type) + .userMode() + .toObject(); + } catch(Exception e) { + queryException = e; + } + + // Verify + Assert.isTrue(queryException.getMessage().contains('No such column \'Type\' on entity \'Task\'.')); + } + } + @IsTest static void stripInaccessibleToObject() { // Setup diff --git a/force-app/main/default/classes/SOQL_Test.cls-meta.xml b/force-app/main/default/classes/SOQL_Test.cls-meta.xml index f5e18fd..651b172 100644 --- a/force-app/main/default/classes/SOQL_Test.cls-meta.xml +++ b/force-app/main/default/classes/SOQL_Test.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 61.0 Active diff --git a/force-app/main/default/classes/example/ExampleController.cls-meta.xml b/force-app/main/default/classes/example/ExampleController.cls-meta.xml index f5e18fd..651b172 100644 --- a/force-app/main/default/classes/example/ExampleController.cls-meta.xml +++ b/force-app/main/default/classes/example/ExampleController.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 61.0 Active diff --git a/force-app/main/default/classes/example/SOQL_Account.cls-meta.xml b/force-app/main/default/classes/example/SOQL_Account.cls-meta.xml index f5e18fd..651b172 100644 --- a/force-app/main/default/classes/example/SOQL_Account.cls-meta.xml +++ b/force-app/main/default/classes/example/SOQL_Account.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 61.0 Active diff --git a/force-app/main/default/classes/example/SOQL_Contact.cls-meta.xml b/force-app/main/default/classes/example/SOQL_Contact.cls-meta.xml index f5e18fd..651b172 100644 --- a/force-app/main/default/classes/example/SOQL_Contact.cls-meta.xml +++ b/force-app/main/default/classes/example/SOQL_Contact.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 61.0 Active diff --git a/force-app/main/default/classes/example/SOQL_Opportunity.cls-meta.xml b/force-app/main/default/classes/example/SOQL_Opportunity.cls-meta.xml index f5e18fd..651b172 100644 --- a/force-app/main/default/classes/example/SOQL_Opportunity.cls-meta.xml +++ b/force-app/main/default/classes/example/SOQL_Opportunity.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 61.0 Active From 2672368c50dc9248a187535d1dda8b02cf751dde Mon Sep 17 00:00:00 2001 From: Piotr PG Gajek Date: Fri, 28 Jun 2024 17:23:21 +0200 Subject: [PATCH 2/2] documentation update Signed-off-by: Piotr PG Gajek --- website/docs/api/soql.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/website/docs/api/soql.md b/website/docs/api/soql.md index fe8c3cd..5ce745b 100644 --- a/website/docs/api/soql.md +++ b/website/docs/api/soql.md @@ -130,6 +130,7 @@ The following are methods for `SOQL`. [**FIELD-LEVEL SECURITY**](#field-level-security) +- [`userMode()`](#userMode) - [`systemMode()`](#systemmode) - [`stripInaccessible()`](#stripinaccessible) - [`stripInaccessible(AccessType accessType)`](#stripinaccessible) @@ -1682,6 +1683,28 @@ By default AccessLevel is set as `USER_MODE`. More details you can find in [here](../advanced-usage/fls.md) +### userMode + +By default, all queries are executed `WITH USER_MODE`. However, developers can override this. For more details, check [Field-Level Security](../advanced-usage/fls.md) and [Sharing Rules](../advanced-usage/sharing.md). + +The `userMode` method can be useful to override the `systemMode()` provided by the selector. + +> Execution mode in which the object permissions, field-level security, and sharing rules of the current user are enforced. + +**Signature** + +```apex +Queryable userMode() +``` + +**Example** + +```apex +SOQL.of(Account.SObjectType) + .userMode() + .toList(); +``` + ### systemMode > Execution mode in which the the object and field-level permissions of the current user are ignored, and the record sharing rules are controlled by the class sharing keywords.