Thursday, January 24, 2019

DemandTools and Salesforce....Login Setup Isses

Got ready to use a new tool called DemandTool but could not get past the Login page.

It had 2 option a) API login and b) OAuth login.

Going with the API Login, tried using my UID/PWD and just could not get thru.

I found that the URL needs to be the URL found in the salesforce Partner WSDL file.

To generate the Partner WSDL file go to Salesforce Setup/API --Generate Partner WSDL.
Open the file and look for section which has soap:address location.

Copy the URL.

Thursday, January 17, 2019

Migrating Chatter data from one Org to Another....

Had a requirement to migrate Chatter data since we are migrating our Backlog Tool to Agile Accelerator in Org B from a Salesforce based vendor tool which resided in Org A.

Typically, for custom objects, if feed tracking is on, <object>_feed will be the object under which feed related records will be found.
Standard Objects have the feed in objects like AccountFeed, CaseFeed and so on.

Data can be exported using Dataloader.

To import, for custom objects, you need to import it back into an object called FeedItem and that should allow you to see the imported records.

For standard objects, you can import it back into it's own object i.e. AccountFeed, CaseFeed and so on.

Wednesday, January 16, 2019

Reporting Errors...

Team ran into the following issue while building reports:

a) Error: This report can no longer be edited or run. Your administrator has disabled all reports for the custom object, or its relationships have changed.

b) The filter logic references an undefined filter

On reviewing the setup, it was found that users were not having read access to the object, once the read access was provided that resolved error a.

The second error b) was resolved by providing field access to all the fields on the report.



Wednesday, January 2, 2019

SSO Integration: Salesforce Azure setup-Writing UserRegistration Class

There are 2 ways of integrating Salesforece and Azure.

One way seems to be from the Azure side, please see link below

https://docs.microsoft.com/en-us/azure/active-directory/saas-apps/salesforce-tutorial

This also does automatic user provisioning.

The other way is from the Salesforce side, please see link below for the steps:

https://help.salesforce.com/articleView?id=sso_provider_azure.htm

One of the steps is to write a user registration class. Follow the steps to create a sample class, once the sample class is created you need to modify it per your needs and depending on the data provided by the SSO provider in this case Azure.

//TODO:This autogenerated class includes the basics for a Registration
//Handler class. You will need to customize it to ensure it meets your needs and
//the data provided by the third party.


global class AzureSSOUsrCheck implements Auth.RegistrationHandler{
 
       static global boolean canCreateUser(Auth.UserData data) {
         system.debug('canCreateUser');
          system.debug('canCreateUser-identifier' + data.identifier);
           system.debug('canCreateUser-username' + data.Username);
     
              //Check if User exists - if not then create user else update user
              List<User> U = [SELECT Id, Username FROM User where Email=:data.email and IsActive=true LIMIT 1];
               if (U.size() > 0 ){
                   system.debug('canCreateUser-false');
                   return false;
               }
            system.debug('canCreateUser-true');
                   return true;
           
             
         }
 
   static global User createUser(Id portalId, Auth.UserData data){
            system.debug('createUser-data.email' + data.email );
            system.debug('createUser-data.firstName' + data.lastName + data.firstName );
            system.debug('createUser-data.username' + data.username );
            if(!canCreateUser(data)) {
    //Returning null or throwing an exception fails the SSO flow
    system.debug('Returning NULL from createUser' );
                User u1 = [select Id from User where email=:data.email and IsActive=true LIMIT 1];
     return u1;
  }

     
        //User u = new User();
            //Profile p = [SELECT Id FROM profile WHERE name='Standard User'];
            //u.username = data.username + '@hexagon.com' + '.slsmktg';
            //u.email = data.email;
            //u.username = 'deepak.balur@hexagon.com.slsmktg';

        List<User> UsrVal = [select Id from User where email=:data.email and IsActive=true LIMIT 1];
     
           if (UsrVal.size() > 0){
               return UsrVal[0];
           } else {
               return null;
           }
         

        }

       static global void updateUser(Id userId, Id portalId, Auth.UserData data){
    system.debug('updateUser-data.username' + data.username + data.email );
            system.debug('updateUser-data.firstName' + data.lastName + data.firstName );
            system.debug('updateUser-data.username' + data.username );
         
            User u = new User(id=userId);
            //u.username = data.username + '@hexagon.com';
            u.email = data.email;
            u.lastName = data.lastName;
            u.firstName = data.firstName;
            String alias = data.username;

            update(u);
        }
}

Execution Flow:

When the instance URL is typed in user is presented with the option of logging in via Azure SSO credentials, once the credentials are entered the createUser method is executed.
If the user does not exist then an error is returned to the user.

If the user exists then the updateUser will be executed and fields updated as specified in the method.

Please note; the requirement was not to create users on the fly and hence the createUser method only looks if the user exists or not.

Auth.UserData is a salesforce provided class; it contains the following fields
String identifier, String firstName, String lastName, String fullName, String email, String link,String userName, String locale, String provider, String siteLoginUrl, Map<String,String> attributeMap

When the interaction happens with Azure these fields can be passed from Azure.
For this integration, I was not the Azure Admin.

Hope this helps.