Salesforce Certified Sharing and Visibility Designer – Programmatic Sharing
- 3.0- Programmatic Sharing Introduction
This is section three, programmatic sharing. And this is the introduction lecture as per the official Salesforce certified sharing and visibility designer exam outline. The exam topics are classified into three sections declarative sharing, performance and scalability and programmatic sharing. This is the Programmatic Sharing section that has 17% and exam questions weight.
So if the exam has 60 questions, this section will have around ten questions. The lectures that cover the objectives in this section include Programmatic Apex Sharing, which deals with how to open up rapid access using Apex. We will visit the share objects, the details and fields of these objects, how to write Apex code, to add share object records, how to use sharing reason and what
are some tips when it comes to deleting shared records? Minimizing security risks and programmatic Apex Sharing, which deals with what are some known risks when it comes to Apex in general and sharing records. These are things like soccer injection attacks and how to prevent them unit tests for Programmatic Apex Sharing, where we will talk about test classes in general and what annotations and methods should be used with test classes.
And finally enforcing object and feed level permission and programmatic sharing. This is mainly the use of System Mode, enforcing Object and feed level permissions in Apex classes. Enforcing permissions in VF pages and in custom controllers. And that’s it for this lecture. Thanks for watching.
- 3.1- Programmatic Apex Sharing
This is section three, Programmatic Sharing, and this lecture is about programmatic Apex Sharing. The topics of this lecture are Apex managed Sharing Overview, Share Object and Share Object columns, sharing reasons and creating Share Object records using Apex Apex Managed Sharing is yet another way to open a record axis at this time.
Through code, it allows developers to build sophisticated and dynamic sharing settings. Apex Managed Sharing can be done on objects that have their Owd set to private or public read only. Also note that only users with Modify all data permission can add or change Apex Managed Sharing on a record. Now, let’s talk about this Share object. A Share Object exists for a Salesforce object if the Owd sharing settings for this object is restrictive, which means private or public read only. This is because if the Owd is set to public read and write, there is no need to open up record access, as Edit is available for anyone.
So if an object’s Owd is public read and write, the Share Object table has zero records, and there is no need to share as it is already publicly read and write. Now, for objects on the detail side of a master detail relationship, these don’t have any associated sharing object. Why? Well, because the details object records access is determined by the master object. A shared object includes record supporting explicit sharing. This is managed sharing, which means record ownership and sharing rules. This is also User Managed Sharing, which means manual sharing by the owner or by a user with full access permission on the record. And this also means Apex Managed Sharing, and it also supports implicit Sharing.
So anytime an explicit or an implicit sharing is created, a new entry gets created in the Sharing table. And this entry allows the access to the record. So, as you can see in this list, we have Apex Managed Sharing, which is part of the explicit sharing. So in conclusion, Apex Managed Sharing means simply creating records and the shared objects through Apex. Now, let’s get into more details about the Share object. For standard objects, the Share Object is defined as object name Share. This is something like opportunity share, like account share, like k share and so on. The Share Object has zero records until you make the object Owd restrictive.
So if the Owd is set to public read Edit, then the object Share Table exists, but it has zero records. For custom objects, the Share Object is defined as the custom object name, and then to underscore, and then the War Chair, for example, invoice underscore underscore Share. And there is no Share Object until you make the object Owd restrictive.
This is different than the standard Share Object. This is an example in my Salesforce. org, the Opportunity Owd was set to PublicRead, right? So doing a query against the Opportunity Share Object will get me zero records. But the moment I change the Owd to something else like let’s say private or public read. The opportunity. Share table gets populated with records. Let’s add more details and more fields in the query. We will add the field opportunity, access level opportunity, ID row code and user or group ID. And we will run the query again. So as you can see, this is the result.
What are these? What are all of these fields? We will see in detail in the next slide. So to be more precise, the Share Table or object has these columns ID, which is simply the idea of the Sharing Entry Opportunity Access Level, which specifies the level of access that this specific user or group has been granted. The value can be edit, read, or all opportunity. ID. This contains the ID of the specific opportunity record that we want to share.
Row Code, which specifies the reason why the user or group is being granted access. And finally, User or Group ID, which specifies the User or Group ID to which you are granting access. So, going back to this query now we should understand the meaning of each record. So, as you can see on this table, we have this opportunity that ends with nine QA and then we are sharing this opportunity with this user and then why we are sharing it. What’s the reason of this row? The reason is the owner, which means that this user is the owner of this opportunity. And then the level of access that this user has on this opportunity is all.
So this user can edit this opportunity. And then the idea of this Sharing entry is simply the first column. So the same thing is for the other opportunities. So as you can see, we have a list of opportunities. As you can see, these are all different opportunities and each one of them has an owner and this owner has full access to this opportunity. And then you can see that the ID is different for each one of these entries. So, to make it simple, Apex Managed Sharing is simply the action of adding and removing records to and from this table. So if, let’s say I use Apex to create an Opportunity Share Record with the Opportunity Axis Level set to read and the Opportunity ID set to the ID ending with nine QA and a user or group is set to an ID of a user called X.
And then I login as X. So in this case, X will be able to see this opportunity in the User interface. So I add Share Records to share opportunities with users and custom objects. Sharing Tables salesforce uses two different fields than in standard objects. The first one is access level. This is used instead of something like Opportunity Access Level and the second one is Parent ID. This is used instead of something like Opportunity ID. This is an example. As you can see, we have a soccer or query and this query is using this custom share object. So for that we cannot use, let’s say invoice ID or let’s say invoice Access Level. We have to use access level and parent ID.
So as you can see, this is the result. We have Access Level set to old and then we have Parent ID. Again. Access level is instead of opportunity. Access level and parent ID. Is instead of opportunity. ID. Now, let’s talk in detail about the rowcos field and the share object. Rowcos explains the reason the record is being shared to the specific user or group. Now this is very important to know. Standard share objects like the Opportunity Share, Account Share and so on, will not have write access to the Row course field. Which means that when inserting a share object record for a standard object, we cannot write to the rowcourse field. But we can indeed write to this field when the object in question is a custom object. This is the list of the Rocos values.
Owner means that the specific user is the record owner. Implicit. Parent means that a child record related to this record is owned by the specific user. Team means that the specific user is a team member like Account Team case Team Opportunity Team. Manual means that sharing was manually granted to the specific user. Territory manual means that the account record was manually assigned to a territory. Territory means that a territory assignment rule granted access for this account to the specific user.
And finally, Apex sharing reason can be any custom reason that we specify. This is only available for custom objects. How to add custom Apex sharing reasons. As you mentioned, Apex sharing reasons are only available for custom objects and not for standard objects. They can be created from the object settings and the classic user interface. And you can create Apex sharing reasons using the Metadata API. Up to ten Apex sharing reasons can be created per object. And needless to say, that once created reasons can be used in Apex sharing.
Deleting an Apex sharing reason will delete all sharing on the object that uses it. So if, let’s say I create the custom object sharing reason on the right side, let’s call it a lead reason, and then I use Apex to create share records that use this reason, then I delete this reason, then all share records that are using this reason as row codes will be deleted.
This is also very important by default. And if I don’t specify any row codes reason when creating a share record using Apex, then the row codes will be specified as manual. So if I am inserting share records for a standard object using Apex, then the only row codes will be manual. Why? Because I don’t have the luxury to create other share reasons. And finally, when ownership of a record changes, only shares with row codes equal to manual will be deleted. So if I have an opportunity record with a bunch of share records written using Apex. These can only have the row coast set to manual because this is a standard object.
As we cannot specify, the row calls for a standard object. So when the owner changes for this opportunity, all of these share records will get deleted. For custom objects, all Apex sharing reason names will have the following format my reason name underscore underscore C just like any field API name apex sharing reasons can be referenced in Apex as follows schema custom object name underscore Share rowcos sharing reason underscore C this is an example.
An Apex sharing reason called recruiter for an object called Job can be referenced as follows schema job underscore Share which is the share table of the job object. And then that row cause recruiter underscore C which is the row cause. Now, why the use of Apex managed sharing as opposed to all of the sharing mechanisms that we have seen so far? After all, and as you know, best practices from Salesforce is to always use decorative sharing.
What are some reasons of using Apex sharing? Well, the first reason that we have to use Apex is when standard sharing functionality is not sufficient and sharing logic is too complex to be established declaratively. The second reason is when sharing rules depend on a combination of values across multiple objects and not the same object.
When sharing access is criteria based, but the evaluated field is not supported by declarative sharing. And finally when all attempts to share declaratively have failed. So we have to revert to Apex when any declarative sharing is not sufficient. Now, these are the steps that are needed to do Apex managed sharing. One sharing reason must first be defined for custom object. This can be created by navigating to the Apex sharing reasons related list of an object. Again, this is on the classic interface. And each Apex sharing reason has a label and a name. Two.
While creating Apex code for sharing a record, the following fields must be defined. The first field is the parent ID which corresponds to the record being shared. Then we have the user or group ID. This is the ID of the user or public group to whom access is being granted. Then we have the access level which can be read, edit or all. And then we have the row code which is used for specifying the reason why the user or the group is being granted access. Note that either a custom row calls or manual row codes can be used in Apex code to create records and share tables.
And if left blank, it will be manual. This is an example of how to create a standard object a share record. We will go with the opportunity Share. As you can see on the first line, we are simply creating a new S object of type opportunity Share and the name is Opshare. And then on the next line we are filling the field of this S object. So as you can see, I’m using the name of this S object. And then I’m using the dot notation and then the field and then the value. So I’m specifying read as value for the opportunity access level.
And then I’m specifying this ID as the opportunity ID. This ID as the user or group ID. And then this row cause as the rowcos. And then I am inserting op share into the database. The same model is for Custom object. But there are two differences. So the first line will declare the S object. So the first difference is the name of the S object being object name. And then two underscores and then Share. And then everything is the same except for using Parent ID and for using Access Level. So if I go back, you can notice that I was using Opportunity access level and Opportunity ID. But for custom objects I use Access Level and Parent ID and everything else is exactly the same.
And as you can see row codes. I can use a custom row code. From the Apex Developer Guide, you can find classes that you can use to create managed sharing using Apex. And also the test class is included. To do so, you have to just click on this link. And then you have this page. And then on this page you can see that there is a class called Job Sharing. And then it has a method called manual share read. This method takes two parameters. The record. ID.
This is mainly the ID of the job record. And then we have the user or group ID. This is the ID of the user or group that we want to share this record with. And then as you can see, I have all of the fields being populated. And then if I invoke this method, I will get a new share record created. Finally, some notes regarding Apex Managed Sharing that you should be aware of.
Only users with modify all data permission can add, edit or delete Apex Managed Sharing records. A record can be shared multiple times with a user or a group using different Apex Sharing reasons. When multiple entries and the Share object apply for the logged in user, the most permissive one will apply.
And Apex Managed Sharing is maintained across record owner changes if the row codes is not manual. So if let’s say we have a record and this record has changed ownership. So now we have a new owner. In this case, all of the records and the shared table that have Roko’s equal to manual will be deleted. Now let’s go to salesforce to see Apex managed sharing. And action.
Okay, so I’m now logged in as the admin. The first thing that I want to show you is the Owd of two objects that I will pick. So I will use the Opportunity Standard object which has Owd of internal and external set to public read and write, which is the least restrictive. And then for the custom object I will choose the invoice object which also has Owd set to the list restrictive. Now let me go to workbench and then to the soccer query. So, let’s see. First opportunity share. So it will be there.
But because the Owd is set to the least restrictive, it will have zero records. So if I go to the count and query you can see that I have zero records. Now for the invoice you can see that I have the object name and then I have the history. But I don’t have invoice underscore underscore Share. Why? Again, because the Owd of this object is set to public read and write.
Now I will set both of these to private and see what will happen. Okay, so the opportunity I need to make it private and for the invoice I will do the same thing. Now save and let me close workbench and then wait for this to be complete and then I will open workbench again. Okay, so opportunity Count and let’s see how many we have. We have 37 now.
And then for the invoice count and query you can see that we have five. Now let me go to the admin page and then go to, let’s say the Invoice object. Okay, so as you can see, these are the five invoice records that correspond to the five that we have. Why? Because each owner will have a record and this table. So let’s make it more clear.
Access level ID parent row cause and user group ID So as you can see, these are the five share records where parent ID is simply each one of these invoice records. So if let’s say I click on this, you can see that the ID is five B-C-A AA Z which is this one. Now for the opportunity you can see that now we have Opportunity Access Level instead of access Level and then we have Opportunity ID instead of Parent ID. And then we have this list of records. So the difference is mainly this field and this field. These are the same fields but the naming is different. Now let’s go to the invoice object and let’s create row codes. So how to do that? We have to go to Classic and then we have to go to Setup and then we have to search for create objects. And then click on invoice.
You can see Apex sharing reasons. So let’s create a new one and save. Okay, so now I have a custom reason for this object. And as you can see, if let’s say I go to any standard object like the Opportunity, you can see that there is no section for creating these reasons. These are only available on the custom objects. Now let’s go back to Lightning and let’s go to the invoice object and we have these five records. Now you can see that these five records are owned by these users. So I will log in with any user that is not part of these five users. So let me open the three.
I will log in with Angela and Angela is service team user too. Okay, so as you can see, Angela cannot see any invoice. Now let’s create a new sharing record. So we will open the developer console and then I will open anonymous Apex. And then I will paste this code. So I’m doing one. The first one is simply creating a new S object with type invoice underscore underscore share, and then the name is n share. And then I’m adding the fields. So the access level will be read and then the parent ID will be the ID of the record that I want to share. So if I go back to this, let’s say that I want to share invoice one.
Let me copy the ID, and then let me put this ID instead of that one. Now I need to get the ID of the user to whom I want to share this record with. So in this case, it will be Angela. Let’s go to the setup menu and let’s search for Angela and let’s take the ID. And then the reason will be this one. And then I will insert it. Now, at the same time, let me go to workbench and let me do a query on the invoice Share table and let me add access level.
Okay, so as you can see, now I have the list of five records. Now let me go back to the developer console and let me add this one. And then let me query again. You can see now I have six, and the 6th one is this one, and this ID is the ID of Angela. So if I click on this, you can see that I have this name. Now, if I go back to Firefox and then if I refresh this page, you can see that now I have access. Angela has access to this record and she can only read it. Why? Because this is the access level that I did add on the insertion of the record.
So if I go back to Firefox and then if I try to edit, you can see that I cannot. Okay, what we can do more, we can edit this record. So let me take the ID, which is this one, and then let me do a soccer query. So I will just paste the ID. Okay, so now this query will fetch this invoice Share and then it will add it to this variable. Now let me change the access level to edit and I will highlight this code, these lines of code, and then let’s execute them and query again. You can see now I have edit. Now, what happens if I change the owner of this invoice? So going back to my admin page, let’s change this to a new owner. So let’s make it myself or Sarah and change. Now what will happen? Create again. It is still intact. Why? Because I’m using this row code. Now let’s go back to the developer console and let me add a new Share record. So in this case, I will add this Share record, but I will remove the row codes and then I will share this with another user. So let’s go back to the admin page and we will share this with, let’s say, Lee. So I just need to make sure that Lee does not have access to any invoice. And then I will take the ID and then I will insert this Share record. Okay? So now I have this.
And if I log in as Lee, lee will be able to view this invoice record. But what will happen now if I change the owner? So let’s go back to this invoice one and let’s change this to myself. So now if I run this query, you will notice that this will stay, but this will be deleted. Okay? So as you can see, using manual as row codes will make this row deletable.
But using a custom row code will keep this row intact. Now, the final piece that I want to show is the link that I told you about. Let me open a new tab and then let’s go to this. So as you can see, I have here this class. And then I have all of the lines that we have made. And then I have this method that will take these two parameters. And then I also have a test class for the same. So I can simply copy and paste this class, control A, control C. And then I can go to my where I can paste this class and a new class.
And then I can use this class and this method to simply share records with users. So I need to simply add a record ID and a user or group ID as two parameters to this method. And this will take care of sharing this record with this user. And the sharing type will be read. Of course, I can make my own methods by following the same logic. So in this case, I can have, let’s say, Manual, Share, Edit and so on. So I can use the same format and then I can add my own methods. And that’s it for this lecture. In this lecture, we have talked about Apex managed sharing, which allows developers to build sophisticated and dynamic sharing settings.
We mentioned that only users with the Modify All Data permission can add or change Apex managed sharing on a record. We talked about the Share object and that Apex managed sharing is simply creating records and the Share object through Apex. For standard objects. The Share object has the format object name share. Like account share opportunity share. And for custom objects, we add two underscores between the object name and the share world. The share object includes records supporting both explicit and implicit sharing. Explicit includes apex managed sharing. We also talked about the columns or fields of a shared object.
The main ones are parent ID, which corresponds to the record being shared user or group ID, which is the ID of the user or public group to whom access is being granted. Access level can be either read, edit or all row codes. Specifies the reason why the user or group is being granted access. And finally, we have talked about the sharing reason, which can only be defined for custom objects and not for standard objects. And very important point if the owner of a record is changed, all share records with the manual reason are deleted. Deleted by default and deleting. An Apex sharing reason will delete all sharing on the object that uses it. And we also talked about the syntax to add sharing reasons when using Apex.