Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Salesforce User Disconnect API #76

Merged
merged 10 commits into from
Aug 30, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.SaveBehavior;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
Expand All @@ -21,28 +20,28 @@ public class DynamoDBConfiguration {
@Bean
public DynamoDBMapper dynamoDBMapper() {
DynamoDBMapper defaultMapper = new DynamoDBMapper(buildAmazonDynamoDB(), dynamoDBMapperConfig());
//Override DynamoDb operations to add logging.
// Override DynamoDb operations to add logging.
return new DynamoDBMapper(buildAmazonDynamoDB(), dynamoDBMapperConfig()) {
@Override
public <T> T load(Class<T> clazz, Object hashKey) {
T response = null;
long startTimestamp = System.currentTimeMillis();
try{
try {
response = defaultMapper.load(clazz, hashKey);
} catch (Exception e) {
logger.debug("DBQuery:Load: table-{} hashKey-{}", clazz.getSimpleName(), hashKey);
logger.error("DBQuery:Load: exception-{}", e);
throw new RuntimeException("Error during load database operation", e);
}
long duration = System.currentTimeMillis() - startTimestamp;

long duration = System.currentTimeMillis() - startTimestamp;
logger.debug("({} ms)DBQuery:Load: table-{} hashKey-{}", duration, clazz.getSimpleName(), hashKey);
return response;
}

@Override
public <T> void save(T object) {
long startTimestamp = System.currentTimeMillis();
long startTimestamp = System.currentTimeMillis();
try {
defaultMapper.save(object);
} catch (Exception e) {
ajinkyac03 marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -51,22 +50,39 @@ public <T> void save(T object) {
throw new RuntimeException("Error during save database operation", e);
}

long duration = System.currentTimeMillis() - startTimestamp;
long duration = System.currentTimeMillis() - startTimestamp;
logger.debug("({} ms)DBQuery:Save: table-{}", duration, object.getClass().getSimpleName());
}
// Similarly, you can override other used methods like delete, batchSave, etc. similarly

@Override
public <T> void save(T object, DynamoDBMapperConfig config) {
long startTimestamp = System.currentTimeMillis();
try {
defaultMapper.save(object, config);
} catch (Exception e) {
logger.debug("DBQuery:Save: table-{}", object.getClass().getSimpleName());
logger.error("DBQuery:Save: exception-{}", e);
throw new RuntimeException("Error during save database operation", e);
}

long duration = System.currentTimeMillis() - startTimestamp;
logger.debug("({} ms)DBQuery:Save: table-{}", duration, object.getClass().getSimpleName());
}

// Similarly, you can override other used methods like delete, batchSave, etc.
// similarly
ajinkyac03 marked this conversation as resolved.
Show resolved Hide resolved
};
ajinkyac03 marked this conversation as resolved.
Show resolved Hide resolved
}

@Bean
public AmazonDynamoDB buildAmazonDynamoDB() {
return AmazonDynamoDBClientBuilder
.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
CoreConstants.dynamoDbUrl(),
CoreConstants.awsRegion()))
.build();
.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
CoreConstants.dynamoDbUrl(),
CoreConstants.awsRegion()))
.build();
}

@Bean
Expand Down
25 changes: 22 additions & 3 deletions src/main/java/com/salessparrow/api/controllers/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.salessparrow.api.dto.requestMapper.SalesforceConnectDto;
import com.salessparrow.api.dto.requestMapper.SalesforceRedirectUrlDto;
import com.salessparrow.api.lib.CookieHelper;
import com.salessparrow.api.services.auth.DisconnectUserService;
import com.salessparrow.api.services.salesforce.AuthService;
import com.salessparrow.api.services.salesforce.AuthService.AuthServiceDto;

