User Sharing: Control Who Sees Who in Your Organization

User Sharing offers more control over who can see and collaborate with each other among your internal and external users. With Winter '14 all new organizations have User Sharing enabled. Learn more.

As your organization grows and becomes more social, you might want more control over who can see and collaborate with each other among your internal and external users. User Sharing helps you manage your visibility requirements with an organization-wide default for the user object, sharing rules, and manual sharing. With Winter ’14, all new organizations have User Sharing enabled. Existing organizations can contact to enable this feature.

Watch the video to learn more about User Sharing!

How can User Sharing work for your organization? Maybe you are a manufacturer who needs to include all dealers in your organization while still maintaining a silo approach among your dealers and internal users. You can set the organization-wide defaults for the user object to Private. Then, use sharing rules or manual sharing to open up access among internal groups of users who need to see and collaborate with each other. You can also open up access among groups of dealers who need to see and interact with each other. Furthermore, you can enable collaboration between internal sales representatives with their respective dealers. Additionally, you can assign the “View All Users” permission to users who need to see or manage all users in the organization.

In a nutshell, what you know about sharing for standard and custom objects now applies to the user object. For example, you can create a manual share with Apex using the following sample code. Note that Apex sharing reasons is not supported.

public class UserSharing { 
    public static boolean manualShareRead(Id recordId, Id userOrGroupId) { 

    // Create a new sharing object for the User object. 
    UserShare userShr = new UserShare(); 

    // Set the ID of record being shared.
    userShr.UserId = recordId;

    // Set the ID of user or group being granted access. 
    userShr.UserOrGroupId = userOrGroupId; 

    // Set the access level.
    userShr.UserAccessLevel = 'Read';

    // Insert the sharing record and capture the save result.
    // The false parameter allows for partial processing if multiple records passed into the operation.
    Database.SaveResult sr = Database.insert(userShr,false); 

    // Process the save results.
        return true; 
    } else { 

        // Get first save result error. 
        Database.Error err = sr.getErrors()[0]; 

        // Check if the error is related to trivial access level.
        // Access levels that are equal or more permissive than the object's default access level are not allowed.

        // These sharing records are not required and thus an insert exception is acceptable.
        if(err.getStatusCode() == StatusCode.FIELD_FILTER_VALIDATION_EXCEPTION &&
            err.getMessage().contains('AccessLevel')) {
            return true; 
     } else{ 
            // Indicates failure.
            return false; 

To illustrate, running the following code creates a manual share that shares the user whose Id is 005D0000001Qi5c to the user or group whose Id is 00GD0000001Gu79.

UserSharing.manualShareRead('005D0000001Qi5c', '00GD0000001Gu79');

Additionally, keep in mind that Visualforce standard controllers run in the user’s context and now respect User Sharing. If you would like access to user information in your email templates, use a custom controller, which defaults to running in the system context without sharing.

Related Resources