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
Josh Packer 10Josh Packer 10 

Test for custom auth provider

We had to set up a custom auth provider and registration handler for our community. I was able to get the registration handler class and test completed.  Salesforce provided the auth provider class below, but no test.  I have been searching for ways to write a compatable test, with no luck.  

Please help.  Can somebody guide me on how to test this class?
 
global class FamilySearch implements Auth.AuthProviderPlugin {
    
    //You'll need to get this from your Auth Provider AFTER it's been created.  (we should provide this at runtime, but its a gap)
    public String redirectUrl = 'https://test.salesforce.com/services/authcallback/00D4C0000000OrwUAE/FamilySearch';
    
    global String getCustomMetadataType() {
        return 'FamilySearch__mdt';
    }
    
    global PageReference initiate(Map<string,string> authProviderConfiguration, String stateToPropagate) {
        System.debug(authProviderConfiguration);
        String authUrl = authProviderConfiguration.get('AuthorizationURL__c');
        String clientID = authProviderConfiguration.get('ClientID__c');
        
        String authZ = authUrl + '?response_type=code&client_id='+ clientID +'&scope=openid%20profile%20email&redirect_uri='+ redirectUrl + '&state=' + stateToPropagate;
        return new PageReference(authZ);
    }
    
    global Auth.AuthProviderTokenResponse handleCallback(Map<string,string> authProviderConfiguration, Auth.AuthProviderCallbackState state ) {
        
        String clientID = authProviderConfiguration.get('ClientID__c');
        String tokenURL = authProviderConfiguration.get('TokenURL__c');
        
        Map<String,String> queryParams = state.queryParameters;
        String code = queryParams.get('code');
        String sfdcState = queryParams.get('state');
        
        HttpRequest req = new HttpRequest();
        String url = tokenURL;
        req.setEndpoint(url);
        req.setHeader('Accept','application/json');
        req.setMethod('POST');
        String body = 'code=' + code + '&client_id=' + clientID + '&grant_type=authorization_code&redirect_uri='+ EncodingUtil.urlEncode(redirectUrl, 'UTF-8');
        req.setBody(body);
        
        Http http = new Http();
        HTTPResponse res = http.send(req);
        String responseBody = res.getBody();
        
        System.debug(res.getStatusCode() + ': ' + responseBody);
        
        String token = null;
        if (res.getStatusCode() == 200) {
            
            JSONParser parser = JSON.createParser(responseBody);
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)){
                    String fieldName = parser.getText();
                    parser.nextToken();
                    if(fieldName == 'access_token') {
                        token = parser.getText();
                    } 
                }
            }
        } //TODO - error handling
        return new Auth.AuthProviderTokenResponse('FamilySearch', token, 'refreshToken', sfdcState);
        
        
    }
    
    
    global Auth.UserData  getUserInfo(Map<string,string> authProviderConfiguration, Auth.AuthProviderTokenResponse response) { 
        //Here the developer is responsible for constructing an Auth.UserData object
        String token = response.oauthToken;
        HttpRequest req = new HttpRequest();
        String userInfo = authProviderConfiguration.get('UserInfoURL__c');
        req.setHeader('Authorization', 'Bearer ' + token);
        req.setEndpoint(userInfo);
        req.setMethod('GET');
        
        Http http = new Http();
        HTTPResponse res = http.send(req);
        String responseBody = res.getBody();
        
        String[] jwtParts = responseBody.split('\\.');
        String header = EncodingUtil.base64Decode(jwtParts[0]).toString();
        String payload = EncodingUtil.base64Decode(jwtParts[1]).toString();
        
        Blob signature = Crypto.generateMac('hmacSHA256', Blob.valueOf(jwtParts[0] + '.' + jwtParts[1]), Blob.valueOf('698DF3C23215E7FF28AE5368343CD0F64743D2036AE315791E5052C3645D0982'));
        
        String output = encodingUtil.base64Encode(signature);
        output = output.replace('+', '-');
        output = output.replace('/', '_');
        while ( output.endsWith('=')){
            output = output.subString(0,output.length()-1);
        }
       
        if(jwtParts[2] == output){
            
            
            String sub;
            String email;
            Boolean email_verified;
            String locale;
            String family_name;
            String given_name;
            
            JSONParser parser = JSON.createParser(payload);
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)){
                    String fieldName = parser.getText();
                    parser.nextToken();
                    if (fieldName == 'sub') {
                        sub = parser.getText();
                    } else if (fieldName == 'email') {
                        email = parser.getText();
                    } else if (fieldName == 'email_verified') {
                        email_verified = parser.getBooleanValue();
                    } else if (fieldName == 'locale') {
                        locale = parser.getText();
                    } else if (fieldName == 'family_name') {
                        family_name = parser.getText();
                    } else if (fieldName == 'given_name') {
                        given_name = parser.getText();
                    }
                }
            }


            Map<String,String> attrMap = new Map<String,String>();
            
            return new Auth.UserData(sub, given_name, family_name, given_name + ' ' + family_name, email,'', email, locale, 'FamilySearch', null, attrMap);

        }
        // TODO - proper error handling
        return null;
    }
    
    
}