SyncMadeEasy/force-app/main/default/classes/AuthenticateInternally.cls

426 lines
26 KiB
OpenEdge ABL

/**
* ─────────────────────────────────────────────────────────────────────────────────────────────────┐
* This class is handle user authentication process.
* Aurthenticate user and update its refresh token into the Config custom settings.
* Shopify API Documentation: https://shopify.dev/docs/admin-api/rest/reference
* Create Shopify Store: https://www.shopify.com/signup?itcat=identity&itterm=create-new-store
* Shopify API Release 2020: https://www.shopify.in/partners/blog/shopify-api-release-january-2020
* What is Person Account in Salesforce ? https://help.salesforce.com/articleView?id=account_person.htm&type=5
* ──────────────────────────────────────────────────────────────────────────────────────────────────
* @author Sumit <sumit@hicShopify.com>
* ──────────────────────────────────────────────────────────────────────────────────────────────────
*/
public with sharing class AuthenticateInternally {
String clientIdProduction;
String clientSecretproduction;
String salesforceUrl = system.url.getOrgDomainUrl().toexternalform();
public Boolean inProgress{get;set;}
public Boolean error{get;set;}
public String customerInstanceUrl ;
public String customerDomainURL;
public String ReturnViewmode;
public pagereference authenticateInternallyController(){
String isLwcApp;
list<HIC_ShopifySync__Configuration__c> listofConfiguration = new list<HIC_ShopifySync__Configuration__c>();
//String conquery = 'Select '+CheckAccessibility.isAccessible('id,name,HIC_ShopifySync__ClientId__c,HIC_ShopifySync__ClientSecret__c','HIC_ShopifySync__Configuration__c')+' from HIC_ShopifySync__Configuration__c where '+CheckAccessibility.isAccessible('name','HIC_ShopifySync__Configuration__c')+' = \'Default\' LIMIT 1';
//listofConfiguration = database.query(conquery);
listofConfiguration = [select id,name,HIC_ShopifySync__ClientId__c,HIC_ShopifySync__ClientSecret__c from HIC_ShopifySync__Configuration__c limit 1];
if(listofConfiguration.isEmpty()) return null;
clientIdProduction = listofConfiguration[0].HIC_ShopifySync__ClientId__c;
clientSecretproduction = listofConfiguration[0].HIC_ShopifySync__ClientSecret__c;
system.debug('authenticateInternallyControllerCalled-params--'+apexpages.currentpage().getparameters());
if(apexpages.currentpage().getparameters().containsKey('code') && apexpages.currentpage().getparameters().containsKey('state')){
system.debug('authenticateInternallyControllerEntered');
inProgress = true;
error = false;
// PKCE: strip the embedded code_verifier from state before the legacy
// suffix-parsing logic runs (verifier is recovered separately below for token exchange).
String rawStateParam = apexpages.currentpage().getparameters().get('state');
String returnCustomerUrl = PkceUtil.extractOriginalState(rawStateParam);
if(returnCustomerUrl.containsIgnoreCase('islwcapp')){
isLwcApp = 'true';
returnCustomerUrl = returnCustomerUrl.replace('islwcapp', '');
}
string urlLoginhint = apexpages.currentpage().getparameters().get('login_hint');
System.debug('in login_hint' + urlLoginhint);
String viewmode = returnCustomerUrl.substring(returnCustomerUrl.length() - 7,returnCustomerUrl.length());
system.debug('viewmode' + viewmode);
if(viewmode.containsIgnoreCase('Theme3')){
ReturnViewmode = 'Theme3';
}else if(viewmode.containsIgnoreCase('Theme4d')){
ReturnViewmode = 'Theme4d';
}
String toCheck = returnCustomerUrl.substring(returnCustomerUrl.length() - 13,returnCustomerUrl.length());
If(toCheck.contains('login')){
if(ReturnViewmode == 'Theme3'){
customerInstanceUrl = returnCustomerUrl.substring(0, returnCustomerUrl.length() - 11);
}
if( ReturnViewmode == 'Theme4d'){
customerInstanceUrl = returnCustomerUrl.substring(0, returnCustomerUrl.length() - 12);
}
}else{
if(ReturnViewmode == 'Theme3'){
customerInstanceUrl = returnCustomerUrl.substring(0, returnCustomerUrl.length() - 10);
}
if( ReturnViewmode == 'Theme4d'){
customerInstanceUrl = returnCustomerUrl.substring(0, returnCustomerUrl.length() - 11);
}
}
// PKCE: recover the code_verifier that was packed into state at /authorize time
// by salesforceAuthenticationController.authenticate() in the customer org.
String codeVerifier = PkceUtil.extractVerifier(rawStateParam);
HttpRequest req = new HttpRequest();
req.setMethod('POST');
//if(returnCustomerUrl.containsIgnoreCase('test')){
if(toCheck.containsIgnoreCase('login')){
req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
}else{
req.setEndpoint('https://test.salesforce.com/services/oauth2/token');
}
String tokenBody = 'grant_type=authorization_code' +
'&client_secret=' + clientSecretproduction +
'&client_id='+ clientIdProduction +
'&redirect_uri=https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication' +
'&code=' + apexpages.currentpage().getparameters().get('code');
if(String.isNotBlank(codeVerifier)){
tokenBody += '&code_verifier=' + codeVerifier;
}
req.setBody(tokenBody);
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res;
if(!Test.isRunningTest()){
res = http.send(req);
System.debug('BODY: '+res.getBody());
System.debug('STATUS:'+res.getStatus());
System.debug('STATUS_CODE:'+res.getStatusCode());
}
list<HIC_ShopifySync__Internal_Callout__c> customSettingRecord = new list<HIC_ShopifySync__Internal_Callout__c>();
//String query = 'Select '+CheckAccessibility.isAccessible('name,HIC_ShopifySync__Client_Id__c, HIC_ShopifySync__Client_Secret__c, HIC_ShopifySync__Password__c, HIC_ShopifySync__Salesforce_Url__c, HIC_ShopifySync__UserName__c ', 'HIC_ShopifySync__Internal_Callout__c')+ ' from HIC_ShopifySync__Internal_Callout__c LIMIT 1';
//customSettingRecord = database.query(query);
customSettingRecord = [select name,HIC_ShopifySync__Client_Id__c, HIC_ShopifySync__Client_Secret__c, HIC_ShopifySync__Password__c, HIC_ShopifySync__Salesforce_Url__c, HIC_ShopifySync__UserName__c from HIC_ShopifySync__Internal_Callout__c limit 1];
string packageOrdAccessToken = oauthLogin(customSettingRecord[0].HIC_ShopifySync__Salesforce_Url__c,customSettingRecord[0].HIC_ShopifySync__Client_Id__c,customSettingRecord[0].HIC_ShopifySync__Client_Secret__c,customSettingRecord[0].HIC_ShopifySync__UserName__c,customSettingRecord[0].HIC_ShopifySync__Password__c);
system.debug('packageOrdAccessToken++++++++'+packageOrdAccessToken);
if( packageOrdAccessToken != null){
System.debug('customerInstanceUrl--> '+customerInstanceUrl);
createRemoteSiteSettings(packageOrdAccessToken,customerInstanceUrl);
Map<String, Object> responseBody = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
System.debug('Refreshtoken++++'+ responseBody.get('refresh_token'));
// NOTE: string.valueOf(null) returns the literal 'null', which used to be concatenated
// straight into the JSON body below and stored as if it were a real token. A stored
// 'null' defeats every blank check in the package (the keep-alive probe and
// ShopifyController.refreshTokenCheck both accept it), so the org reports connected while
// every refresh fails. Keep these genuinely null; the body builder omits them.
String refershToken = responseBody.get('refresh_token') == null
? null : string.valueOf(responseBody.get('refresh_token'));
String accessToken = responseBody.get('access_token') == null
? null : string.valueOf(responseBody.get('access_token'));
customerDomainURL = String.valueof(responseBody.get('instance_url'));
if (customerDomainURL != null) createRemoteSiteSettings(packageOrdAccessToken, customerDomainURL);
System.debug('Org Refresh Token++'+refershToken );
System.debug('Org accessToken Token++'+accessToken );
/* HttpRequest toInsertRefreshToken = new HttpRequest();
toInsertRefreshToken.setHeader('X-HTTP-Method-Override','PATCH');
toInsertRefreshToken.setMethod('POST');
toInsertRefreshToken.setHeader('Authorization','Bearer '+ accessToken);
toInsertRefreshToken.setHeader('Content-Type','application/json');
toInsertRefreshToken.setEndpoint(customerInstanceUrl+'/services/data/v36.0/sobjects/HIC_ShopifySync__Configuration__c/Name/Default?_HttpMethod=PATCH');
toInsertRefreshToken.setEndpoint(customerInstanceUrl+'/services/apexrest/HIC_ShopifySync/UpdateRefreshToken');
string refreshTokenBody = '{ "HIC_ShopifySync__Refresh_Token__c" : " '+refershToken+' " } ';
toInsertRefreshToken.setBody(refreshTokenBody);
Http insertRefreshToken = new Http();
if(!Test.isRunningTest()){
HTTPResponse resResult = insertRefreshToken.send(toInsertRefreshToken);
System.debug('BODY1: '+resResult.getBody());
System.debug('STATUS1:'+resResult.getStatus());
System.debug('STATUS_CODE1:'+resResult.getStatusCode());
if(resResult.getStatusCode() == 204 || resResult.getStatusCode() == 302){
pagereference successPage = new pagereference('https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication?authenticationSuccess=true');
return successPage;
}else{
pagereference errorPage = new pagereference('https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication?authenticationSuccess=false');
return errorPage;
}
}*/
if(!Test.isRunningTest()){
Http insertRefreshToken = new Http();
HttpRequest httpReq = new HttpRequest();
httpReq.setEndpoint(customerInstanceUrl+'/services/apexrest/HIC_ShopifySync/AuthenticateAllApexClass?objectname=UpdateRefreshToken&DMLType=Update');
httpReq.setMethod( 'POST' );
httpReq.setHeader( 'Content-Type', 'application/json' );
httpReq.setHeader( 'Accept', 'application/json' );
httpReq.setHeader( 'Authorization', 'Bearer ' + accessToken );
// Built with JSON.serialize so a null token is omitted rather than becoming the
// string "null", and so any character in a token is escaped correctly.
Map<String, Object> tokenPayload = new Map<String, Object>();
if (String.isNotBlank(refershToken)) tokenPayload.put('HIC_ShopifySync__Refresh_Token__c', refershToken);
if (String.isNotBlank(accessToken)) tokenPayload.put('HIC_ShopifySync__Access_Token__c', accessToken);
String body = JSON.serialize(tokenPayload);
httpReq.setBody( body );
HttpResponse restoken = insertRefreshToken.send( httpReq );
System.debug('BODY1: '+restoken.getBody());
System.debug('STATUS1:'+restoken.getStatus());
System.debug('STATUS_CODE1:'+restoken.getStatusCode());
Boolean redirect = false;
if(restoken.getStatusCode() >=300 && restoken.getStatusCode() <= 307 && restoken.getStatusCode() != 306) {
String locforstart = restoken.getHeader('Location');
if(locforstart != null && locforstart != ''){
createRemoteSiteSettings(packageOrdAccessToken,locforstart.removeEndIgnoreCase('/services/apexrest/HIC_ShopifySync/AuthenticateAllApexClass?objectname=UpdateRefreshToken&DMLType=Update'));
}
do {
redirect = false; // reset the value each time
String loc = restoken.getHeader('Location'); // get location of the redirect
if(loc == null) {
redirect = false;
continue;
}
req = new HttpRequest();
req.setEndpoint(loc);
req.setMethod('POST');
req.setHeader( 'Content-Type', 'application/json' );
req.setHeader( 'Accept', 'application/json' );
req.setHeader( 'Authorization', 'Bearer ' + accessToken );
req.setBody( body );
req.setTimeout(120000);
restoken = insertRefreshToken.send(req);
if(restoken.getStatusCode() != 500) { // 500 = fail
if(restoken.getStatusCode() >=300 && restoken.getStatusCode() <= 307 && restoken.getStatusCode() != 306) {
redirect= true;
}
// I do special handling here with cookies
// if you need to bring a session cookie over to the
// redirected page, this is the place to grab that info
}
} while (redirect && Limits.getCallouts() != Limits.getLimitCallouts());
}
system.debug('StatusCode: '+ restoken.getStatus() );
if(restoken.getStatusCode() == 200 || restoken.getStatusCode() == 204 ){
System.debug('@@@ Does LWC Contains true ::: '+isLwcApp);
if(String.isNotBlank(isLwcApp) && isLwcApp.containsIgnoreCase('true')){
System.debug('@@@ inside LWC true ::: ');
pagereference successPage = new pagereference('https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication?authenticationSuccess=true&customerInstanceUrl='+customerInstanceUrl+'&viewmode='+ReturnViewmode+'&islwcapp=true');
return successPage;
}
pagereference successPage = new pagereference('https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication?authenticationSuccess=true&customerInstanceUrl='+customerInstanceUrl+'&viewmode='+ReturnViewmode);
return successPage;
}else{
if(String.isNotBlank(isLwcApp) && isLwcApp.containsIgnoreCase('true')){
System.debug('@@@ inside LWC true ::: ');
pagereference errorPage = new pagereference('https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication?authenticationSuccess=false&customerInstanceUrl='+customerInstanceUrl+'&viewmode='+ReturnViewmode+'&islwcapp=true');
return errorPage;
}
pagereference errorPage = new pagereference('https://hicshopifymadeeasy-dev-ed.my.salesforce-sites.com/thankYouPageSuccessfulAuthentication?authenticationSuccess=false&customerInstanceUrl='+customerInstanceUrl+'&viewmode='+ReturnViewmode);
return errorPage;
}
}
}
}
system.debug('customerUrl--'+customerInstanceUrl);
if(apexpages.currentpage().getparameters().containsKey('authenticationSuccess') && apexpages.currentpage().getparameters().get('authenticationSuccess') != null && apexpages.currentpage().getparameters().get('authenticationSuccess') == 'true' ){
inProgress = false;
// error = true;
}else if(apexpages.currentpage().getparameters().containsKey('authenticationSuccess') && apexpages.currentpage().getparameters().get('authenticationSuccess') != null && apexpages.currentpage().getparameters().get('authenticationSuccess') == 'false' ){
inProgress = null;
error = true;
}
return null;
}
public static boolean CheckingRemotesiteExistence(String SFdomainUrl ,string Sessionid){
boolean exist = false;
// String SFdomainUrl = URL.getOrgDomainUrl().toExternalForm();
String OrgURl = URL.getOrgDomainUrl().toExternalForm();
try{
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + Sessionid); //Get user Session ID
req.setHeader('Content-Type', 'application/json');
String query='select+id,+EndpointUrl+from+Remotesitesetting+where+EndpointUrl=+\''+SFdomainUrl+'\'';
req.setEndpoint(OrgURl+'/services/data/v58.0/tooling/query/?q='+query);
req.setMethod('GET');
req.setTimeout(120000);
Http h = new Http();
HttpResponse response;
String RemotesitesettingResponse;
if(!Test.isRunningTest()){
response = h.send(req);
RemotesitesettingResponse = response.getBody().trim();
}else{
RemotesitesettingResponse = '{"size":1,"totalSize":1,"done":true,"queryLocator":null,"entityTypeName":"Certificate","records":[{"attributes":{"type":"Certificate","url":"/services/data/v58.0/tooling/sobjects/Certificate/0P12v000006b5K9CAI"},"Id":"0P12v000006b5K9CAI","DeveloperName":"Shopify"}]}';
}
System.debug('response---- '+ RemotesitesettingResponse);
if(RemotesitesettingResponse == null || RemotesitesettingResponse =='') return false;
Map<String,object> mapofRemoteSitesettings = (Map<String,object>) JSON.deserializeUntyped(RemotesitesettingResponse);
if(!mapofRemoteSitesettings.isempty() && mapofRemoteSitesettings != null && mapofRemoteSitesettings.containskey('size')){
if(Integer.valueof(mapofRemoteSitesettings.get('size')) > 0){
exist = true;
}
}
return exist;
}Catch(Exception e){
System.debug('Exception---- '+ e + 'at line number '+ e.getLineNumber());
return exist;
}
}
public static void createRemoteSiteSettings(String accessToken, String instanceURl){
system.debug('createRemoteSiteSettings+++++'+accessToken) ;
if(CheckingRemotesiteExistence(instanceURl,accessToken)) return;
MetadataServiceNew.MetadataPort service = createService(accessToken);
MetadataServiceNew.RemoteSiteSetting remoteSiteSettings = new MetadataServiceNew.RemoteSiteSetting();
remoteSiteSettings.fullName = 'App'+DateTime.now().getTime();
remoteSiteSettings.url = instanceURl;
remoteSiteSettings.description='Client Remote Site '+instanceURl;
remoteSiteSettings.isActive=true;
remoteSiteSettings.disableProtocolSecurity=false;
/* MetadataServiceNew.RemoteSiteSetting remoteSiteSettingsWithoutVf = new MetadataServiceNew.RemoteSiteSetting();
remoteSiteSettingsWithoutVf.fullName = 'AppMain'+DateTime.now().getTime();
remoteSiteSettingsWithoutVf.url = instanceURl.remove('visualforce.');
remoteSiteSettingsWithoutVf.description='Client Remote Site '+instanceURl;
remoteSiteSettingsWithoutVf.isActive=true;
remoteSiteSettingsWithoutVf.disableProtocolSecurity=false;
system.debug('url without vf '+instanceURl.remove('visualforce.'));
system.debug('remoteSiteSettingsWithoutVf--'+remoteSiteSettingsWithoutVf);*/
MetadataServiceNew.AsyncResult[] results = service.create(new List<MetadataServiceNew.Metadata> { remoteSiteSettings });
// MetadataServiceNew.AsyncResult[] resultsVF = service.create(new List<MetadataServiceNew.Metadata> { remoteSiteSettingsWithoutVf });
system.debug('results meta size '+results.size());
system.debug('results meta '+results);
system.debug('string.ValueOf(results[0].Id)'+string.ValueOf(results[0].Id));
MetadataServiceNew.AsyncResult[] checkResults = service.checkStatus(new List<string> {string.ValueOf(results[0].Id)});
system.debug('checkResults meta size '+checkResults.size());
system.debug('checkResults meta '+checkResults);
system.debug('chk' + checkResults );
}
public static MetadataServiceNew.MetadataPort createService(String accessToken){
system.debug('createService+++++'+accessToken) ;
MetadataServiceNew.MetadataPort service = new MetadataServiceNew.MetadataPort();
service.SessionHeader = new MetadataServiceNew.SessionHeader_element();
service.SessionHeader.sessionId = accessToken;
return service;
}
public static string oauthLogin(String loginUri, String clientId,
String clientSecret, String username, String password) {
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint(loginUri+'/services/oauth2/token');
req.setBody('grant_type=password' +
'&client_id=' + clientId +
'&client_secret=' + clientSecret +
'&username=' + EncodingUtil.urlEncode(username, 'UTF-8') +
'&password=' + EncodingUtil.urlEncode(password, 'UTF-8'));
req.setTimeout(120000);
System.debug('BODY:req '+req.getBody());
Http http = new Http();
if(!Test.isRunningTest()){
HTTPResponse res = http.send(req);
System.debug('BODY: '+res.getBody());
System.debug('STATUS:'+res.getStatus());
System.debug('STATUS_CODE:'+res.getStatusCode());
readToken body = (readToken)JSON.deserialize(res.getBody(), readToken.class);
System.debug('Token:'+body.access_token);
return body.access_token;
}else{
return null;
}
}
public PageReference dosubmit(){
string UserCustomDomain;
String ViewMode;
String isLwcApp;
if(apexpages.currentpage().getparameters().containsKey('customerInstanceUrl') && apexpages.currentpage().getparameters().get('customerInstanceUrl') != null && apexpages.currentpage().getparameters().get('customerInstanceUrl') != '' ){
UserCustomDomain = apexpages.currentpage().getparameters().get('customerInstanceUrl');
}
if(apexpages.currentpage().getparameters().containsKey('islwcapp') && apexpages.currentpage().getparameters().get('islwcapp') != null && apexpages.currentpage().getparameters().get('islwcapp') != '' ){
isLwcApp = apexpages.currentpage().getparameters().get('islwcapp');
}
if(apexpages.currentpage().getparameters().containsKey('viewmode') && apexpages.currentpage().getparameters().get('viewmode') != null && apexpages.currentpage().getparameters().get('viewmode') != '' ){
ViewMode = apexpages.currentpage().getparameters().get('viewmode');
}
String sfUrl=URL.getOrgDomainUrl().getHost();
String myURL;
//= UserCustomDomain + '/lightning/n/HIC_ShopifySync__Salesforce_Shopify_Sync_Settings';
if(ViewMode == 'Theme3')
{
myURL = 'apex/SfdcShopifySyncSettings?';
}
else if(ViewMode == 'Theme4d' && String.isNotBlank(isLwcApp) && isLwcApp.containsIgnoreCase('true'))
{
myURL = 'lightning/n/HIC_ShopifySync__SME_Settings';
}
else if(ViewMode == 'Theme4d' && isLwcApp == null){
// else if(ViewMode == 'Theme4d'){
myURL = 'lightning/n/HIC_ShopifySync__Salesforce_Shopify_Sync_Settings';
}else{
myURL = 'lightning/n/HIC_ShopifySync__Salesforce_Shopify_Sync_Settings';
}
PageReference pr = new PageReference(UserCustomDomain +'/'+myURL); // google is blocked here
// PageReference pr = new PageReference('https://hicshopifymadeeasy-dev-ed.my.salesforce.com/apex/SfdcShopifySyncSettings?'); // google is blocked here
pr.setRedirect(true);
return pr;
}
public class readToken{
public string access_token{get;set;}
public string instance_url{get;set;}
}
}