function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
MonisfdcMonisfdc 

Custom JIT Handler- How to update inactive user to active

Hi, 
I have a custom JIT handler that will create a user record in SF when the user tries to log in using SSO. My requirement is to update the inactive user to active when the user logs in. I tried doing it but it's not working as the user is inactive. It says "unable to verify identity" in the portal and "user is inactive" in login history status. It's obvious that the user can't log in as the status is inactive. But any idea how can I implement this? 
Rohit B ☁Rohit B ☁
Yes, you can do this in your custom JIT handler. I've done the same.
You might be missing something. Could you please paste your code so I can look into it and let you know what have you missed?

Thanks,
Rohit B
MonisfdcMonisfdc
Hi Rohit,

Thanks for your reply! I attached my code. Please let me know what should I change. TIA!
global class JustInTime_v2_Handler implements Auth.SamlJitHandler {
    private class JitException extends Exception{}
    private String federationIdentifier;
    private String defaultUserNameSuffix;
    private String loginPath;
    private String loginViaAccount;
    private String pId;
    private String errorMsg;
    private Id userProfileId;
    private User setupNewUser(Contact c, String possibleNewUserName, Id userProfileId, String umichEmail, String friendAccountEmail){        
        
        User newUser = new User();        
            newUser.Username = possibleNewUserName;
            newUser.Reset_Password_On_Create__c = true;
            newUser.FederationIdentifier = federationIdentifier;
            newUser.FirstName = c.FirstName;
            newUser.LastName = c.LastName;
        
        if( friendAccountEmail != null ) { 
            newUser.Email = friendAccountEmail ; 
        }            
        else if( umichEmail != null ) { 
            newUser.Email = umichEmail; 
        }   
        if( c.MailingPostalCode != '' && c.MailingPostalCode != null ) {
            newUser.PostalCode = c.MailingPostalCode ; 
        }            
        if( c.MailingCountry != '' && c.MailingCountry != null ) {
            newUser.Country = c.MailingCountry ; 
        }   
        Integer i = Integer.valueof(Math.random() * 1000000);
        String randomInt1 = '99';
        if( String.valueof(i).length() >= 2 ){
            randomInt1 = String.valueof(i).substring(0,2); 
        }              
        String firstNameSubstring =  (c.FirstName + c.FirstName + c.FirstName).substring(0,4); // triple up in case length is too short
        String lastNameSubstring = (c.LastName + c.LastName + c.FirstName).substring(0,4);  // triple up in case length is too short
        newUser.CommunityNickname = lastNameSubstring + firstNameSubstring + randomInt1;  
        User currentUser = [SELECT LocaleSidKey, LanguageLocaleKey, TimeZoneSidKey, EmailEncodingKey FROM User WHERE Id=:UserInfo.getUserId()];  // per Andre: it is okay to set time zone as anything since Fonteva will handle time zone in the portal.  language can be default english.
        newUser.LocaleSidKey = currentUser.LocaleSidKey;
        newUser.LanguageLocaleKey = currentUser.LanguageLocaleKey;
        
        String alias = '';
        String randomInt2 = String.valueof(i).substring(0,1);
            
        if(c.FirstName == null) {
            alias = randomInt2 + c.LastName + 'abc';
        } else {
            alias = randomInt2 + newUser.LastName + newUser.FirstName ;
        }
        
        if(alias.length() >= 5) {
            alias = alias.substring(0, 5);
        }
        
        newUser.Alias = alias;
        newUser.TimeZoneSidKey = currentUser.TimeZoneSidKey; 
        newUser.EmailEncodingKey = currentUser.EmailEncodingKey;

        /*
         * If you are updating Contact or Account object fields, you cannot update the following User fields at the same time.
         * If your identity provider sends these User fields as attributes along with Contact 
         * or Account fields, you must modify the logic in this class to update either these 
         * User fields or the Contact and Account fields.
         */
         
        newUser.isActive = true;
        newUser.contactId = c.id;
        newUser.profileId = userProfileId;

     return newUser;   
    }

    private User handleJit( boolean fromCreateMethod, String ProfileName,  Map<String, String> attributes) {  
                                     
        User u2Return;
            
        
        if( fromCreateMethod) {
        
        
            // GET PROFILE ID
            List<Profile> profile = [Select Id From Profile Where Name =:ProfileName limit 1];        
            if( profile.isEmpty() ){ 
                throw new JitException ('Unable to create a user account.  The profile ' + ProfileName + ' cannot be found.');   
            }    
            userProfileId = profile[0].id;        

            // FIND EXISTING CONTACTS 
            Contact c = getMatchingContact();  
            
            if( c != null ) {
                
                String umichEmail = (c.AAUMCustom__UMich_Email__c != null? c.AAUMCustom__UMich_Email__c : c.OrderApi__Preferred_Email__c) ;
                String friendAccountEmail = c.AAUM_Friend_Account_ID__c;
                
                String newUserName = buildNewUserName(umichEmail, friendAccountEmail);
            
                // FIND ANY EXISTING PORTAL USER RECORD FOR THE CONTACT.  
                List<User> uList = [ Select id, userName, Profile.Name, ProfileId, FederationIdentifier, isActive, ContactId 
                                     From User Where  ContactId =: c.id ]; 
                                     
                // if no existing duplicate user record found
                if ( uList.isEmpty() ){
                    u2Return = setupNewUser ( c, newUserName, userProfileId, umichEmail, friendAccountEmail);
                    updateContact(c);
                } 
                  else{
          if(uList[0].isActive==true){
          throw new JitException('Unable to create a user account.  One already exists, but it may need to be re-configured');
                 }
                }        
               }                                        
            }          
     return u2Return;   
    }
    
    private void handleuser(boolean create, user u, Map<String, String> attributes){
        if(!create){
            if (attributes.containsKey('User.IsActive')) {
            String IsActiveVal = attributes.get('User.IsActive');
                If(IsActiveVal=='false'){
                    u.IsActive=true;
                    update u;
                }
             }
         }
     }
    private Contact getMatchingContact(){
        Contact theContact;
        List<Contact> matchingContacts = [Select Id,AAUMCustom__Ext_Alumni_ID__c,AAUMCustom__UMich_Email__c,LastName,FirstName,Name,
                                          MailingPostalCode, MailingCountry,AAUM_Friend_Account_ID__c,OrderApi__Preferred_Email__c
                                          From Contact Where AAUMCustom__Ext_Alumni_ID__c =: federationIdentifier And AAUMCustom__Ext_Alumni_ID__c != null ];
                
        if(  matchingContacts.isEmpty() ){
            throw new JitException ('Unable to create a user account for you.  Reason: No Contact Record is found matching your Alumni/Member ID');
        }
        else if( matchingContacts.size() > 1 ){
            throw new JitException ('Unable to create a user account. Reason: Multiple Contact Records found matching your Alumni/Member ID. Further verification steps needed.');
        }
        else {
            theContact = matchingContacts[0];           
        }       
    return theContact;
    } 
          
    private String getUserNameSuffix(){    
        String orgId = UserInfo.getOrganizationId();
        if( orgId.startswith('00D630000009Dob') ){ return '.uat';
        }else if ( orgId.startswith('00D1a000000KDXx' )) {  return '';  // prod                   
        }else if ( orgId.startswith('00D630000009GiM' )) {  return '.devPartial';
        }else if ( orgId.startswith('00Dg0000006HjcC' )) {  return '.QA';
        }else if ( orgId.startswith('00D0q0000000NVf' )) {  return '.uat';
        }else return '.otherSandbox';            
    }
    
    private void updateContact(Contact c){
   
    }
    
    private String buildNewUserName(String umichEmail,String friendAccountEmail){
        defaultUserNameSuffix = getUserNameSuffix();
        String newUserName = '';

        if( friendAccountEmail != null && friendAccountEmail.length() > 0 ){
            newUserName = friendAccountEmail + '.asfportal' + defaultUserNameSuffix;            
        }        
        else if( umichEmail != null && umichEmail.length() > 0 ){     
            newUserName = umichEmail + '.asfportal' + defaultUserNameSuffix; 
        }
        else{
            throw new JitException('Unable to create a user account.  System cannot find a valid email address on your Contact record');
        }   
        system.debug(logginglevel.error,'username: ' + newUserName);
    return newUserName;    
    }
      
    global User createUser(Id samlSsoProviderId, Id communityId, Id portalId,
                           String federationIdentifier, Map<String, String> attributes, String assertion) {
        User u ; 
        parseInfo('CreateUser', communityId, portalId, federationIdentifier, attributes );
        if( pId != null ){            
            u = handleJit(true, 'Fonteva Customer Community User', attributes);                    
        }else {
            throw new JitException('The login link that routed you here is for staff members with an active Account.  It doesn\'t look like you have an active Staff Account.');
        }

    return u;
    }
    
    global void updateUser(Id userId, Id samlSsoProviderId, Id communityId, Id portalId,
        String federationIdentifier, Map<String, String> attributes, String assertion) {
    User u = [SELECT Id, FirstName, ContactId FROM User WHERE Id =: userId];
       
              handleuser(false,u,attributes);    
        } 
   
   private void parseInfo(String methodCalled,Id communityId, Id portalId,String federationIdentifier,Map<String,String> attributes){
       pId = (communityId != null? communityId : portalId);
       this.federationIdentifier = federationIdentifier;
       loginPath = 'Social';
       
       Map<String,JIT_Attributes_Mappings__c> allSettings = JIT_Attributes_Mappings__c.getAll();
       String ShibbolethTypeKey = (allSettings.get('ShibbolethType') != null? allSettings.get('ShibbolethType').Raw_Attribute_Name__c : 'None');
       String SocialEmailKey = (allSettings.get('SocialEmail') != null? allSettings.get('SocialEmail').Raw_Attribute_Name__c : 'None');
       String UmichAccountKey = (allSettings.get('UmichAccount') != null? allSettings.get('UmichAccount').Raw_Attribute_Name__c : 'None');
        
       for( String key : attributes.keyset() ){
           System.debug(logginglevel.error,'Key: ' + key + ' - value: ' + attributes.get(key));
           if( key == ShibbolethTypeKey ){
               loginPath = 'Shibboleth';
           }
           
           if( key == UmichAccountKey ){
               loginViaAccount = attributes.get(key);
           }
       }
       
       String outputMsg = 'Method Called: ' + methodCalled + '\n';
              outputMsg += 'federationIdentifier: ' + federationIdentifier + '\n';
              outputMsg += 'pId : ' + pId + '\n';
              outputMsg += 'loginPath : ' + loginPath + '\n';
              outputMsg += 'loginViaAccount : ' + loginViaAccount + '\n';
              
       System.debug(logginglevel.error,'outputMsg : ' + outputMsg );        
       }    
}