Find your content:

Search form

You are here

Determine if a user has a license to package for sharing

 
Share

I'm trying to do some checks that insert a custom sObject share to determine if that sObject is set to 'Public Read Only', see this question: Determine org. wide security on an object

However, because I have to trap an DML exception about arbitrary 'sharing rules', I've been checking other users sharing records on these custom sobjects: because the current user always has 'ALL' access to their own records of that sobject.

However, if no other users have a record of the sobject in question than I need to create a temporary one in their name (create, update owner id, test-insert share, look for exception).

Except I need to know if I can determine which users in the particular org have a license to the product (so I can use their user Id) - and if not, do non-licensed users have access to the API to create sObject's that are part of my package, so that I can choose a user at random and create a temporary object for their user id!?

Example code:

public boolean determineIfProjectIsPublicReadOnly(){
        Schema.SObjectType targetType = Schema.getGlobalDescribe().get('Project__share');
        sObject testProjectTaskShare = targetType.newSObject();
    List<Project__c> projects = [SELECT Id,OwnerId FROM Project__c WHERE OwnerId != :UserInfo.GetUserId() LIMIT 1];

    if(projects.size() == 0){
        return true;            
    }
    else{
        testProjectTaskShare.put('AccessLevel','Read');
        testProjectTaskShare.put('UserOrGroupId',UserInfo.getUserId());
        testProjectTaskShare.put('ParentId',projects[0].Id);

        Database.SaveResult sr = Database.insert(testProjectTaskShare, false);
        if(sr.isSuccess()){
            // Public Read Only for Project_Task__c
            return false;
        }
        else{
            Database.Error err = sr.getErrors()[0];
            system.debug(err.getMessage());
            if(err.getStatusCode() == StatusCode.FIELD_INTEGRITY_EXCEPTION  &&  err.getMessage().contains('AccessLevel')){
                return true;
            }
                 //this error is thrown attempting to insert share record where one already exists for the current user 
            else if(err.getStatusCode() == StatusCode.FIELD_FILTER_VALIDATION_EXCEPTION){
                return false;
            }
            else{
                return false;
            }
        }
    }

Attribution to: jordan.baucke

Possible Suggestion/Solution #1

Short answer: You can determine if the current user has access to a given namespace (your package): http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_userinfo.htm

To check for accessibility, describe the sObject and check isAccessible, updateable, writeable, etc. You generally don't need to know if no other users have access - only if the running user has access. After all, a properly-set security model gives access where needed without crating duplicate records of an object.

That being said, I'm not sure that from your question you're necessarily developing a package in the best possible way. We don't refer to "instances" of sObjects, generally; the word is "record." I'm sure you've gone through the documentation thoroughly, but perhaps looking at the ISV part of the developerforce website will help.

Sorry to be harsh; I just think there are ways to architect your app so you can avoid this issue and not have to solve it.


Attribution to: DavidSchach

Possible Suggestion/Solution #2

With all the issues you raised your best bet here might be going outside of apex and getting this via the metadata REST api. The CustomObject.SharingModel property has exactly what you need.

The only thing to consider is whether this callout needs to run whenever your page loads to make sure the metadata your app has is up to date or if you can get away with running it on a scheduled basis and clean up any "sharing hierarchies" that the user made that no longer make sense.


Attribution to: Greg Grinberg
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/1283

My Block Status

My Block Content