You need to sign in to do that
Don't have an account?
sparky
determine edit/delete permissions in code?
Is it possible to determine whether the current user has delete permissions (aka Full Access) for a particular record (custom object), without actually attempting to delete the record?
I'm creating some custom actions using VF/apex, and for some of them I want to limit who can perform the action to the same users who can delete the record. The action does not involve deleting the record, but I want it to be more restrictive than who can perform an edit.
I looked into the sharing table (object_share) but that only lists the owner as Full Access. Since anyone above the owner in the role hierarchy also has full access, and the hierarchy might be several levels tall, it seems like a tall order for my code to walk the entire hierarchy and determine if that applies. Is there an easier way?
Thanks much!
I'm creating some custom actions using VF/apex, and for some of them I want to limit who can perform the action to the same users who can delete the record. The action does not involve deleting the record, but I want it to be more restrictive than who can perform an edit.
I looked into the sharing table (object_share) but that only lists the owner as Full Access. Since anyone above the owner in the role hierarchy also has full access, and the hierarchy might be several levels tall, it seems like a tall order for my code to walk the entire hierarchy and determine if that applies. Is there an easier way?
Thanks much!
If so, that's only half the battle. I need to know if they have delete permissions on the record (via their role).
All you have to worry about is the Profile though... right?
I thought Roles only limit visibility... not edit/delete. If they can't see it, then they can't delete it.
So, are you encountering some sort of cascading delete issue where they can delete the Parent but the Child is not viewable via their Role or something?
Why do I get an "Insufficient privileges" error when trying to delete records?
The ability to delete records in Salesforce is controlled by the role hierarchy. Setting a sharing model to ""Public Read/Write"" alone does not give users the right to delete others records. There are 2 scenarios in which a user can delete a record:
1. The user attempting to delete the record is a System Administrator.
2. The user attempting to delete the record is the owner, or higher on the role hierarchy than the record owner.
Any other user that attempts to delete a record will receive an "Insufficient Privilege" error message.
Those below you on the role hierarchy may have read/write privileges according to the sharing model rules, however, they may not delete information from those individuals above them in that hierarchy.
Ok... so it blocks a delete for anything they are not supposed to see anyway. I guess that is good functionality.
There is your answer though.
If the userId = ownerId you are good to go.
If the userRole = ownerRole you are good to go.
If the userRole > ownerRole you are good to go.
I'm sure there is a way to query that last one, but you could just create a loop that walks up the chain looking for a match between the ParentRoleId and the other Id's.
FYI, there are two factually incorrect statements in your last post.
"If the userRole = ownerRole you are good to go" - Not true. Another user w/ same role as owner cannot delete owner's records (unless both are sysadmins).
"so it blocks a delete for anything they are not supposed to see anyway" - No, deletion and view/edit rights are separate. Often a user can view and even make edits to a record that they cannot delete.
Does anyone else have any suggestions here? I'm guessing there's no shortcut or someone would have offered it by now..
I suppose I could actually attempt the delete in a try block, and if it succeeds then immediately roll it back. That seems risky, but maybe just because I don't understand the ramifications. Anything I should be concerned with there?
Any provision of allowing User to delet records with User Rolw lesser then the Role of Record Owner, in ANY Future Releases?
Hi Sparky and folks,
We are currently in design / planning for a feature that would allow you to query a user's access to a record (maybe a set of records?) prior to rendering a detail page, list view, or related list. Recursion on the Role Hierarchy is just the beginning of the complexity on this, so we are looking to short-cut this chore for you.
You have been talking about the single-record access check, but would you also find it valuable to be able to pre-query a list of records? For example, if you were presenting a list view, you could send a list and an access level you want to check, then we send you back the access decision for that user for each record in the list. You could then use this to figure out whether to show Edit or Delete links next to each item in your list.
Bud Vieira
Sr. Product Manager, Platform (Sharing)
Salesforce.com
Hi all, this functionality is coming out in Spring '12, implemented as an API query in the form:
SELECT RecordId, [HasReadAccess, HasEditAccess, HasAllAccess, MaxAccessLevel] FROM UserRecordAccess
WHERE UserId = [single ID]
AND RecordId = [single ID] //or Record IN [list of IDs]
It returns either a 1/0 decision on the access level you have chosen, or if you choose MaxAccessLeve, the highest access level the user has to each of the records in the list.
@steve.stogner - as it is a query and not a new API verb, it should be accessible from the current SOAP API
As a quick test, I rebuilt the client jar from the 24.0 enterprise wsdl and tried:
SELECT RecordId FROM UserRecordAccess
but I'm encountering an INVALID_TYPE error.
[InvalidSObjectFault [ApiQueryFault [ApiFault exceptionCode='INVALID_TYPE'
exceptionMessage='sObject type 'UserRecordAccess' is not supported.'
]
row='-1'
column='-1'
]
]
Amazing, I'm surprised that SFDC is moving towards opening that up more. Historically, they've been very opposed to anything that even resembles reflection.
Hi Steve - that's puzzling. Just had one of our devs test it and working fine. Are you working from a clean build of Winter '12? The wsdl version is correct, anyway.
OK nevermind -- version 24.0 is working: the client code was indeed updated, but the test runner was passing the old version number in the salesforce URL. Thanks!
This is a fantastic new feature and is sure to save developers a ton of time. I am, however, getting some very unexpected results. I have a list of records that I own and I am using the following query:
List<UserRecordAccess> accessList = [SELECT HasDeleteAccess, HasEditAccess, HasReadAccess, RecordId FROM UserRecordAccess WHERE RecordId IN :myObjectIds AND UserId = :UserInfo.getUserId()];
This query is being run as the System Admin in a DE org (this user owns all records in that list).
The result of that query is saying that I have read access, edit access, but no delete access to these records. However, I can click the delete button on my Visualforce page and the record is deleted. It is also reporting that for some of the records, I have neither read access nor edit access, but I can view and edit them with no problems.
Has anyone experienced this inconsistency? Is there something that I am missing about how this object works?
Hi,
The way you are you writing the query looks correct. What is the object type / object types of the records in the query? Do you see this with only certain object types?
Thanks,
Helen
Helen,
I am querying on the Task object. I have noticed that if I pass a single record id, I get the correct result (read/edit/delete), but if I pass a list of Task IDs (including the task I got the correct result with), I get just read/edit back for the same task. I have not yet tried this with a different object, but will do so.
-Derrek
Hi Helen,
Similar to Derek's problem, I have noticed that RecordId IN [List<Id>] works, but RecordId IN [Set<Id>] does not, although it doesn't throw any type of error. Is this expected behavior?
It's not a big deal because I can convert from Set to List, but thought I would ask anyway.
https://success.salesforce.com/ideaView?id=0873A000000LmcJQAS