diff --git a/src/main/java/biz/nynja/account/models/ContactInfo.java b/src/main/java/biz/nynja/account/models/ContactInfo.java index 6acc182a2d768f5a9373d2b0f33c18d18de41f88..a6c96b49eaf8f0ed421a2790a082419bdfb7ba86 100644 --- a/src/main/java/biz/nynja/account/models/ContactInfo.java +++ b/src/main/java/biz/nynja/account/models/ContactInfo.java @@ -3,6 +3,8 @@ */ package biz.nynja.account.models; +import java.io.Serializable; + import org.springframework.data.cassandra.core.mapping.UserDefinedType; import biz.nynja.account.grpc.ContactDetails; @@ -11,11 +13,12 @@ import biz.nynja.account.grpc.ContactType; import biz.nynja.account.phone.PhoneNumberUtils; @UserDefinedType -public class ContactInfo { +public class ContactInfo implements Serializable { private String type; private String value; private String label; + private String countrySelector; public String getType() { return type; @@ -41,6 +44,14 @@ public class ContactInfo { this.label = label; } + public String getCountrySelector() { + return countrySelector; + } + + public void setCountrySelector(String countrySelector) { + this.countrySelector = countrySelector; + } + @Override public int hashCode() { final int prime = 31; @@ -89,6 +100,7 @@ public class ContactInfo { contactInfo.setType(contactDetails.getType().toString()); contactInfo.setValue(contactDetails.getValue()); contactInfo.setLabel(contactDetails.getLabel()); + contactInfo.setCountrySelector(contactDetails.getCountrySelector()); return contactInfo; } diff --git a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java index a30e94f24183674a612d2282ae01aee797f923f5..d7bffb5e4754ff0d756c780645ead2407eddd9c7 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java @@ -200,18 +200,18 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio Transaction sagaTransaction = new SagaTransaction(cassandraTemplate); Account existingAccount = accountRepository.findByAccountId(UUID.fromString(request.getAccountId())); + if (existingAccount == null) { + logger.error("Existing account with the provided id {} was not found.", request.getAccountId()); + logger.debug("Existing account with the provided id {} was not found.", request.getAccountId()); + return null; + } + if (!permissionsValidator.isAdminToken()) { // No permission to update roles, load old ones Set roles = existingAccount.getRoles().stream().map(Role::valueOf).collect(Collectors.toSet()); request = UpdateAccountRequest.newBuilder(request).clearRoles().addAllRoles(roles).build(); } - - if (existingAccount == null) { - logger.error("Existing account with the provided id {} was not found.", request.getAccountId()); - logger.debug("Existing account with the provided id {} was not found.", request.getAccountId()); - return null; - } Long timeUpdated = Instant.now().toEpochMilli(); WriteResult wr = null; try { @@ -465,7 +465,7 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio } public Optional deleteProfile(UUID profileId) { - CassandraBatchOperations batchOperations = cassandraTemplate.batchOps(); + Transaction sagaTransaction = new SagaTransaction(cassandraTemplate); Profile existingProfile = profileRepository.findByProfileId(profileId); if (existingProfile == null) { logger.error("Error deleting profile. Existing profile with the provided id {} was not found.", profileId); @@ -479,22 +479,32 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio return Optional.of(Cause.ERROR_PERMISSION_DENIED); } - WriteResult wr = null; + WriteResult wr; try { - deleteProfileAccountsWhenDeletingProfile(batchOperations, existingAccountsForProfile); + deleteProfileAccountsWhenDeletingProfile(sagaTransaction, existingAccountsForProfile); if (existingProfile.getAuthenticationProviders() != null && existingProfile.getAuthenticationProviders().size() > 0) { - deleteAuthenticationProvidersFromProfile(batchOperations, existingProfile.getProfileId(), + deleteAuthenticationProvidersFromProfile(sagaTransaction, existingProfile.getProfileId(), existingProfile.getAuthenticationProviders()); } - deleteProfileData(batchOperations, existingProfile); - wr = batchOperations.execute(); + deleteProfileData(sagaTransaction, existingProfile); + wr = sagaTransaction.execute(); + if (!erlangAccountBridge.deleteProfile(existingProfile.getProfileId(), existingAccountsForProfile.stream() + .map(AccountByProfileId::getAccountId).collect(Collectors.toList()))) { + logger.error("Internal error with erlang"); + sagaTransaction.rollBack(); + return Optional.of(Cause.ERROR_DELETING_PROFILE); + } + } catch (StatusRuntimeException e) { + logger.info("Error while lose connection with bridge"); + sagaTransaction.rollBack(); + return Optional.of(Cause.ERROR_DELETING_PROFILE); } catch (IllegalArgumentException | IllegalStateException e) { logger.info("Exception while deleting account."); logger.debug("Exception while deleting account: {} ...", e.getMessage()); return Optional.of(Cause.ERROR_DELETING_PROFILE); } - if (wr != null && wr.wasApplied()) { + if (wr.wasApplied()) { return Optional.empty(); } return Optional.of(Cause.ERROR_DELETING_PROFILE); diff --git a/src/main/java/biz/nynja/account/services/AccountServiceImpl.java b/src/main/java/biz/nynja/account/services/AccountServiceImpl.java index 058737bb55d42b88f2ee988e885c406e67d9aee0..d33e6249e3dd11755c6190599b4571d11c2b2f3b 100644 --- a/src/main/java/biz/nynja/account/services/AccountServiceImpl.java +++ b/src/main/java/biz/nynja/account/services/AccountServiceImpl.java @@ -5,6 +5,7 @@ package biz.nynja.account.services; import static biz.nynja.account.validation.Validators.account; import static biz.nynja.account.validation.Validators.authenticationProvider; +import static biz.nynja.account.validation.Validators.pendingAccount; import static biz.nynja.account.validation.Validators.phoneValidator; import static biz.nynja.account.validation.Validators.util; @@ -456,14 +457,19 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas @Permitted(role = RoleConstants.USER) public void createPendingAccount(CreatePendingAccountRequest request, StreamObserver responseObserver) { + CreatePendingAccountResponse response; logger.info("Creating pending account..."); logger.debug("Creating pending account: {} ...", request); - CreatePendingAccountResponse response = accountCreator.retrieveCreatePendingAccountResponse(request); + Optional cause = pendingAccount.validateCreatePendingAccountRequest(request); + if (cause.isPresent()) { + response = CreatePendingAccountResponse.newBuilder().setError(ErrorResponse.newBuilder().setCause(cause.get())) + .build(); + } else { + response = accountCreator.retrieveCreatePendingAccountResponse(request); + } - logger.info("SUCCESS: Created pending account for provider {}: \"{}\"", request.getAuthenticationProvider(), - response); responseObserver.onNext(response); responseObserver.onCompleted(); } diff --git a/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java b/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java index 9123af320b46845f216fd640adba58e85373a228..794177b30e5cc52700a4557e75459cbaed50a831 100644 --- a/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java +++ b/src/main/java/biz/nynja/account/services/decomposition/AccountCreator.java @@ -3,13 +3,12 @@ */ package biz.nynja.account.services.decomposition; +import static biz.nynja.account.validation.Validators.pendingAccount; + import java.time.Instant; import java.util.Optional; import java.util.UUID; -import biz.nynja.account.phone.PhoneNumberNormalizer; -import biz.nynja.account.validation.Validation; -import biz.nynja.account.validation.Validators; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -27,11 +26,10 @@ import biz.nynja.account.models.Account; import biz.nynja.account.models.AuthenticationProvider; import biz.nynja.account.models.PendingAccount; import biz.nynja.account.models.PendingAccountByAuthenticationProvider; +import biz.nynja.account.phone.PhoneNumberNormalizer; import biz.nynja.account.repositories.AccountRepositoryAdditional; import biz.nynja.account.repositories.PendingAccountRepository; -import static biz.nynja.account.validation.Validators.pendingAccount; - @Service public class AccountCreator { @@ -55,11 +53,6 @@ public class AccountCreator { * @return */ public CreatePendingAccountResponse retrieveCreatePendingAccountResponse(CreatePendingAccountRequest request) { - Optional cause = pendingAccount.validateCreatePendingAccountRequest(request); - if (cause.isPresent()) { - return CreatePendingAccountResponse.newBuilder().setError(ErrorResponse.newBuilder().setCause(cause.get())) - .build(); - } if (request.getAuthenticationType() == AuthenticationType.PHONE) { // Get the normalized phone number from libphone @@ -82,12 +75,14 @@ public class AccountCreator { pendingAccount.setProfileId(UUID.randomUUID()); if (pendingAccountRepository.findByAccountId(pendingAccount.getAccountId()) != null || accountRepositoryAdditional.accountIdAlreadyUsed(pendingAccount.getAccountId())) { - logger.error("Can not create pending account. The account id {} is already used.", pendingAccount.getAccountId()); + logger.error("Can not create pending account. The account id {} is already used.", + pendingAccount.getAccountId()); return CreatePendingAccountResponse.newBuilder() .setError(ErrorResponse.newBuilder().setCause(Cause.INTERNAL_SERVER_ERROR)).build(); } if (accountRepositoryAdditional.profileIdAlreadyUsed(pendingAccount.getProfileId())) { - logger.error("Can not create pending account. The profile id {} is already used.", pendingAccount.getProfileId()); + logger.error("Can not create pending account. The profile id {} is already used.", + pendingAccount.getProfileId()); return CreatePendingAccountResponse.newBuilder() .setError(ErrorResponse.newBuilder().setCause(Cause.INTERNAL_SERVER_ERROR)).build(); } @@ -98,8 +93,8 @@ public class AccountCreator { logger.debug("Pending account \"{}\" saved into the DB", savedPendingAccount); response = CreatePendingAccountResponse.newBuilder().setPendingAccountDetails(savedPendingAccount.toProto()) .build(); - logger.info("Pending account created successfully."); - logger.debug("Pending account: \"{}\" created successfully.", response); + logger.info("SUCCESS: Pending account created successfully."); + logger.debug("SUCCESS: Pending account: \"{}\" created successfully.", response); return response; } catch (Exception e) { logger.error(e.getMessage()); @@ -151,9 +146,7 @@ public class AccountCreator { return response; } - if (request.getRolesList() == null || request.getRolesList().isEmpty()) { - request = CompletePendingAccountCreationRequest.newBuilder(request).addRoles(Role.USER).build(); - } + request = CompletePendingAccountCreationRequest.newBuilder(request).clearRoles().addRoles(Role.USER).build(); Account createdAccount = accountRepositoryAdditional.completePendingAccountCreation(request); diff --git a/src/main/java/biz/nynja/account/validation/Validators.java b/src/main/java/biz/nynja/account/validation/Validators.java index 21dc73cca84cc91da3fc83b7dfd5d5d0375b88a2..51ff76671da8914e949549d0cfbd0d50331fab11 100644 --- a/src/main/java/biz/nynja/account/validation/Validators.java +++ b/src/main/java/biz/nynja/account/validation/Validators.java @@ -143,13 +143,11 @@ public class Validators { if (!isContactInfoPhoneLabelValid(oldPhoneNumberLabel)) { validation.addError( - new ValidationError("Invalid phone label: " + oldPhoneNumberLabel, Cause.INVALID_PHONE_LABEL)); - return validation; + new ValidationError("Invalid old phone label: " + oldPhoneNumberLabel, Cause.INVALID_PHONE_LABEL)); } if (!isContactInfoPhoneLabelValid(editedPhoneNumberLabel)) { - validation.addError(new ValidationError("Invalid phone label: " + editedPhoneNumberLabel, + validation.addError(new ValidationError("Invalid new phone label: " + editedPhoneNumberLabel, Cause.INVALID_PHONE_LABEL)); - return validation; } return validation; @@ -453,9 +451,13 @@ public class Validators { logger.info("Checking email: {}", email); EmailValidator eValidator = EmailValidator.getInstance(); - boolean result = eValidator.isValid(email); - logger.info("Email: {} is " + (result ? "" : "not ") + "valid.", email); - return result; + boolean validated = eValidator.isValid(email); + if (!validated) { + logger.error("Email: {} is not valid.", email); + } else { + logger.info("Email: {} is valid.", email); + } + return validated; } public boolean validateBirthdayIsSet(Date birthday) { diff --git a/src/test/java/biz/nynja/account/services/AccountServiceTests.java b/src/test/java/biz/nynja/account/services/AccountServiceTests.java index 0f0386d6f8bc2cf33c0566b5e814e28418fafc22..919803c8623dab181f96bc474f327be5f7fab6ff 100644 --- a/src/test/java/biz/nynja/account/services/AccountServiceTests.java +++ b/src/test/java/biz/nynja/account/services/AccountServiceTests.java @@ -97,12 +97,7 @@ import biz.nynja.account.services.decomposition.IncorrectAccountCountException; import biz.nynja.account.services.decomposition.ProfileProvider; import biz.nynja.account.utils.GrpcServerTestBase; import biz.nynja.account.utils.Util; -import io.grpc.Context; -import io.grpc.Contexts; import io.grpc.Metadata; -import io.grpc.ServerCall; -import io.grpc.ServerCallHandler; -import io.grpc.ServerInterceptor; import io.grpc.stub.MetadataUtils; /** @@ -1510,8 +1505,8 @@ public class AccountServiceTests extends GrpcServerTestBase { final SearchResponse reply = searchServiceBlockingStub.searchByUsername(request); assertNotNull("Reply should not be null", reply); - assertTrue(String.format("Reply should contain cause '%s'", Cause.MULTIPLE_INVALID_PARAMETERS), - reply.getError().getCause().equals(Cause.MULTIPLE_INVALID_PARAMETERS)); + assertTrue(String.format("Reply should contain cause '%s'", Cause.MISSING_USERNAME), + reply.getError().getCause().equals(Cause.MISSING_USERNAME)); } @Test