8

Situation:

  • We are doing SOAP API (custom made apex webservice) calls to service using admin user.
  • Those calls do search on Accounts (millions of records, search mostly on Name field)
  • Account are set Private (org-wide) with many sharing rules and hierarchy sharing
  • Calls pass userId (or email) of user in whose context result should be returned

Is there a way to apply sharing restrictions to the query I'm doing?

I have tried following:

  • Use UserRecordAccess but it only allows to query for 200 records which is definitely not enough
  • Use AccountShare table but it contains Groups for Role and Subordinates, which doesn't have any members in GroupMember table that means I would have to query for all the roles in role hierachy (which we have over 1000) also this table doesn't include sharing above in the hierarchy

Any ideas?

  • how are you accessing the API? are you hitting from a Web Page or through a client application? – Seb Wagner Jun 25 '14 at 14:04
  • It's SOAP API (custom made apex webservice), edited the question – Łukasz Skrodzki Jun 25 '14 at 14:08
1

The only way to automatically enforce sharing is to log in as the user whom the query should be performed as, not as an admin user. As you've noted, using UserRecordAccess is exceptionally limited, so you'd have to perform many queries based on an initial query result. Assuming the account query returned less than about 20,000 rows, you could probably use UseRecordAccess without running out of query statements (and if it's more than that, you should consider narrowing the results anyways).

| improve this answer | |
  • Without going into too much detail on our org this is not suitable unfortunately. There are many accounts with similar parameters but each of them is visible to different people. Therefore the first select may return a lot of records. And doing a 200 selects to UserRecordAccess would be a very big performance hit. – Łukasz Skrodzki Jun 26 '14 at 7:34
1

we ve had recently some head aches around how to determine access for a certain user against million of records where we could not rely on the native sharing capabilities. in the end we went with a different approach which wont fit here, but here are two possible options I see for your situation:

Batch Search
Write a piece of code - I suspect this might have to reside client side due to data volume and timeouts - and to run the search against the entire data set. in the next step loop through the results in chunks of 200 (due to the 200 records limitation for UserRecordAccess) and query the UserRecordAccess records for the record ids
https://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_userrecordaccess.htm

Impersonation
Assuming you have an Identity Provider that allows you to generate a SAML response to login as the user

Using oAuth Web SSO SAML Assertion you can obtain an access token for the user you'd like to run the query for and then run the query through the API directly https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

| improve this answer | |
  • For your first proposal I have answered above. For the impersonation this is something we are looking in parallel into. What I'm trying to discover here is fallback plan if impersonation wont be available. – Łukasz Skrodzki Jun 26 '14 at 7:35
  • @ŁukaszSkrodzki what do you mean with answered above? are you referring to the 200 UserRecordAccess records limitation? updated my answer to make it a bit clearer – Seb Wagner Jun 26 '14 at 7:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.