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

[ES-177] #279

Merged
merged 2 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/push_trigger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 1.*
- develop
- main
- bugfix-ES-177

jobs:
call-workflow-codeql-analysis:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void bindWallet_withUnsupportedFormat_thenFail() throws EsignetException,
Assert.assertNotNull(keyBindingService.bindWallet(walletBindingRequest, new HashMap<>()));
Assert.fail();
} catch (EsignetException e) {
Assert.assertTrue(e.getErrorCode().equals(ErrorConstants.INVALID_CHALLENGE_FORMAT));
Assert.assertTrue(e.getErrorCode().equals(ErrorConstants.INVALID_AUTH_FACTOR_TYPE_OR_CHALLENGE_FORMAT));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.UUID;
@Repository
public interface ConsentRepository extends JpaRepository<ConsentDetail, UUID> {
boolean existsByClientIdAndPsuToken(String clientId, String psuToken);
Optional<ConsentDetail> findByClientIdAndPsuToken(String clientId, String psuToken);
void deleteByClientIdAndPsuToken(String clientId, String psuToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,10 @@ public ConsentDetail saveUserConsent(UserConsent userConsent) {
AuditHelper.buildAuditDto(userConsent.getClientId()), null);
return consentDetailDto;
}

@Override
@Transactional
public void deleteUserConsent(String clientId, String psuToken) {
consentRepository.deleteByClientIdAndPsuToken(clientId, psuToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,36 @@ public void createConsent_withNullCreatedtimes_thenFail() {
Assert.fail();
}

@Test
public void createAndDeleteConsent_withValidDetail_thenPass() {

ConsentDetail consentDetail =new ConsentDetail();
UUID uuid=UUID.randomUUID();
LocalDateTime date = LocalDateTime.of(2019, 12, 12, 12, 12, 12);
consentDetail.setClientId("123");
consentDetail.setPsuToken("abc");
consentDetail.setClaims("claims");
consentDetail.setAuthorizationScopes("authorizationScopes");
consentDetail.setCreatedtimes(date);
consentDetail.setExpiredtimes(LocalDateTime.now());
consentDetail.setSignature("signature");
consentDetail.setHash("hash");
consentDetail.setAcceptedClaims("claim");
consentDetail.setPermittedScopes("scope");
consentDetail =consentRepository.save(consentDetail);
Assert.assertNotNull(consentDetail);

Optional<ConsentDetail> result;

result = consentRepository.findByClientIdAndPsuToken("123", "abc");
Assert.assertTrue(result.isPresent());

result = consentRepository.findByClientIdAndPsuToken("123", "abcd");
Assert.assertFalse(result.isPresent());
consentRepository.deleteByClientIdAndPsuToken(consentDetail.getClientId(),consentDetail.getPsuToken());
consentRepository.flush();
Optional<ConsentDetail> consentDetailOptional = consentRepository.findByClientIdAndPsuToken("123", "abc");
Assert.assertFalse(consentDetailOptional.isPresent());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,13 @@ public void saveUserConsent_withValidDetails_thenPass() throws Exception{

}

@Test
public void deleteConsentByClientIdAndPsuToken_thenPass(){
String clientId = "test-client-id";
String psuToken = "test-psu-token";
consentService.deleteUserConsent(clientId,psuToken);
Mockito.verify(consentRepository).deleteByClientIdAndPsuToken(clientId, psuToken);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class OIDCTransaction implements Serializable {
String relyingPartyId;
String redirectUri;
Claims requestedClaims;
List<String> essentialClaims;
List<String> voluntaryClaims;
List<String> requestedAuthorizeScopes;
String[] claimsLocales;
String authTransactionId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ public interface ConsentService {
*
*/
ConsentDetail saveUserConsent(UserConsent userConsent) throws EsignetException;

/**
* Api to delete user consent from Consent Registry
* @param psuToken
* @param clientId
*/
void deleteUserConsent(String clientId, String psuToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ public enum Action {
LINK_SEND_OTP,
LINK_AUTH_CODE,
GET_USER_CONSENT,
SAVE_USER_CONSENT
SAVE_USER_CONSENT,
UPDATE_USER_CONSENT
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.*;
Expand Down Expand Up @@ -114,6 +113,8 @@ public OAuthDetailResponse getOauthDetails(OAuthDetailRequest oauthDetailReqDto)

//Cache the transaction
OIDCTransaction oidcTransaction = new OIDCTransaction();
oidcTransaction.setEssentialClaims(oauthDetailResponse.getEssentialClaims());
oidcTransaction.setVoluntaryClaims(oauthDetailResponse.getVoluntaryClaims());
oidcTransaction.setRedirectUri(oauthDetailReqDto.getRedirectUri());
oidcTransaction.setRelyingPartyId(clientDetailDto.getRpId());
oidcTransaction.setClientId(clientDetailDto.getId());
Expand Down Expand Up @@ -224,7 +225,7 @@ public AuthCodeResponse getAuthCode(AuthCodeRequest authCodeRequest) throws Esig
transaction.setCodeHash(authorizationHelperService.getKeyHash(authCode));
transaction.setAcceptedClaims(acceptedClaims);
transaction.setPermittedScopes(acceptedScopes);
consentHelperService.addUserConsent(transaction, false, null);
consentHelperService.updateUserConsent(transaction, false, null);
transaction = cacheUtilService.setAuthCodeGeneratedTransaction(authCodeRequest.getTransactionId(), transaction);
auditWrapper.logAudit(Action.GET_AUTH_CODE, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(authCodeRequest.getTransactionId(), transaction), null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import io.mosip.esignet.api.dto.ClaimDetail;
import io.mosip.esignet.api.dto.Claims;
import io.mosip.esignet.api.spi.AuditPlugin;
import io.mosip.esignet.api.util.Action;
import io.mosip.esignet.api.util.ActionStatus;
import io.mosip.esignet.api.util.ConsentAction;
import io.mosip.esignet.core.constants.ErrorConstants;
import io.mosip.esignet.core.dto.ConsentDetail;
Expand All @@ -16,10 +19,12 @@
import io.mosip.esignet.core.dto.UserConsentRequest;
import io.mosip.esignet.core.exception.EsignetException;
import io.mosip.esignet.core.spi.ConsentService;
import io.mosip.esignet.core.util.AuditHelper;
import io.mosip.esignet.core.util.IdentityProviderUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
Expand All @@ -33,24 +38,44 @@ public class ConsentHelperService {
@Autowired
private ConsentService consentService;

@Autowired
private AuditPlugin auditWrapper;

public void processConsent(OIDCTransaction transaction, boolean linked) {
UserConsentRequest userConsentRequest = new UserConsentRequest();
userConsentRequest.setClientId(transaction.getClientId());
userConsentRequest.setPsuToken(transaction.getPartnerSpecificUserToken());
Optional<ConsentDetail> consent = consentService.getUserConsent(userConsentRequest);

ConsentAction consentAction = consent.isEmpty() ? ConsentAction.CAPTURE : evaluateConsentAction(transaction,consent.get(), linked);
if(CollectionUtils.isEmpty(transaction.getVoluntaryClaims())
&& CollectionUtils.isEmpty(transaction.getEssentialClaims())
&& CollectionUtils.isEmpty(transaction.getRequestedAuthorizeScopes())){
transaction.setConsentAction(ConsentAction.NOCAPTURE);
transaction.setAcceptedClaims(List.of());
transaction.setPermittedScopes(List.of());
} else {
ConsentAction consentAction = consent.isEmpty() ? ConsentAction.CAPTURE : evaluateConsentAction(transaction, consent.get(), linked);

transaction.setConsentAction(consentAction);
transaction.setConsentAction(consentAction);

if(consentAction.equals(ConsentAction.NOCAPTURE)) {
transaction.setAcceptedClaims(consent.get().getAcceptedClaims()); //NOSONAR consent is already evaluated to be not null
transaction.setPermittedScopes(consent.get().getPermittedScopes()); //NOSONAR consent is already evaluated to be not null
if (consentAction.equals(ConsentAction.NOCAPTURE)) {
transaction.setAcceptedClaims(consent.get().getAcceptedClaims()); //NOSONAR consent is already evaluated to be not null
transaction.setPermittedScopes(consent.get().getPermittedScopes()); //NOSONAR consent is already evaluated to be not null
}
}
}


public void addUserConsent(OIDCTransaction transaction, boolean linked, String signature) {
public void updateUserConsent(OIDCTransaction transaction, boolean linked, String signature) {
if(ConsentAction.NOCAPTURE.equals(transaction.getConsentAction())
&& transaction.getEssentialClaims().isEmpty()
&& transaction.getVoluntaryClaims().isEmpty()
&& transaction.getRequestedAuthorizeScopes().isEmpty()
){
//delete old consent if it exists since this scenario doesn't require capture of consent.
consentService.deleteUserConsent(transaction.getClientId(),transaction.getPartnerSpecificUserToken());
auditWrapper.logAudit(Action.UPDATE_USER_CONSENT, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(transaction.getAuthTransactionId(),transaction),null);
}
if(ConsentAction.CAPTURE.equals(transaction.getConsentAction())){
UserConsent userConsent = new UserConsent();
userConsent.setClientId(transaction.getClientId());
Expand All @@ -76,6 +101,7 @@ public void addUserConsent(OIDCTransaction transaction, boolean linked, String s
throw new EsignetException(ErrorConstants.INVALID_CLAIM);
}
consentService.saveUserConsent(userConsent);
auditWrapper.logAudit(Action.UPDATE_USER_CONSENT, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(transaction.getAuthTransactionId(),transaction),null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
Expand Down Expand Up @@ -270,7 +269,7 @@ public LinkedConsentResponse saveConsentV2(LinkedConsentRequestV2 linkedConsentR
// cache consent only, auth-code will be generated on link-auth-code-status API call
transaction.setAcceptedClaims(linkedConsentRequest.getAcceptedClaims());
transaction.setPermittedScopes(linkedConsentRequest.getPermittedAuthorizeScopes());
consentHelperService.addUserConsent(transaction, true, linkedConsentRequest.getSignature());
consentHelperService.updateUserConsent(transaction, true, linkedConsentRequest.getSignature());
cacheUtilService.setLinkedConsentedTransaction(linkedConsentRequest.getLinkedTransactionId(), transaction);
//Publish message after successfully saving the consent
kafkaHelperService.publish(linkedAuthCodeTopicName, linkedConsentRequest.getLinkedTransactionId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.mosip.esignet.api.dto.ClaimDetail;
import io.mosip.esignet.api.dto.Claims;
import io.mosip.esignet.api.spi.AuditPlugin;
import io.mosip.esignet.api.util.ConsentAction;
import io.mosip.esignet.core.dto.ConsentDetail;
import io.mosip.esignet.core.dto.OIDCTransaction;
import io.mosip.esignet.core.dto.UserConsent;
import io.mosip.esignet.core.dto.UserConsentRequest;
import io.mosip.esignet.core.spi.ConsentService;
import io.mosip.esignet.core.util.KafkaHelperService;
Expand Down Expand Up @@ -50,13 +52,16 @@ public class ConsentHelperServiceTest {
@Autowired
ObjectMapper objectMapper;

@Mock
AuditPlugin auditHelper;


@Test
public void addUserConsent_withValidLinkedTransaction_thenPass()
{
OIDCTransaction oidcTransaction = new OIDCTransaction();
oidcTransaction.setAuthTransactionId("123");
oidcTransaction.setAcceptedClaims(List.of("name","email"));
oidcTransaction.setAcceptedClaims(List.of("name"));
oidcTransaction.setPermittedScopes(null);
oidcTransaction.setConsentAction(ConsentAction.CAPTURE);

Expand All @@ -66,13 +71,18 @@ public void addUserConsent_withValidLinkedTransaction_thenPass()
ClaimDetail userinfoNameClaimDetail = new ClaimDetail("name", new String[]{"value1a", "value1b"}, true);
ClaimDetail idTokenClaimDetail = new ClaimDetail("token", new String[]{"value2a", "value2b"}, false);
userinfo.put("name", userinfoNameClaimDetail);
userinfo.put("email",null);
id_token.put("idTokenKey", idTokenClaimDetail);
claims.setUserinfo(userinfo);
claims.setId_token(id_token);

oidcTransaction.setRequestedClaims(claims);
consentHelperService.addUserConsent(oidcTransaction, true, null);
consentHelperService.updateUserConsent(oidcTransaction, true, null);
UserConsent userConsent = new UserConsent();
userConsent.setHash("PxQIckCdFC5TPmL7_G7NH0Zs4UmHC74rGpOkyldqRpg");
userConsent.setClaims(claims);
userConsent.setAuthorizationScopes(Map.of());
userConsent.setAcceptedClaims(List.of("name"));
Mockito.verify(consentService).saveUserConsent(userConsent);

}

Expand All @@ -81,7 +91,7 @@ public void addUserConsent_withValidWebTransaction_thenPass()
{
OIDCTransaction oidcTransaction = new OIDCTransaction();
oidcTransaction.setAuthTransactionId("123");
oidcTransaction.setAcceptedClaims(List.of("name","email"));
oidcTransaction.setAcceptedClaims(List.of("value1"));
oidcTransaction.setPermittedScopes(null);
oidcTransaction.setConsentAction(ConsentAction.CAPTURE);

Expand All @@ -99,7 +109,34 @@ public void addUserConsent_withValidWebTransaction_thenPass()

Mockito.when(consentService.saveUserConsent(Mockito.any())).thenReturn(new ConsentDetail());

consentHelperService.addUserConsent(oidcTransaction, false, "");
consentHelperService.updateUserConsent(oidcTransaction, false, "");
UserConsent userConsent = new UserConsent();
userConsent.setHash("Cgh8oWpNM84WPYQVvluGj616_kd4z60elVXtc7R_lXw");
userConsent.setClaims(claims);
userConsent.setAuthorizationScopes(Map.of());
userConsent.setAcceptedClaims(List.of("value1"));
userConsent.setSignature("");
Mockito.verify(consentService).saveUserConsent(userConsent);
}

@Test
public void addUserConsent_withValidWebTransactionNoClaimsAndScopes_thenPass()
{
String clientId = "clientId";
String psuToken = "psuToken";
OIDCTransaction oidcTransaction = new OIDCTransaction();
oidcTransaction.setAuthTransactionId("123");
oidcTransaction.setAcceptedClaims(List.of());
oidcTransaction.setRequestedAuthorizeScopes(List.of());
oidcTransaction.setConsentAction(ConsentAction.NOCAPTURE);
oidcTransaction.setVoluntaryClaims(List.of());
oidcTransaction.setEssentialClaims(List.of());
oidcTransaction.setAcceptedClaims(List.of());
oidcTransaction.setPermittedScopes(List.of());
oidcTransaction.setClientId(clientId);
oidcTransaction.setPartnerSpecificUserToken(psuToken);
consentHelperService.updateUserConsent(oidcTransaction, false, "");
Mockito.verify(consentService).deleteUserConsent(clientId, psuToken);
}

@Test
Expand All @@ -110,6 +147,8 @@ public void processConsent_withValidConsentAndConsentActionAsNoCapture_thenPass(
oidcTransaction.setPartnerSpecificUserToken("123");
oidcTransaction.setRequestedAuthorizeScopes(List.of("openid","profile"));
oidcTransaction.setPermittedScopes(List.of("openid","profile"));
oidcTransaction.setEssentialClaims(List.of("name"));
oidcTransaction.setVoluntaryClaims(List.of("email"));

Claims claims = new Claims();
Map<String, ClaimDetail> userinfo = new HashMap<>();
Expand Down Expand Up @@ -156,7 +195,8 @@ public void processConsent_withValidConsentAndConsentActionAsCapture_thenPass()
oidcTransaction.setPartnerSpecificUserToken("123");
oidcTransaction.setRequestedAuthorizeScopes(List.of("openid","profile"));
oidcTransaction.setPermittedScopes(List.of("openid","profile"));

oidcTransaction.setEssentialClaims(List.of("name"));
oidcTransaction.setVoluntaryClaims(List.of("email"));
Claims claims = new Claims();
Map<String, ClaimDetail> userinfo = new HashMap<>();
Map<String, ClaimDetail> id_token = new HashMap<>();
Expand Down Expand Up @@ -207,7 +247,9 @@ public void processConsent_withEmptyConsent_thenPass(){
OIDCTransaction oidcTransaction=new OIDCTransaction();
oidcTransaction.setClientId("abc");
oidcTransaction.setPartnerSpecificUserToken("123");

oidcTransaction.setVoluntaryClaims(List.of("email"));
oidcTransaction.setEssentialClaims(List.of());
oidcTransaction.setRequestedAuthorizeScopes(List.of());
UserConsentRequest userConsentRequest = new UserConsentRequest();
userConsentRequest.setClientId(oidcTransaction.getClientId());
userConsentRequest.setPsuToken(oidcTransaction.getPartnerSpecificUserToken());
Expand All @@ -218,4 +260,19 @@ public void processConsent_withEmptyConsent_thenPass(){
Assert.assertEquals(oidcTransaction.getConsentAction(),ConsentAction.CAPTURE);

}

@Test
public void processConsent_withEmptyRequestedClaims_thenPass(){
OIDCTransaction oidcTransaction=new OIDCTransaction();
oidcTransaction.setClientId("abc");
oidcTransaction.setPartnerSpecificUserToken("123");
oidcTransaction.setVoluntaryClaims(List.of());
oidcTransaction.setEssentialClaims(List.of());
oidcTransaction.setRequestedAuthorizeScopes(List.of());
UserConsentRequest userConsentRequest = new UserConsentRequest();
userConsentRequest.setClientId(oidcTransaction.getClientId());
userConsentRequest.setPsuToken(oidcTransaction.getPartnerSpecificUserToken());
consentHelperService.processConsent(oidcTransaction,true);
Assert.assertEquals(oidcTransaction.getConsentAction(),ConsentAction.NOCAPTURE);
}
}
Loading