Thursday, August 4, 2016

Inserting records with inactive owners or inactive user lookups

Recently I had to upload records into Salesforce from a legacy system. The catch here was that the records were for an managed package object and the records were owned by people who were no longer with the company. The records were being brought in for historical completeness of the Salesforce system.

There were a few interesting questions which were raised by this
  1. Can we upload a record owned by an inactive user?
  2. Can we upload records which reference inactive users in lookup fields?
  3. since we are inserting managed package object records,
    • should the record owner need a managed package license?
    • should the users referenced in the lookup fields need a managed package license?

Note: this is different from the newly released Winter 16 feature - "Set Audit Fields and Update Records with Inactive Owners [docs.salesforce.com]". That talks about Updating records owned by inactive users not inserting them.

I created a sample data load CSV and tried these out on my developer sandbox. 

I found -

  • Records cannot be inserted with inactive users as Owners. I got the following error from Salesforce when I tried to insert a record in sandbox - Operation Performed With Inactive User <15 char user ID> As Owner Of <15 char record ID>
    • It was decided that we would insert the records using a dummy Migration User owner record.
  • Records can have inactive users referenced in lookups. I tried to insert a record with active Owner, but with an inactive user referenced in a field on the record. This worked ok.
  • Inactive users do not need a managed package license to be in lookups. For the next trial, about whether inactive users require a managed package license to be in a field reference, this is the scenario: There is an inactive user A. There is a managed package object B with a text field text__c and a lookup field to user, say operator__c. Can we load a record like this one into object B though A is inactive and doesn't have the managed package license ?
Text__c,operator__c
'Test',15 character id of A.
The answer is yes. You can have inactive users in lookup references. Also the inactive user will not need a managed package license.
  •  Inactive users can own records of managed package objects without requiring a managed package license. Since we cannot load records with inactive user owners, the question of having a managed package license doesn't matter for data load. But I decided to try it out in a different scenario: say a record was created by an active user having the managed package license. Later the user was made inactive since the user left the org. Should the user record still have a managed package license or can we revoke it?
Brief background here: Inactive users in a Salesforce org assigned to a package license will be counted as an active user of a managed package in the licenses section. This article [help.salesforce.com] talks about it.

Obviously we don't want managed package licenses tied to inactive users. We want them to be freed up for active actual users.

I found that inactive users can own records of managed package objects. They don't need to have the managed package license. Salesforce support confirmed this.

Hopefully this helps someone!

Reference:



Wednesday, May 25, 2016

Search Salesforce Setup quickly

Here's a note from the Salesforce documentation on a shortcut link to search in the setup for approval
items, assignment rules, custom objects and fields, custom profiles, permission sets, workflow items, users, groups, queues, email alerts and templates.

Note

  • this is different from the global search at the top of every Salesforce screen which only searches records not setup configuration items
  • this only works if Advanced Setup Search is enabled.



https://<instance>.salesforce.com/ui/setup/SetupSearchResultsPage?setupSearch=<your search term here>

Examples are:
https://na15.salesforce.com/ui/setup/SetupSearchResultsPage?setupSearch=anil

Or for multiple keywords put a %20 in place of a space
https://na15.salesforce.com/ui/setup/SetupSearchResultsPage?setupSearch=installed%20pac

Also, for developers there is a Chrome extension - Salesforce advanced Code searcher[linked in the references] which enables searching for apex and VF code. This extension is awesome in finding the apex or VF you need and quickly jumping to it.


Reference:
Searching Setup with Advanced Setup Search [help.salesforce.com]
Salesforce advanced Code searcher[chrome.google.com]



Friday, April 29, 2016

Playing with Salesforce Custom Settings (List based)

Querying Custom Settings

While working with Custom Settings in Apex, it is possible to use both Salesforce provided instance methods to access the Custom Settings or to use SOQL to query the data in the Custom Setting.

The Salesforce provided methods are well known and are documented here - Custom Settings Methods [developer.salesforce.com]