Expand All @@ -38,15 +39,19 @@ public class AuthController {
@Autowired
private AuthService authService;

@Autowired
private DisconnectUserService disconnectUserService;

@Autowired
private CookieHelper cookieHelper;

@GetMapping("/salesforce/redirect-url")
public ResponseEntity<RedirectUrlFormatterDto> getSalesforceRedirectUrl(
@Valid @ModelAttribute SalesforceRedirectUrlDto salesforceRedirectUrlDto) {

RedirectUrlFormatterDto redirectUrlFormatterDto = redirectUrlService.getSalesforceOauthUrl(salesforceRedirectUrlDto);


RedirectUrlFormatterDto redirectUrlFormatterDto = redirectUrlService
.getSalesforceOauthUrl(salesforceRedirectUrlDto);

return ResponseEntity.ok().body(redirectUrlFormatterDto);
}

Expand Down Expand Up @@ -75,4 +80,18 @@ public ResponseEntity<String> logout(HttpServletRequest request) {

return ResponseEntity.ok().headers(headers).body(null);
}

@PostMapping("/disconnect")
public ResponseEntity<String> disconnect(HttpServletRequest request) {
logger.info("User disconnect request received");

disconnectUserService.disconnect(request);

logger.info("Clearing user cookie");
HttpHeaders headers = new HttpHeaders();
headers = cookieHelper.clearUserCookie(headers);

logger.info("User disconnected successfully");
return ResponseEntity.noContent().headers(headers).build();
}
}
1 change: 1 addition & 0 deletions src/main/java/com/salessparrow/api/lib/AwsKms.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public String decryptToken(String encryptedToken) {
try {
result = kmsClient.decrypt(request);
} catch (Exception e) {
System.out.println(e.getMessage());
throw new CustomException(
new ErrorObject(
"l_ak_dt_1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private void validate() {
*
* @throws RuntimeException
*/
private void setParts() {
private void setParts() {
List<String> cookieValueParts = Arrays.asList(cookieValue.split(":"));

if (cookieValueParts.size() != 6) {
Expand All @@ -107,7 +107,7 @@ private void setParts() {
if (cookieValueParts.get(0).equals(CookieConstants.LATEST_VERSION)) {
userId = cookieValueParts.get(1);
userKind = cookieValueParts.get(2);
cookieApiSource = cookieValueParts.get(3);
cookieApiSource = cookieValueParts.get(3);
timestampInCookie = Integer.parseInt(cookieValueParts.get(4));
token = cookieValueParts.get(5);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.salessparrow.api.lib.crmActions.disconnectUser;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.salessparrow.api.domain.SalesforceOauthToken;
import com.salessparrow.api.domain.User;
import com.salessparrow.api.exception.CustomException;
import com.salessparrow.api.lib.AwsKms;
import com.salessparrow.api.lib.errorLib.ErrorObject;
import com.salessparrow.api.lib.salesforce.wrappers.SalesforceTokens;
import com.salessparrow.api.repositories.SalesforceOauthTokenRepository;
import com.salessparrow.api.repositories.SalesforceUserRepository;

/**
* DisconnectSalesforceUser class to disconnect a user from Salesforce.
*/
@Component
public class DisconnectSalesforceUser implements DisconnectUser {

@Autowired
private SalesforceOauthTokenRepository salesforceOauthTokenRepository;

@Autowired
private SalesforceUserRepository salesforceUserRepository;

@Autowired
private AwsKms awsKms;

@Autowired
private SalesforceTokens salesforceTokens;

Logger logger = LoggerFactory.getLogger(DisconnectSalesforceUser.class);
ajinkyac03 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Disconnects a user from Salesforce by revoking the tokens and deleting the
* user data from the database.
*
* @param user
* @return void
*/
public void disconnect(User user) {

String salesforceUserId = user.getExternalUserId();

logger.info("Disconnecting user from Salesforce: " + salesforceUserId);
SalesforceOauthToken salesforceOauthToken = salesforceOauthTokenRepository
.getSalesforceOauthTokenByExternalUserId(salesforceUserId);

if (salesforceOauthToken == null) {
throw new CustomException(
new ErrorObject(
"l_ca_du_dsu_d_1",
"something_went_wrong",
"No tokens data found for this user."));
}

String decryptedRefreshToken = awsKms.decryptToken(salesforceOauthToken.getRefreshToken());

logger.info("Revoking tokens from Salesforce: " + salesforceUserId);
salesforceTokens.revokeTokens(salesforceOauthToken.getInstanceUrl(), decryptedRefreshToken);

logger.info("Deleting tokens from database: " + salesforceUserId);
salesforceOauthTokenRepository.deleteSalesforceOauthTokenBySalesforceOauthToken(salesforceOauthToken);

logger.info("Deleting user data from database: " + salesforceUserId);
salesforceUserRepository.removeSalesforceUserData(salesforceUserId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.salessparrow.api.lib.crmActions.disconnectUser;

import org.springframework.stereotype.Component;

import com.salessparrow.api.domain.User;

/**
* DisconnectUser interface for disconnecting a user from the CRM.
*/
@Component
public interface DisconnectUser {

public void disconnect(User User);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.salessparrow.api.lib.crmActions.disconnectUser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.salessparrow.api.domain.User;
import com.salessparrow.api.exception.CustomException;
import com.salessparrow.api.lib.errorLib.ErrorObject;
import com.salessparrow.api.lib.globalConstants.UserConstants;

/**
* Factory for disconnecting a user from the CRM based on the user kind.
*/
@Component
public class DisconnectUserFactory {

@Autowired
private DisconnectSalesforceUser disconnectSalesforceUser;

/**
* Disconnect a user from the CRM based on the user kind.
*
* @param user
*
* @return void
*/
public void disconnect(User user) {

switch (user.getUserKind()) {
case UserConstants.SALESFORCE_USER_KIND:
disconnectSalesforceUser.disconnect(user);
break;
default:
throw new CustomException(
new ErrorObject(
"l_ca_du_duf_d_1",
"something_went_wrong",
"Invalid user kind."));
}
}
}
ajinkyac03 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public String oauth2Url() {
return CoreConstants.salesforceAuthUrl() + "/services/oauth2/token";
}

public String revokeTokensUrl() {
return "/services/oauth2/revoke";
}

public String salesforceCreateNoteUrl() {
return sObjectsPath() + "/ContentNote";
}
Expand Down Expand Up @@ -58,11 +62,11 @@ public Integer timeoutMillis() {
return 10000;
}

public String salesforceNotesContentUrl(String urlPrefix, String noteId){
public String salesforceNotesContentUrl(String urlPrefix, String noteId) {
return urlPrefix + "/services/data/v58.0/sobjects/ContentNote/" + noteId + "/Content";
}

public String salesforceCreateTaskUrl(){
public String salesforceCreateTaskUrl() {
return sObjectsPath() + "/Task";
}

Expand Down
12 changes: 8 additions & 4 deletions src/main/java/com/salessparrow/api/lib/httpLib/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ public static HttpResponse makeGetRequest(String url, Map<String, String> header
int statusCode = responseEntity.getStatusCode().value();
String responseBody = responseEntity.getBody();
Map<String, List<String>> responseHeaders = new HashMap<>(responseEntity.getHeaders());
String contentType = responseEntity.getHeaders().getContentType().toString();

String contentType = "";
if (responseEntity.getHeaders().getContentType() != null) {
contentType = responseEntity.getHeaders().getContentType().toString();
}
return new HttpResponse(statusCode, responseBody, responseHeaders, contentType);
}

Expand Down Expand Up @@ -102,8 +104,10 @@ public static HttpResponse makePostRequest(String url, Map<String, String> heade
int statusCode = responseEntity.getStatusCode().value();
String responseBody = responseEntity.getBody();
Map<String, List<String>> responseHeaders = new HashMap<>(responseEntity.getHeaders());
String contentType = responseEntity.getHeaders().getContentType().toString();

String contentType = "";
if (responseEntity.getHeaders().getContentType() != null) {
contentType = responseEntity.getHeaders().getContentType().toString();
}
return new HttpResponse(statusCode, responseBody, responseHeaders, contentType);
}
}
Loading
Loading