diff --git a/app/controllers/AccountController.scala b/app/controllers/AccountController.scala index f87092f7..0d776313 100644 --- a/app/controllers/AccountController.scala +++ b/app/controllers/AccountController.scala @@ -128,7 +128,7 @@ class AccountController( def validateEmail() = Action.async(parse.json) { implicit request => for { token <- request.parseBody[String](JsPath \ "token") - user <- accessesOrchestrator.validateDGCCRFEmail(token) + user <- accessesOrchestrator.validateAgentEmail(token) cookie <- authenticator.init(user.email) match { case Right(value) => Future.successful(value) case Left(error) => Future.failed(error) diff --git a/app/controllers/error/AppError.scala b/app/controllers/error/AppError.scala index 116ae3bb..6ec4924a 100644 --- a/app/controllers/error/AppError.scala +++ b/app/controllers/error/AppError.scala @@ -36,11 +36,11 @@ object AppError { override val titleForLogs: String = "server_error" } - final case class DGCCRFActivationTokenNotFound(token: String) extends NotFoundError { + final case class AgentActivationTokenNotFound(token: String) extends NotFoundError { override val `type`: String = "SC-0002" - override val title: String = s"DGCCRF user token $token not found" + override val title: String = s"Agent user token $token not found" override val details: String = s"Le lien d'activation n'est pas valide ($token). Merci de contacter le support" - override val titleForLogs: String = "dgccrf_activation_token_not_found" + override val titleForLogs: String = "agent_activation_token_not_found" } final case class CompanyActivationTokenNotFound(token: String, siret: SIRET) extends NotFoundError { diff --git a/app/orchestrators/AccessesOrchestrator.scala b/app/orchestrators/AccessesOrchestrator.scala index 570f91d6..764078ac 100644 --- a/app/orchestrators/AccessesOrchestrator.scala +++ b/app/orchestrators/AccessesOrchestrator.scala @@ -182,7 +182,7 @@ class AccessesOrchestrator( .findToken(token) accessToken <- maybeAccessToken .map(Future.successful(_)) - .getOrElse(Future.failed[AccessToken](DGCCRFActivationTokenNotFound(token))) + .getOrElse(Future.failed[AccessToken](AgentActivationTokenNotFound(token))) _ = logger.debug("Validating email") emailTo <- accessToken.emailedTo @@ -325,12 +325,12 @@ class AccessesOrchestrator( ) } yield logger.debug(s"Sent email validation to ${user.email}") - def validateDGCCRFEmail(token: String): Future[User] = + def validateAgentEmail(token: String): Future[User] = for { accessToken <- accessTokenRepository.findToken(token) emailValidationToken <- accessToken .filter(_.kind == ValidateEmail) - .liftTo[Future](DGCCRFActivationTokenNotFound(token)) + .liftTo[Future](AgentActivationTokenNotFound(token)) emailTo <- emailValidationToken.emailedTo.liftTo[Future]( ServerError("ValidateEmailToken should have valid email associated") @@ -350,10 +350,10 @@ class AccessesOrchestrator( user <- userOrchestrator .findOrError(email) .ensure { - logger.error("Cannot revalidate user with role different from DGCCRF") + logger.error("Cannot revalidate user with role different from DGCCRF or DGAL") CantPerformAction - }(_.userRole == UserRole.DGCCRF) - _ = logger.debug(s"Validating DGCCRF user email") + }(user => user.userRole == UserRole.DGCCRF || user.userRole == UserRole.DGAL) + _ = logger.debug(s"Validating agent user email") _ <- if (emailValidationToken.nonEmpty) { emailValidationToken.map(accessTokenRepository.validateEmail(_, user)).sequence diff --git a/app/orchestrators/AuthOrchestrator.scala b/app/orchestrators/AuthOrchestrator.scala index 9bed8a16..5608803e 100644 --- a/app/orchestrators/AuthOrchestrator.scala +++ b/app/orchestrators/AuthOrchestrator.scala @@ -92,7 +92,7 @@ class AuthOrchestrator( _ = logger.debug(s"Found user (maybe deleted)") _ <- handleDeletedUser(user, userLogin) _ = logger.debug(s"Check last validation email for DGCCRF users") - _ <- validateDGCCRFAccountLastEmailValidation(user) + _ <- validateAgentAccountLastEmailValidation(user) _ = logger.debug(s"Successful login for user") cookie <- getCookie(userLogin)(request) _ = logger.debug(s"Successful generated token for user") @@ -180,8 +180,8 @@ class AuthOrchestrator( } } yield cookie - private def validateDGCCRFAccountLastEmailValidation(user: User): Future[User] = user.userRole match { - case UserRole.DGCCRF if needsEmailRevalidation(user) => + private def validateAgentAccountLastEmailValidation(user: User): Future[User] = user.userRole match { + case UserRole.DGCCRF | UserRole.DGAL if needsEmailRevalidation(user) => accessesOrchestrator .sendEmailValidation(user) .flatMap(_ => throw DGCCRFUserEmailValidationExpired(user.email.value)) diff --git a/app/repositories/user/UserRepository.scala b/app/repositories/user/UserRepository.scala index 533bcfe9..d62f26cd 100644 --- a/app/repositories/user/UserRepository.scala +++ b/app/repositories/user/UserRepository.scala @@ -2,6 +2,7 @@ package repositories.user import authentication.PasswordHasherRegistry import controllers.error.AppError.EmailAlreadyExist +import models.UserRole.DGAL import models.UserRole.DGCCRF import models._ import play.api.Logger @@ -36,29 +37,29 @@ class UserRepository( import dbConfig._ - override def listExpiredDGCCRF(expirationDate: OffsetDateTime): Future[List[User]] = + override def listExpiredAgents(expirationDate: OffsetDateTime): Future[List[User]] = db .run( table - .filter(_.role === DGCCRF.entryName) + .filter(user => user.role === DGCCRF.entryName || user.role === DGAL.entryName) .filter(_.lastEmailValidation <= expirationDate) .to[List] .result ) - override def listInactiveDGCCRFWithSentEmailCount( + override def listInactiveAgentsWithSentEmailCount( reminderDate: OffsetDateTime, expirationDate: OffsetDateTime ): Future[List[(User, Option[Int])]] = db.run( UserTable.table - .filter(_.role === DGCCRF.entryName) + .filter(user => user.role === DGCCRF.entryName || user.role === DGAL.entryName) .filter(_.lastEmailValidation <= reminderDate) .filter(_.lastEmailValidation > expirationDate) .joinLeft( EventTable.table - .filter(_.action === ActionEvent.EMAIL_INACTIVE_DGCCRF_ACCOUNT.value) - .filter(_.eventType === EventType.DGCCRF.value) + .filter(_.action === ActionEvent.EMAIL_INACTIVE_AGENT_ACCOUNT.value) + .filter(user => user.eventType === EventType.DGCCRF.value || user.eventType === EventType.DGAL.value) .filter(_.userId.isDefined) .groupBy(_.userId) .map { case (userId, results) => userId -> results.length } diff --git a/app/repositories/user/UserRepositoryInterface.scala b/app/repositories/user/UserRepositoryInterface.scala index 5f2fa2a0..a1ba04ed 100644 --- a/app/repositories/user/UserRepositoryInterface.scala +++ b/app/repositories/user/UserRepositoryInterface.scala @@ -11,9 +11,9 @@ import scala.concurrent.Future trait UserRepositoryInterface extends CRUDRepositoryInterface[User] { - def listExpiredDGCCRF(expirationDate: OffsetDateTime): Future[List[User]] + def listExpiredAgents(expirationDate: OffsetDateTime): Future[List[User]] - def listInactiveDGCCRFWithSentEmailCount( + def listInactiveAgentsWithSentEmailCount( reminderDate: OffsetDateTime, expirationDate: OffsetDateTime ): Future[List[(User, Option[Int])]] diff --git a/app/tasks/account/InactiveDgccrfAccountReminderTask.scala b/app/tasks/account/InactiveDgccrfAccountReminderTask.scala index c608cdc2..19c0c6c2 100644 --- a/app/tasks/account/InactiveDgccrfAccountReminderTask.scala +++ b/app/tasks/account/InactiveDgccrfAccountReminderTask.scala @@ -1,6 +1,7 @@ package tasks.account import models.User +import models.UserRole import models.event.Event import play.api.Logger import play.api.libs.json.Json @@ -35,11 +36,11 @@ class InactiveDgccrfAccountReminderTask( inactivePeriod: Period ): Future[Unit] = for { - firstReminderEvents <- userRepository.listInactiveDGCCRFWithSentEmailCount( + firstReminderEvents <- userRepository.listInactiveAgentsWithSentEmailCount( firstReminderThreshold, expirationDateThreshold ) - secondReminderEvents <- userRepository.listInactiveDGCCRFWithSentEmailCount( + secondReminderEvents <- userRepository.listInactiveAgentsWithSentEmailCount( secondReminderThreshold, expirationDateThreshold ) @@ -64,8 +65,8 @@ class InactiveDgccrfAccountReminderTask( None, Some(user.id), now, - EventType.DGCCRF, - ActionEvent.EMAIL_INACTIVE_DGCCRF_ACCOUNT, + if (user.userRole == UserRole.DGAL) EventType.DGAL else EventType.DGCCRF, + ActionEvent.EMAIL_INACTIVE_AGENT_ACCOUNT, Json.obj( "lastEmailValidation" -> user.lastEmailValidation, "expirationDate" -> expirationDate diff --git a/app/tasks/account/InactiveDgccrfAccountRemoveTask.scala b/app/tasks/account/InactiveDgccrfAccountRemoveTask.scala index e3f77abf..eb8aa6d9 100644 --- a/app/tasks/account/InactiveDgccrfAccountRemoveTask.scala +++ b/app/tasks/account/InactiveDgccrfAccountRemoveTask.scala @@ -28,7 +28,7 @@ class InactiveDgccrfAccountRemoveTask( logger.info(s"Soft delete inactive DGCCRF accounts with last validation below $expirationDateThreshold") for { - inactiveDGCCRFAccounts <- userRepository.listExpiredDGCCRF(expirationDateThreshold) + inactiveDGCCRFAccounts <- userRepository.listExpiredAgents(expirationDateThreshold) results <- inactiveDGCCRFAccounts.map(removeWithSubscriptions).sequence } yield results.sequence } diff --git a/app/utils/Constants.scala b/app/utils/Constants.scala index 73cd15df..647d19e5 100644 --- a/app/utils/Constants.scala +++ b/app/utils/Constants.scala @@ -112,7 +112,7 @@ object Constants { object USER_DELETION extends ActionEventValue("Suppression d'un utilisateur") - object EMAIL_INACTIVE_DGCCRF_ACCOUNT extends ActionEventValue("Email «compte inactif» envoyé à l'agent") + object EMAIL_INACTIVE_AGENT_ACCOUNT extends ActionEventValue("Email «compte inactif» envoyé à l'agent") object CONSUMER_THREATEN_BY_PRO extends ActionEventValue("ConsumerThreatenByProReportDeletion") object REFUND_BLACKMAIL extends ActionEventValue("RefundBlackMailReportDeletion") diff --git a/test/models/UserRoleTest.scala b/test/models/UserRoleTest.scala index 4cd28573..cba3cea9 100644 --- a/test/models/UserRoleTest.scala +++ b/test/models/UserRoleTest.scala @@ -12,6 +12,7 @@ class UserRoleTest extends Specification { "get value from string name" in { UserRole.withName("DGCCRF") shouldEqual UserRole.DGCCRF + UserRole.withName("DGAL") shouldEqual UserRole.DGAL UserRole.withName("Admin") shouldEqual UserRole.Admin UserRole.withName("Professionnel") shouldEqual UserRole.Professionnel Try(UserRole.withName("XXXXXXXXXX")).isFailure shouldEqual true diff --git a/test/orchestrators/AccessesOrchestratorTest.scala b/test/orchestrators/AccessesOrchestratorTest.scala index 8cf89d0f..5d6bf677 100644 --- a/test/orchestrators/AccessesOrchestratorTest.scala +++ b/test/orchestrators/AccessesOrchestratorTest.scala @@ -95,7 +95,7 @@ class AccessesOrchestratorTest extends Specification with AppSpec { "email validation should fail when token not found" >> { val unknownToken = "" components.accessesOrchestrator - .validateDGCCRFEmail(unknownToken) must throwA[DGCCRFActivationTokenNotFound].await + .validateAgentEmail(unknownToken) must throwA[AgentActivationTokenNotFound].await } "email validation should fail when no validation email token found" >> { @@ -109,11 +109,11 @@ class AccessesOrchestratorTest extends Specification with AppSpec { ) val result = for { _ <- components.accessTokenRepository.create(nonRelevantToken) - res <- components.accessesOrchestrator.validateDGCCRFEmail(nonRelevantToken.token) + res <- components.accessesOrchestrator.validateAgentEmail(nonRelevantToken.token) } yield res - result must throwA[DGCCRFActivationTokenNotFound].await + result must throwA[AgentActivationTokenNotFound].await } "email validation should fail when validation email token found not link to any email" >> { @@ -128,7 +128,7 @@ class AccessesOrchestratorTest extends Specification with AppSpec { val result = for { _ <- components.accessTokenRepository.create(invalidValidationEmailToken) - res <- components.accessesOrchestrator.validateDGCCRFEmail(invalidValidationEmailToken.token) + res <- components.accessesOrchestrator.validateAgentEmail(invalidValidationEmailToken.token) } yield res @@ -147,7 +147,7 @@ class AccessesOrchestratorTest extends Specification with AppSpec { val result = for { _ <- components.accessTokenRepository.create(validationEmailToken) - res <- components.accessesOrchestrator.validateDGCCRFEmail(validationEmailToken.token) + res <- components.accessesOrchestrator.validateAgentEmail(validationEmailToken.token) } yield res @@ -170,7 +170,7 @@ class AccessesOrchestratorTest extends Specification with AppSpec { val result = for { _ <- components.accessTokenRepository.create(validationEmailToken) _ <- components.userRepository.create(dgccrfUser) - res <- components.accessesOrchestrator.validateDGCCRFEmail(validationEmailToken.token) + res <- components.accessesOrchestrator.validateAgentEmail(validationEmailToken.token) } yield res diff --git a/test/repositories/UserRepositorySpec.scala b/test/repositories/UserRepositorySpec.scala index d36b5c84..033cde3a 100644 --- a/test/repositories/UserRepositorySpec.scala +++ b/test/repositories/UserRepositorySpec.scala @@ -64,7 +64,7 @@ class UserRepositorySpec(implicit ee: ExecutionEnv) extends Specification with A userId = Some(inactiveDgccrfUserWithEmails.id), creationDate = now, eventType = EventType.DGCCRF, - action = ActionEvent.EMAIL_INACTIVE_DGCCRF_ACCOUNT, + action = ActionEvent.EMAIL_INACTIVE_AGENT_ACCOUNT, details = Json.obj() ) ), @@ -79,7 +79,7 @@ class UserRepositorySpec(implicit ee: ExecutionEnv) extends Specification with A userId = Some(inactiveDgccrfUserWithEmails.id), creationDate = now, eventType = EventType.DGCCRF, - action = ActionEvent.EMAIL_INACTIVE_DGCCRF_ACCOUNT, + action = ActionEvent.EMAIL_INACTIVE_AGENT_ACCOUNT, details = Json.obj() ) ), @@ -113,12 +113,12 @@ class UserRepositorySpec(implicit ee: ExecutionEnv) extends Specification with A def e4 = userRepository.get(userToto.id).map(_.isDefined) must beFalse.await def e6 = userRepository - .listInactiveDGCCRFWithSentEmailCount(now.minusMonths(1), now.minusYears(1)) + .listInactiveAgentsWithSentEmailCount(now.minusMonths(1), now.minusYears(1)) .map(_.map { case (user, count) => (user.id, count) }) must beEqualTo( List(inactiveDgccrfUser.id -> None, inactiveDgccrfUserWithEmails.id -> Some(2)) ).await def e7 = userRepository - .listInactiveDGCCRFWithSentEmailCount(now.minusMonths(1), now.minusMonths(2)) must beEmpty[List[ + .listInactiveAgentsWithSentEmailCount(now.minusMonths(1), now.minusMonths(2)) must beEmpty[List[ (User, Option[Int]) ]].await diff --git a/test/tasks/account/InactiveDgccrfAccountReminderTaskSpec.scala b/test/tasks/account/InactiveDgccrfAccountReminderTaskSpec.scala index 0a360f42..96fda97b 100644 --- a/test/tasks/account/InactiveDgccrfAccountReminderTaskSpec.scala +++ b/test/tasks/account/InactiveDgccrfAccountReminderTaskSpec.scala @@ -82,21 +82,21 @@ class InactiveDgccrfAccountReminderTaskSpec(implicit ee: ExecutionEnv) Some(firstMailToSendUser.id), OffsetDateTime.now(), EventType.DGCCRF, - ActionEvent.EMAIL_INACTIVE_DGCCRF_ACCOUNT, + ActionEvent.EMAIL_INACTIVE_AGENT_ACCOUNT, Json.obj() ) - when(mockUserRepository.listInactiveDGCCRFWithSentEmailCount(firstReminder, expiration)) + when(mockUserRepository.listInactiveAgentsWithSentEmailCount(firstReminder, expiration)) .thenReturn(Future.successful(List(firstMailToSendUser -> None))) - when(mockUserRepository.listInactiveDGCCRFWithSentEmailCount(secondReminder, expiration)) + when(mockUserRepository.listInactiveAgentsWithSentEmailCount(secondReminder, expiration)) .thenReturn(Future.successful(List.empty)) when(mockEventRepository.create(any[Event]())).thenReturn(Future.successful(event)) val test = new InactiveDgccrfAccountReminderTask(mockUserRepository, mockEventRepository, mailService) test.sendReminderEmail(firstReminder, secondReminder, expiration, Period.ofYears(1)) must beEqualTo(()).await - there was one(mockUserRepository).listInactiveDGCCRFWithSentEmailCount(firstReminder, expiration) - there was one(mockUserRepository).listInactiveDGCCRFWithSentEmailCount(secondReminder, expiration) + there was one(mockUserRepository).listInactiveAgentsWithSentEmailCount(firstReminder, expiration) + there was one(mockUserRepository).listInactiveAgentsWithSentEmailCount(secondReminder, expiration) there was one(mockEventRepository).create(any[Event]()) there was one(mockMailRetriesService).sendEmailWithRetries(any[EmailRequest]()) }