Using SOQL to query the Custom Setting is possible since the Custom Setting is similar to a Custom Object. Salesforce does not recommend this since

  • this will not use the application cache
  • will count towards your SOQL query limit
Try this
  • Create a custom setting with one field
  • In the Developer Console anonymous apex window, query your Custom Setting in a loop through SQL to see if you can hit the governor limit [NOTE: do not use SOQL in loops in your production code - I'm just trying this to make a point]


  • Now try retrieving the Custom Setting data using the instance methods - no SOQL is used.
List<anilc__Testing__c> testData2;
for (Integer i=0;i<101;i++) {
    testData2 = anilc__Testing__c.getAll().values();
}



Custom setting field type mapping

While researching this post, I was trying out a lot of the allowed fields in a Custom Setting and querying them in Apex. One of the things I was looking at was the field types - what do they map to in Apex? I didn't see this documented anywhere, so I'm listing them here, after trying them out



Custom Setting Field Type Apex field type
Currency Decimal. You can use Double as well
Date Date
DateTime DateTime
Email String
Number Decimal. You can use Double as well
Percent Decimal. You can use Double as well
Phone String
Text String
TextArea String
URL String
Checkbox Boolean





References

  1. Custom Settings Methods [developer.salesforce.com]





Friday, April 15, 2016

Salesforce Integration notes

Create and use an Integration user with Admin profile

This is so that you have an integration user independent of your actual users. If you were to use an actual user, if and when they leave or change roles in your company, you'll have to configure another user. Don't do this and instead save yourself the trouble and create a user named Integration User instead. See reference 1 for more information about this.

You can also create one more user named Data Migration with the same configuration and use this for all data loads into Salesforce. This allows you to figure out if the record was created (or updated) by someone doing a data migration or was touched through external integration

Finally create one more similar user named Code Migration. This allows your deployment team to login to production and deploy code without having to reuse or know the Integration or Data Migration credentials.

Bypass Triggers for this Integration or Data Migration user

Turning off triggers in production is a pain and requires a changeset deployment to turn off. Instead while developing the trigger itself, add code to bypass it for the Integration and Data Migration users. This is something you'll need to be careful of, since in some situations you might need the triggers to fire. So think about this carefully

Bypass validation rules and workflows for this Integration or Data Migration user

When doing a data load or an API integration, you may not want any validations to occur or workflows to run. Add these users as a check in the validation rule and workflow so that the validation rule and workflow gets bypassed if the user name is Integration or Data Migration

Make Contacts owned by the Integration user

Contacts are normally owned by the user who created them. This causes an issue when the person leaves the organization which makes the contact uneditable (if org wide default is private or public read only). (This problem - editing records of inactive users - is solved in Winter 16 - see reference 3 below). Also record owners are able to delete contacts they own. To prevent this, write a workflow rule which changes the contact owner to the Integration user immediately on contact creation. Then share the contact (through criteria based sharing settings) with only the roles which need access

References


Thursday, April 14, 2016

Setting up single sign on (SSO) with Okta and Salesforce Community

Problem

Consider this: you have a salesforce instance (sales or service cloud) where single sign on (SSO) was already setup. Later when you create a community, you want to reuse the same SSO configuration done in Salesforce without having to create a multiple SAML configurations in Salesforce.

Unfortunately, salesforce documentation isn't very clear on how to do this when you already have SSO setup for the main instance. Hopefully these steps will help.

I had done this integration with Okta and Salesforce, so the steps below reference Okta as the Identity Provider (IdP). But the overall process should be the same

Prerequisites


  1. Your main instance (sales / service cloud) is already configured with SSO
  2. You have a few users setup with Community profiles/permissions in Salesforce
  3. install the SAML Tracer plugin in Firefox. You'll need this to help debug if there are any issues later

Step 1 : Prepare information for your IdP

In Okta, you'll need to create a new application integration with Salesforce for the community. You cannot use the existing Okta configured application for this. There is no way around this - while there will be a single SSO configuration in Salesforce, Okta will have two - one for the main Salesforce ServiceCloud and the other for the Community Cloud.

You'll need to provide information from your existing SSO setup in Salesforce. 

In Salesforce, Go to Setup-> Security Controls->Single Sign-On Settings

Okta needs the following values from your Salesforce instance
  • For the Okta Single Sign On URL & Recipient URL & Destination URL settings : provide your Community URL appended with the saml parameter from current instance. More on how to create this is below
  • For the Audience Restriction or Entity ID : Use the entity parameter from your Salesforce Single Sign On settings. Normally this is https://saml.salesforce.com

Other settings for Okta
  • Name ID Format :     Unspecified
  • Response :     Signed
  • Assertion Signature :    Unsigned
  • Assertion Encryption :     Unencrypted
  • SAML Issuer ID: Use the issuer parameter from your Salesforce Single Sign On settings

1a: generate the community SSO URL



The first part of the SSO URL will be either of the following
  • In production it will be the community domain you have setup with /login/ appended at the end – say, https://something.yourcompany.com/login/
  • In sandboxes, it will be the Force.com community site URL with /login/ appended at the end – https://yourcommunity.instance.force.com/login/. You can find the Force.com community site URL by going to Setup->Develop->Sites.
NOTE: The Site URL will show as http in the Salesforce Sites page (screenshot above), but you'll have to provide the https link.

The second part of the SSO URL will be the saml parameter from your existing SSO configuration in Salesforce
  • Go to Setup-> Security Controls->Single Sign-On Settings
  • Copy the saml= part of the Salesforce Login URL. This is what needs to be appended to the Community Login URL




Finally you'll get a URL which looks like this https://yourcommunity.instance.force.com/login/saml=somestring

Provide this to Okta as the Single Sign On URL

Step 2: Create the new application in Okta and add users to the new application in Okta

This step is done in Okta and will not be covered here. It's anyway specific to the IdP you choose.

Step 3: Test

Test the new SSO by going to the Okta Dashboard and logging in as one of the users assigned the application and clicking on the new application tile. Okta should drop you into the Community without having to relogin

Step N : Debug

This one is marked Step N since you'll be doing this multiple times :)


  1. In case there are issues, open up firefox and open the SAML Tracer extension
  2. Run through the login scenario and capture the SAML request. SAML Tracer helpfully marks this with a big SAML indicator on the right of the capture window
  3. copy the SAML post sent from the browser to SFDC and run it through the SAML Validator provided by SFDC. To use the SAML validator, go to Setup-> Security Controls->Single Sign-On Settings and Click on SAML Assertion Validator button.
  4. Paste in the SAML text and click validate
  5. The SAML Validator will provide a list of failures in red. 
    • First look if the identity is being passed correctly in the SAML assertion to Salesforce from the IdP
    • Next check if Salesforce could read the certificate passed from the IdP - this should not be an issue since the existing SSO configuration in Salesforce is being reused, so the certificates should already be installed in Salesforce




References


Saturday, April 2, 2016

How to setup your own domain for Community in Salesforce

Step 1: Register your domain name

Register your domain name in DNS and alias (CNAME) it to your Organization's site. This is done outside of Salesforce.

For example: if your domain is www.samplecommunity.com, you'll have to register it with a domain name provider and add a CNAME to www.samplecommunity.com.<insert your Salesforce siteID here>.live.siteforce.com

You'll find the Salesforce siteID by going to Setup->Domain Management->Domains

Note: Custom domains can only be used with production environments not sandbox


Screenshot of Domain setup


Step 2: setup the domain in Salesforce

Note: First check that the domain name you've created has propagated over the internet by doing a nslookup of the domain name from your local machine
Then in Salesforce, go to Setup->Domain Management->Domains
Enter the new Domain name you've created in the Domain Name text field. You don't need a certificate at this time.
Click Save.

Step 3: Obtain a SSL certificate for your domain

3a: Generate a Certificate Signing Request (CSR) and send it to your Certificate Authority (CA)

  • Go to Setup-> Security Controls-> Certificate and Key Management.
  • Click on Create CA-Signed Certificate and enter the following information. Click on Save
Common Name=<your domain name>
Department=<your department name>
Company=<your company's legal name>
City=<Your company's city>
State=<Your company's city>
Country Code=<two-letter ISO code for the country where your organization is located>
Key size=<either 2048 or 4096 bit - depending on what your CA supports>
Email Address=<preferably provide the email address of your salesforce administrator>

In the next screen, click on Download Certificate Signing Request. Provide this CSR file to the CA

3b: import the certificate into Salesforce and apply it to your domain

  • Once the certificate has been obtained from the CA, go back to Go to Setup-> Security Controls-> Certificate and Key Management and click the record you created the CSR for in Step 3a
  • Click on Update Signed Certificate to apply the new certificate
  • On the same screen, add the certificate to the domain by clicking on Add Domain

Step 4: Configure the domain to point to the community  

Note: your Community must be Published.
Go to the domain setup in Step 2. Click on Add Custom URL and enter the Community URL and save.

Step 5: Test

In a browser window, go to your domain name. The landing page of your community should show up!

References


  1. Configure a Custom Domain for Your Community[developer.salesforce.com]
  2. About Salesforce Certificates and Keys [help.salesforce.com]
  3. Certificate signing request [wikipedia.org]


Tuesday, February 16, 2016

Setting up sharing in Salesforce Communities

Requirement

How to enable some Community Users in an account to view and edit any Case created by anyone in their Account. Also, provide a way to group Community Users together so that Cases are editable only within the group

In Salesforce terminology this breaks down to:
  1. Within an Account, how to group users together for shared case access?
  2. How to allow some Customer Community users in an Account to see and edit all Cases across all groups (defined in point 1) above?
  3. Is it possible to control type of access (read/write) by user?

Salesforce Community Capabilities and constraints (aka what do we have to work with?)

  • Salesforce has a way to allow certain users to have read/write access to Cases irrespective of who filed them using the Community Plus license (see Salesforce documentation: Grant Super User Access to Customer Users in Your Community)
  • Case sharing model OWD is set to Private (internal and external)
  • Role based and Apex Sharing is not allowed for Customer Community license (see Salesforce documentation: Communities User Licenses)
  • Default owner is the person creating the Case
  • Only Contact or Account level sharing is allowed through Sharing Sets configured in community settings (See Salesforce documentation: Sharing Set Overview)
  • There is no way currently to control read or read/write access by community user :(

Solution

  • Setup an Account Hierarchy (You should already have this :)
  • Add a Parent Account attribute to the Contact (You might already have this too)
  • Assign the Case tab to your portal
  • Identify users who need to have access to all Cases filed under their Account (requirement 2 above)
    • Assign these users a Customer Community Plus license. Also create a permission set with one permission - Delegated External User Administrator - and assign it to them. 
  • Setup Sharing Sets
    • Go to Setup->Customize->Communities->Communities Settings
    • In the Sharing Sets section, click on New to create a new Sharing Set named "Share case within Account"
    • Select "Customer Community User" as the profile this Sharing Set will apply to
    • Select "Case" as the object this Sharing Set will apply to
    • Set the access rule to Grant Access where User.Account matches Target Case.Account, give Access Level Read/Write. (You can also give Read only here)
  • Now Contacts within the same Account will be able to view each others cases in the Community. (requirement 1)
    • Contacts under the same Parent Account, but not in the same Account will not be able to see Cases of Contacts in other Accounts
    • Example: Parent Account is A and there are two child Accounts B and C. 
      • Contacts belonging to B will see cases of other Contacts belonging to Account B.
      • Contacts belonging to C will NOT see cases of other Contacts belonging to Account B
      • Only Contacts belonging to either B or C having the Customer Community Plus will be able to see all Cases belonging to Account B and Account C



Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Tuesday, February 9, 2016

When was my sandbox refreshed

One of the questions I get once in a while from my Salesforce users is "when was sandbox refreshed". It gets asked rarely enough that I forget how to check it and often enough to that I need to remember the steps :)

On your Salesforce production instance, go to Setup->Data Management->Sandboxes

Over there, look for your Sandbox name and you'll be able to see when it was last refreshed.