This is an interesting question because there is a sharing button on every record designed to provide this information. However, there are two shortcomings with using this button:
- The sharing button is disabled if org wide defaults are set to public read/write for an object
- It only tells you about sharing rows, not the object permissions contained in a user's profile or permission sets
As a result, it's possible to use this button to see which users have access to a record, only to find out that the user lacked the object permissions necessary to work with this record.
However, there is a workaround for these issues. You can create your own custom sharing button that will take both sharing and profile or permission set permissions into consideration, regardless of the sharing settings on the object.
For instance, we have a user, Doug Bitting. His profile grants him View Setup and Configuration permission and nothing else.
While on an account record, we can click on the sharing button to view which users have access to the record as long as accounts do not have their org wide default set to public read/write.
Viewing this sharing page tells us that our user, Doug Bitting, has access to the record even though he doesn't actually have the object permissions necessary to read the record.
By clicking on a custom button that I added called 'User Access', I can look up more information on what level of access a user like Doug actually has. This button launches a visualforce page with a custom apex controller in a new window.
In this case, when I look up Doug Bitting, I find out that he doesn't have access to the record.
I can add access to accounts through an accountRead permission set that has read on accounts.
Now when I use the custom 'User Access' button, I find that Doug actually has the read access I need him to have.
I built this solution with a custom button, visualforce page, and custom apex controller.
The button can be applied to any object where sharing and custom buttons are supported. Here's an example of the account button that I created. All that is required is to pass in the record Id in the URL when the page is called.
The apex code is pretty simple. The first part enables you to find a user using SOQL.
// query user from the User's Name input Text
public void queryUserName() {
// prevent SOQL Injection - oh no Mr. Bill!
String queryU = '%' + uName + '%';
// create query passing in queryLabel from input text in page
// this can easily be changed with other search parameters
// only return one user,may require narrowing search results
queryUser =
[SELECT Id, Username, Name, Title, Profile.Name, UserRole.Name
FROM User
WHERE Name like :queryU
OR Title like :queryU
OR Profile.Name like :queryU
ORDER By Name
LIMIT 1];
}
The second part enables you to use the user Id from the SOQL query and the record Id from the URL in the UserRecordAccess where clause to determine the user's actual access.
// Determine User Access based on the queryUser
// and the Id passed in through page reference in the URL
public void queryAccess()
{
// Store queryUser results in a new object
User u = [SELECT Id
FROM User
WHERE Id = :queryUser];
// Extract the Id from the user results
String uId = u.Id;
// UserRecordAccess using the userId and recordId
ura = [SELECT MaxAccessLevel,RecordId
FROM UserRecordAccess
WHERE RecordId = :ApexPages.currentPage().getParameters().get('Id')
AND UserId = :uId];
}
This solution works because the UserRecordAccess sObject which is available in the API. If you haven't seen this before, it's a great way to determine who has access to any record by combining profiles, permission sets, and sharing together.
The source code for the apex page and controller can be found on my github page: https://github.com/atorman/CustomSharingButton. Feel free to use it although there is some more work that I am planning to do so keep in mind that there is more to come.
While this doesn't address the original intent of the twitter conversation, it does address a couple of shortcomings with the Sharing button in particular.
error:Method does not exist or incorrect signature: [String].isUpdateable()
ReplyDeletepublic updatecheckbox{get; set;}
public String selecteduserId { get; set; }
public void checkFields()
{
list sobjectfields = new list();
Map fieldMap = schemaMap.get(selectedObject).getDescribe().fields.getMap();
for ( Schema.SObjectField sfield : fieldMap.values() )
{
schema.describefieldresult fieldresult = sfield.getDescribe();
searchresult = 'SELECT ' + fieldresult.getName() + 'FROM '+ selectedObject + where + id =: selecteduserid;
// System.runAs(selecteduserId) // You can only use runAs in a test method.
{
accesscheckbox = searchresult.isAccessible();----> again,i am getting an same error, if true means enable check
box in visualforce whether user have access permission..
updatecheckbox = searchresult.isUpdatable();
}
}
}
please help me code.....