diff --git a/src/inttest/java/com/faforever/api/data/BanInfoTest.java b/src/inttest/java/com/faforever/api/data/BanInfoTest.java index 9b5e2de59..ca7ccb5ab 100644 --- a/src/inttest/java/com/faforever/api/data/BanInfoTest.java +++ b/src/inttest/java/com/faforever/api/data/BanInfoTest.java @@ -1,9 +1,13 @@ package com.faforever.api.data; import com.faforever.api.AbstractIntegrationTest; +import com.faforever.api.email.EmailSender; import com.faforever.api.player.PlayerRepository; import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.Sql.ExecutionPhase; @@ -39,16 +43,18 @@ public class BanInfoTest extends AbstractIntegrationTest { "player": { "data": { "type": "player", - "id": "3" + "id": "2" } } } } } */ - private static final String testPost = "{\"data\":{\"type\":\"banInfo\",\"attributes\":{\"level\":\"CHAT\",\"reason\":\"This test ban should be revoked\"},\"relationships\":{\"author\":{\"data\":{\"type\":\"player\",\"id\":\"1\"}},\"player\":{\"data\":{\"type\":\"player\",\"id\":\"3\"}}}}}"; + private static final String testPost = "{\"data\":{\"type\":\"banInfo\",\"attributes\":{\"level\":\"CHAT\",\"reason\":\"This test ban should be revoked\"},\"relationships\":{\"author\":{\"data\":{\"type\":\"player\",\"id\":\"2\"}},\"player\":{\"data\":{\"type\":\"player\",\"id\":\"3\"}}}}}"; @Autowired PlayerRepository playerRepository; + @MockBean + private EmailSender emailSender; @Test @WithUserDetails(AUTH_USER) @@ -98,5 +104,11 @@ public void canCreateBanInfoAsModerator() throws Exception { .andExpect(status().isCreated()); assertThat(playerRepository.getOne(3).getBans().size(), is(1)); + Mockito.verify(emailSender).sendMail(ArgumentMatchers.eq("integration-test@faforever.com"), + ArgumentMatchers.eq("integration-test@faforever.com"), + ArgumentMatchers.eq("admin@faforever.com"), + ArgumentMatchers.eq("ban subject"), + ArgumentMatchers.matches("Hello ADMIN,\\|Your account was banned\\|Reason - This test ban should be revoked\\|Banner - MODERATOR\\|Time - (.)*\\|Type - CHAT\\|Expires - never\\|Thank you for your fairness and acceptance[.]") + ); } } diff --git a/src/inttest/java/com/faforever/api/data/BanRevokeElideTest.java b/src/inttest/java/com/faforever/api/data/BanRevokeElideTest.java new file mode 100644 index 000000000..9b9ead23d --- /dev/null +++ b/src/inttest/java/com/faforever/api/data/BanRevokeElideTest.java @@ -0,0 +1,47 @@ +package com.faforever.api.data; + +import com.faforever.api.AbstractIntegrationTest; +import com.faforever.api.data.domain.BanStatus; +import com.faforever.api.email.EmailSender; +import com.faforever.api.player.PlayerRepository; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithUserDetails; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.Sql.ExecutionPhase; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepDefaultUser.sql") +@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepBanRevokeData.sql") +@Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:sql/cleanBanRevokeData.sql") +public class BanRevokeElideTest extends AbstractIntegrationTest { + @MockBean + private EmailSender emailSender; + @Autowired + private PlayerRepository playerRepository; + /* +{"data":{"type":"banRevokeData","attributes":{"reason":"unban"},"relationships":{"ban":{"data":{"type":"banInfo","id":"1"}},"author":{"data":{"type":"player","id":"2"}}}}} */ + private static final String TEST_REVOKE="{\"data\":{\"type\":\"banRevokeData\",\"attributes\":{\"reason\":\"unban\"},\"relationships\":{\"ban\":{\"data\":{\"type\":\"banInfo\",\"id\":\"1\"}},\"author\":{\"data\":{\"type\":\"player\",\"id\":\"2\"}}}}}"; + + @Ignore(value = "Posting of ban revokes never worked, moderator use to change expire date instead see issue #259") + @WithUserDetails(AUTH_MODERATOR) + @Test + public void testRevokeBanWithId1() throws Exception { + assertThat(playerRepository.getOne(4).getBans().size(), is(1)); + assertThat(playerRepository.getOne(4).getBans().iterator().next().getBanStatus(), is(BanStatus.BANNED)); + + mockMvc.perform(post("/data/banRevokeData") + .content(TEST_REVOKE)) + .andExpect(status().isCreated()); + + assertThat(playerRepository.getOne(4).getBans().iterator().next().getBanStatus(), is(BanStatus.DISABLED)); + Mockito.verify(emailSender).sendMail("","","","",""); + } +} diff --git a/src/inttest/resources/config/application.yml b/src/inttest/resources/config/application.yml index 2cb9f847c..aca2c37e9 100644 --- a/src/inttest/resources/config/application.yml +++ b/src/inttest/resources/config/application.yml @@ -66,6 +66,14 @@ faf-api: mautic: client-id: banana client-secret: banana + username-change: + mail-body: ${USERNAME_CHANGE_EMAIL_BODY:Hello {0},| your username changed to {1}} + mail-subject: ${USERNAME_CHANGE_EMAIL_SUBJECT:Username changed} + ban: + ban-mail-body: ${BAN_EMAIL_BODY:Hello {0},|Your account was banned|Reason - {1}|Banner - {2}|Time - {3}|Type - {4}|Expires - {5}|Thank you for your fairness and acceptance.} + ban-mail-subject: ${BAN_EMAIL_SUBJECT:ban subject} + ban-revoke-mail-body: ${BAN_REVOKE_EMAIL_BODY:Hello {0},|Your account was been unbanned.|Moderator that unbanned you - {1}|Reason - {2}|Original reason of the ban - {3}|original banner - {4}|Time of original ban - {5}.|Thank you for your fairness and acceptance.} + ban-revoke-mail-subject: ${BAN_REVOKE_EMAIL_SUBJECT:email ban revoke subject} logging: diff --git a/src/inttest/resources/sql/cleanBanRevokeData.sql b/src/inttest/resources/sql/cleanBanRevokeData.sql new file mode 100644 index 000000000..1b908592f --- /dev/null +++ b/src/inttest/resources/sql/cleanBanRevokeData.sql @@ -0,0 +1,2 @@ +DELETE FROM ban_revoke; +DELETE FROM ban; diff --git a/src/inttest/resources/sql/prepBanData.sql b/src/inttest/resources/sql/prepBanData.sql index 8e71d7bcb..4e18526d2 100644 --- a/src/inttest/resources/sql/prepBanData.sql +++ b/src/inttest/resources/sql/prepBanData.sql @@ -5,9 +5,9 @@ INSERT INTO login (id, login, email, password) VALUES (4, 'BANNED', 'banned@faforever.com', 'not relevant'); INSERT INTO ban (id, player_id, author_id, reason, expires_at, level) VALUES - (1, 4, 1, 'Test permaban', DATE_ADD(NOW(), INTERVAL 1 DAY), 'GLOBAL'), - (2, 2, 1, 'To be revoked ban', DATE_ADD(NOW(), INTERVAL 1 DAY), 'GLOBAL'); + (1, 4, 2, 'Test permaban', DATE_ADD(NOW(), INTERVAL 1 DAY), 'GLOBAL'), + (2, 2, 2, 'To be revoked ban', DATE_ADD(NOW(), INTERVAL 1 DAY), 'GLOBAL'); INSERT INTO ban_revoke (ban_id, reason, author_id) VALUES - (2, 'Test revoke', 1); + (2, 'Test revoke', 2); diff --git a/src/inttest/resources/sql/prepBanRevokeData.sql b/src/inttest/resources/sql/prepBanRevokeData.sql new file mode 100644 index 000000000..a877eb06e --- /dev/null +++ b/src/inttest/resources/sql/prepBanRevokeData.sql @@ -0,0 +1,8 @@ +DELETE FROM ban_revoke; +DELETE FROM ban; + +INSERT INTO login (id, login, email, password) VALUES + (4, 'BANNED', 'banned@faforever.com', 'not relevant'); + +INSERT INTO ban (id, player_id, author_id, reason, expires_at, level) VALUES + (1, 4, 2, 'Test permaban', DATE_ADD(NOW(), INTERVAL 1 DAY), 'GLOBAL'); diff --git a/src/main/java/com/faforever/api/config/FafApiProperties.java b/src/main/java/com/faforever/api/config/FafApiProperties.java index 1a9969406..f5d1a277d 100644 --- a/src/main/java/com/faforever/api/config/FafApiProperties.java +++ b/src/main/java/com/faforever/api/config/FafApiProperties.java @@ -39,6 +39,8 @@ public class FafApiProperties { private Anope anope = new Anope(); private Rating rating = new Rating(); private Tutorial tutorial = new Tutorial(); + private UsernameChange usernameChange = new UsernameChange(); + private Ban ban = new Ban(); @Data public static class OAuth2 { @@ -250,4 +252,18 @@ public class Rating { public static class Tutorial { private String thumbnailUrlFormat; } + + @Data + public class UsernameChange { + private String mailBody; + private String mailSubject; + } + + @Data + public class Ban { + private String banMailBody; + private String banMailSubject; + private String banRevokeMailBody; + private String banRevokeMailSubject; + } } diff --git a/src/main/java/com/faforever/api/config/elide/ElideConfig.java b/src/main/java/com/faforever/api/config/elide/ElideConfig.java index c5ae46189..ae52bf4aa 100644 --- a/src/main/java/com/faforever/api/config/elide/ElideConfig.java +++ b/src/main/java/com/faforever/api/config/elide/ElideConfig.java @@ -8,10 +8,15 @@ import com.faforever.api.data.checks.permission.HasBanUpdate; import com.faforever.api.data.checks.permission.HasLadder1v1Update; import com.faforever.api.data.checks.permission.IsModerator; +import com.faforever.api.data.domain.BanInfo; +import com.faforever.api.data.domain.BanRevokeData; +import com.faforever.api.data.listeners.BanInfoPostCreateListener; +import com.faforever.api.data.listeners.BanRevokePostCreateListener; import com.faforever.api.security.ExtendedAuditLogger; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.elide.Elide; import com.yahoo.elide.ElideSettingsBuilder; +import com.yahoo.elide.annotation.OnCreatePostCommit; import com.yahoo.elide.core.EntityDictionary; import com.yahoo.elide.core.filter.dialect.RSQLFilterDialect; import com.yahoo.elide.jsonapi.JsonApiMapper; @@ -37,18 +42,22 @@ public class ElideConfig { public static final String DEFAULT_CACHE_NAME = "Elide.defaultCache"; @Bean - public Elide elide(SpringHibernateDataStore springHibernateDataStore, ObjectMapper objectMapper, EntityDictionary entityDictionary, ExtendedAuditLogger extendedAuditLogger) { + public Elide elide(SpringHibernateDataStore springHibernateDataStore, ObjectMapper objectMapper, EntityDictionary entityDictionary, + ExtendedAuditLogger extendedAuditLogger, BanInfoPostCreateListener banInfoPostCreateListener, BanRevokePostCreateListener banRevokePostCreateListener) { RSQLFilterDialect rsqlFilterDialect = new RSQLFilterDialect(entityDictionary); registerAdditionalConverters(); - return new Elide(new ElideSettingsBuilder(springHibernateDataStore) + Elide elide = new Elide(new ElideSettingsBuilder(springHibernateDataStore) .withJsonApiMapper(new JsonApiMapper(entityDictionary, objectMapper)) .withAuditLogger(extendedAuditLogger) .withEntityDictionary(entityDictionary) .withJoinFilterDialect(rsqlFilterDialect) .withSubqueryFilterDialect(rsqlFilterDialect) .build()); + entityDictionary.bindTrigger(BanInfo.class, OnCreatePostCommit.class, banInfoPostCreateListener); + entityDictionary.bindTrigger(BanRevokeData.class, OnCreatePostCommit.class, banRevokePostCreateListener); + return elide; } @Bean diff --git a/src/main/java/com/faforever/api/data/listeners/BanInfoPostCreateListener.java b/src/main/java/com/faforever/api/data/listeners/BanInfoPostCreateListener.java new file mode 100644 index 000000000..936db016b --- /dev/null +++ b/src/main/java/com/faforever/api/data/listeners/BanInfoPostCreateListener.java @@ -0,0 +1,44 @@ +package com.faforever.api.data.listeners; + +import com.faforever.api.data.domain.BanDurationType; +import com.faforever.api.data.domain.BanInfo; +import com.faforever.api.data.domain.Player; +import com.faforever.api.email.EmailService; +import com.yahoo.elide.functions.LifeCycleHook; +import com.yahoo.elide.security.RequestScope; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; +import javax.validation.constraints.NotNull; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + +@Component +@Slf4j +public class BanInfoPostCreateListener implements LifeCycleHook { + + private final EmailService emailService; + + @Inject + public BanInfoPostCreateListener(EmailService emailService) { + this.emailService = emailService; + } + + @Override + public void execute(BanInfo elideEntity, RequestScope requestScope, Optional changes) { + try { + @NotNull Player player = elideEntity.getPlayer(); + emailService.sendBanMail(player.getEmail(), + player.getLogin(), + elideEntity.getReason(), + elideEntity.getAuthor().getLogin(), + OffsetDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME), + elideEntity.getLevel().name(), + elideEntity.getDuration() == BanDurationType.PERMANENT ? "never" : elideEntity.getExpiresAt().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); + } catch (Exception e) { + log.error("Sending ban email failed", e); + } + } +} diff --git a/src/main/java/com/faforever/api/data/listeners/BanRevokePostCreateListener.java b/src/main/java/com/faforever/api/data/listeners/BanRevokePostCreateListener.java new file mode 100644 index 000000000..beea122f3 --- /dev/null +++ b/src/main/java/com/faforever/api/data/listeners/BanRevokePostCreateListener.java @@ -0,0 +1,42 @@ +package com.faforever.api.data.listeners; + +import com.faforever.api.data.domain.BanInfo; +import com.faforever.api.data.domain.BanRevokeData; +import com.faforever.api.data.domain.Player; +import com.faforever.api.email.EmailService; +import com.yahoo.elide.functions.LifeCycleHook; +import com.yahoo.elide.security.ChangeSpec; +import com.yahoo.elide.security.RequestScope; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.validation.constraints.NotNull; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + +@Slf4j +@Component +public class BanRevokePostCreateListener implements LifeCycleHook { + private final EmailService emailService; + + public BanRevokePostCreateListener(EmailService emailService) { + this.emailService = emailService; + } + + @Override + public void execute(BanRevokeData banRevoke, RequestScope requestScope, Optional changes) { + try { + @NotNull BanInfo ban = banRevoke.getBan(); + @NotNull Player player = ban.getPlayer(); + emailService.sendBanRevokeMail(player.getEmail(), + player.getLogin(), + banRevoke.getAuthor().getLogin(), + banRevoke.getReason(), + ban.getReason(), + ban.getAuthor().getLogin(), + ban.getCreateTime().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); + } catch (Exception e) { + log.error("Failed to send ban revoke email", e); + } + } +} diff --git a/src/main/java/com/faforever/api/email/EmailService.java b/src/main/java/com/faforever/api/email/EmailService.java index 840c909d3..1c17c64b8 100644 --- a/src/main/java/com/faforever/api/email/EmailService.java +++ b/src/main/java/com/faforever/api/email/EmailService.java @@ -1,8 +1,10 @@ package com.faforever.api.email; import com.faforever.api.config.FafApiProperties; +import com.faforever.api.config.FafApiProperties.Ban; import com.faforever.api.config.FafApiProperties.PasswordReset; import com.faforever.api.config.FafApiProperties.Registration; +import com.faforever.api.config.FafApiProperties.UsernameChange; import com.faforever.api.error.ApiException; import com.faforever.api.error.Error; import com.faforever.api.error.ErrorCode; @@ -53,6 +55,43 @@ public void sendActivationMail(String username, String email, String activationU ); } + @SneakyThrows + public void sendUsernameChangeMail(String email, String oldUsername, String newUsername) { + UsernameChange usernameChange = properties.getUsernameChange(); + emailSender.sendMail( + properties.getMail().getFromEmailAddress(), + properties.getMail().getFromEmailName(), + email, + usernameChange.getMailSubject(), + MessageFormat.format(usernameChange.getMailBody(), oldUsername, newUsername) + ); + } + + + @SneakyThrows + public void sendBanMail(String email, String username, String reason, String banner, String createTime, String type, String expires) { + Ban ban = properties.getBan(); + emailSender.sendMail( + properties.getMail().getFromEmailAddress(), + properties.getMail().getFromEmailName(), + email, + ban.getBanMailSubject(), + MessageFormat.format(ban.getBanMailBody(), username, reason, banner, createTime, type, expires) + ); + } + + @SneakyThrows + public void sendBanRevokeMail(String email, String username, String moderatorThatRevoked, String reasonForRevoke, String reasonForBan, String banner, String banCreateTime) { + Ban ban = properties.getBan(); + emailSender.sendMail( + properties.getMail().getFromEmailAddress(), + properties.getMail().getFromEmailName(), + email, + ban.getBanRevokeMailSubject(), + MessageFormat.format(ban.getBanRevokeMailBody(), username, moderatorThatRevoked, reasonForRevoke, reasonForBan, banner, banCreateTime) + ); + } + @SneakyThrows public void sendPasswordResetMail(String username, String email, String passwordResetUrl) { PasswordReset passwordReset = properties.getPasswordReset(); diff --git a/src/main/java/com/faforever/api/user/UserService.java b/src/main/java/com/faforever/api/user/UserService.java index 9f98109e7..51876d43e 100644 --- a/src/main/java/com/faforever/api/user/UserService.java +++ b/src/main/java/com/faforever/api/user/UserService.java @@ -190,15 +190,15 @@ public void changeLogin(String newLogin, User user, String ipAddress) { throw new ApiException(new Error(ErrorCode.USERNAME_RESERVED, newLogin, usernameReservationTimeInMonths)); } }); - + String oldLogin = user.getLogin(); log.debug("Changing username for user ''{}'' to ''{}''", user, newLogin); NameRecord nameRecord = new NameRecord() - .setName(user.getLogin()) + .setName(oldLogin) .setPlayer(playerRepository.getOne(user.getId())); nameRecordRepository.save(nameRecord); - user.setLogin(newLogin); + emailService.sendUsernameChangeMail(user.getEmail(), oldLogin, newLogin); createOrUpdateMauticContact(userRepository.save(user), ipAddress); } diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml index 94dca97fa..fff99845b 100644 --- a/src/main/resources/config/application-dev.yml +++ b/src/main/resources/config/application-dev.yml @@ -49,6 +49,14 @@ faf-api: api-key: ${STEAM_API_KEY:banana} link-to-steam: steam-redirect-url-format: ${STEAM_LINK_REDIRECT_URL:http://localhost:8010/users/linkToSteam?token=%s} + username-change: + mail-body: ${USERNAME_CHANGE_EMAIL_BODY:Hello {0},| your username changed to {1}} + mail-subject: ${USERNAME_CHANGE_EMAIL_SUBJECT:Username changed} + ban: + ban-mail-body: ${BAN_EMAIL_BODY:Hello {0},|Your account was banned|Reason - {1}|Banner - {2}|Time - {3}|Type - {4}|Expires - {5}|Thank you for your fairness and acceptance.} + ban-mail-subject: ${BAN_EMAIL_SUBJECT:ban subject} + ban-revoke-mail-body: ${BAN_REVOKE_EMAIL_BODY:Hello {0},|Your account was been unbanned.|Moderator that unbanned you - {1}|Reason - {2}|Original reason of the ban - {3}|original banner - {4}|Time of original ban - {5}.|Thank you for your fairness and acceptance.} + ban-revoke-mail-subject: ${BAN_REVOKE_EMAIL_SUBJECT:email ban revoke subject} spring: datasource: diff --git a/src/main/resources/config/application-prod.yml b/src/main/resources/config/application-prod.yml index 5f2e5788b..f78ecafdf 100644 --- a/src/main/resources/config/application-prod.yml +++ b/src/main/resources/config/application-prod.yml @@ -51,6 +51,14 @@ faf-api: api-key: ${STEAM_API_KEY} link-to-steam: steam-redirect-url-format: ${STEAM_LINK_REDIRECT_URL} + username-change: + mail-body: ${USERNAME_CHANGE_EMAIL_BODY} + mail-subject: ${USERNAME_CHANGE_EMAIL_SUBJECT} + ban: + ban-mail-body: ${BAN_EMAIL_BODY} + ban-mail-subject: ${BAN_EMAIL_SUBJECT} + ban-revoke-mail-body: ${BAN_REVOKE_EMAIL_BODY} + ban-revoke-mail-subject: ${BAN_REVOKE_EMAIL_SUBJECT} spring: datasource: diff --git a/src/test/java/com/faforever/api/email/EmailServiceTest.java b/src/test/java/com/faforever/api/email/EmailServiceTest.java index 7e18dbc02..dcb575aec 100644 --- a/src/test/java/com/faforever/api/email/EmailServiceTest.java +++ b/src/test/java/com/faforever/api/email/EmailServiceTest.java @@ -1,8 +1,10 @@ package com.faforever.api.email; import com.faforever.api.config.FafApiProperties; +import com.faforever.api.config.FafApiProperties.Ban; import com.faforever.api.config.FafApiProperties.PasswordReset; import com.faforever.api.config.FafApiProperties.Registration; +import com.faforever.api.config.FafApiProperties.UsernameChange; import com.faforever.api.error.ApiExceptionWithCode; import com.faforever.api.error.ErrorCode; import org.junit.Before; @@ -31,7 +33,7 @@ public class EmailServiceTest { private EmailSender emailSender; @Before - public void setUp() throws Exception { + public void setUp() { properties = new FafApiProperties(); properties.getMail().setFromEmailAddress("foo@bar.com"); properties.getMail().setFromEmailName("foobar"); @@ -40,24 +42,24 @@ public void setUp() throws Exception { } @Test - public void validateEmailAddress() throws Exception { + public void validateEmailAddress() { instance.validateEmailAddress("test@example.com"); } @Test - public void validateEmailAddressMissingAt() throws Exception { + public void validateEmailAddressMissingAt() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.EMAIL_INVALID)); instance.validateEmailAddress("testexample.com"); } @Test - public void validateEmailAddressMissingTld() throws Exception { + public void validateEmailAddressMissingTld() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.EMAIL_INVALID)); instance.validateEmailAddress("test@example"); } @Test - public void validateEmailAddressBlacklisted() throws Exception { + public void validateEmailAddressBlacklisted() { when(domainBlacklistRepository.existsByDomain("example.com")).thenReturn(true); expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.EMAIL_BLACKLISTED)); @@ -65,7 +67,7 @@ public void validateEmailAddressBlacklisted() throws Exception { } @Test - public void sendActivationMail() throws Exception { + public void sendActivationMail() { Registration registration = properties.getRegistration(); registration.setSubject("Hello"); registration.setHtmlFormat("Hello {0}, bla: {1}"); @@ -75,6 +77,39 @@ public void sendActivationMail() throws Exception { verify(emailSender).sendMail("foo@bar.com", "foobar", "junit@example.com", "Hello", "Hello junit, bla: http://example.com"); } + @Test + public void sendUsernameChangeMail() { + UsernameChange usernameChange = properties.getUsernameChange(); + usernameChange.setMailSubject("Hello"); + usernameChange.setMailBody("Hello {0}, you changed your name to: {1}"); + + instance.sendUsernameChangeMail("alex@gmail.com", "axel12", "phil12"); + + verify(emailSender).sendMail("foo@bar.com", "foobar", "alex@gmail.com", "Hello", "Hello axel12, you changed your name to: phil12"); + } + + @Test + public void sendBanMail() { + Ban ban = properties.getBan(); + ban.setBanMailSubject("Hello"); + ban.setBanMailBody("Hello {0},\nYour account was banned\nReason - {1}\nBanner - {2}\nTime - {3}\nType - {4}\nExpires - {5}.\nThank you for your fairness and acceptance."); + + instance.sendBanMail("alex@gmail.com", "axel12", "reason","banner","createTime","type","expires"); + + verify(emailSender).sendMail("foo@bar.com", "foobar", "alex@gmail.com", "Hello", "Hello axel12,\nYour account was banned\nReason - reason\nBanner - banner\nTime - createTime\nType - type\nExpires - expires.\nThank you for your fairness and acceptance."); + } + + @Test + public void sendBanRevokeMail() { + Ban ban = properties.getBan(); + ban.setBanRevokeMailSubject("Hello"); + ban.setBanRevokeMailBody("Hello {0},\nYour account was been unbanned.\nModerator that unbanned you - {1}\nReason - {2}\nOriginal reason of the ban - {3}\noriginal banner - {4}\nTime of original ban - {5}.\nThank you for your fairness and acceptance."); + + instance.sendBanRevokeMail("alex@gmail.com", "axel12", "mod1","reason1","reason2","mod2","time"); + + verify(emailSender).sendMail("foo@bar.com", "foobar", "alex@gmail.com", "Hello", "Hello axel12,\nYour account was been unbanned.\nModerator that unbanned you - mod1\nReason - reason1\nOriginal reason of the ban - reason2\noriginal banner - mod2\nTime of original ban - time.\nThank you for your fairness and acceptance."); + } + @Test public void sendPasswordResetMail() { PasswordReset passwordReset = properties.getPasswordReset(); diff --git a/src/test/java/com/faforever/api/user/UserServiceTest.java b/src/test/java/com/faforever/api/user/UserServiceTest.java index 422f00c67..fa5355a6a 100644 --- a/src/test/java/com/faforever/api/user/UserServiceTest.java +++ b/src/test/java/com/faforever/api/user/UserServiceTest.java @@ -102,7 +102,7 @@ private static User createUser(int id, String name, String password, String emai } @Before - public void setUp() throws Exception { + public void setUp() { properties = new FafApiProperties(); properties.getJwt().setSecret(TEST_SECRET); properties.getLinkToSteam().setSteamRedirectUrlFormat("%s"); @@ -117,7 +117,7 @@ public void setUp() throws Exception { @Test @SuppressWarnings("unchecked") - public void register() throws Exception { + public void register() { properties.getRegistration().setActivationUrlFormat(ACTIVATION_URL_FORMAT); instance.register(TEST_USERNAME, TEST_CURRENT_EMAIL, TEST_CURRENT_PASSWORD); @@ -133,7 +133,7 @@ public void register() throws Exception { } @Test - public void registerEmailAlreadyRegistered() throws Exception { + public void registerEmailAlreadyRegistered() { when(userRepository.existsByEmailIgnoreCase(TEST_CURRENT_EMAIL)).thenReturn(true); expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.EMAIL_REGISTERED)); @@ -141,39 +141,39 @@ public void registerEmailAlreadyRegistered() throws Exception { } @Test - public void registerInvalidUsernameWithComma() throws Exception { + public void registerInvalidUsernameWithComma() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_INVALID)); instance.register("junit,", TEST_CURRENT_EMAIL, TEST_CURRENT_PASSWORD); } @Test - public void registerInvalidUsernameStartsUnderscore() throws Exception { + public void registerInvalidUsernameStartsUnderscore() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_INVALID)); instance.register("_junit", TEST_CURRENT_EMAIL, TEST_CURRENT_PASSWORD); } @Test - public void registerInvalidUsernameTooShort() throws Exception { + public void registerInvalidUsernameTooShort() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_INVALID)); instance.register("ju", TEST_CURRENT_EMAIL, TEST_CURRENT_PASSWORD); } @Test - public void registerUsernameTaken() throws Exception { + public void registerUsernameTaken() { when(userRepository.existsByLoginIgnoreCase("junit")).thenReturn(true); expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_TAKEN)); instance.register("junit", TEST_CURRENT_EMAIL, TEST_CURRENT_PASSWORD); } @Test - public void registerUsernameReserved() throws Exception { + public void registerUsernameReserved() { when(nameRecordRepository.getLastUsernameOwnerWithinMonths(any(), anyInt())).thenReturn(Optional.of(1)); expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_RESERVED)); instance.register("junit", TEST_CURRENT_EMAIL, TEST_CURRENT_PASSWORD); } @Test - public void activate() throws Exception { + public void activate() { when(fafTokenService.resolveToken(FafTokenType.REGISTRATION, TOKEN_VALUE)).thenReturn(ImmutableMap.of( UserService.KEY_USERNAME, TEST_USERNAME, UserService.KEY_EMAIL, TEST_CURRENT_EMAIL, @@ -250,6 +250,7 @@ public void changeLogin() { verify(nameRecordRepository).save(captorNameRecord.capture()); assertEquals(captorNameRecord.getValue().getName(), TEST_USERNAME); + verify(emailService).sendUsernameChangeMail(TEST_CURRENT_EMAIL, TEST_USERNAME, TEST_USERNAME_CHANGED); verify(mauticService).createOrUpdateContact(eq(TEST_NEW_EMAIL), eq(String.valueOf(TEST_USERID)), eq(TEST_USERNAME_CHANGED), eq("127.0.0.1"), any(OffsetDateTime.class)); } @@ -300,7 +301,7 @@ public void changeLoginUsernameReservedBySelf() { @Test @SuppressWarnings("unchecked") - public void resetPasswordByLogin() throws Exception { + public void resetPasswordByLogin() { properties.getPasswordReset().setPasswordResetUrlFormat(PASSWORD_RESET_URL_FORMAT); User user = createUser(TEST_USERID, TEST_USERNAME, TEST_CURRENT_PASSWORD, TEST_CURRENT_EMAIL); @@ -324,7 +325,7 @@ public void resetPasswordByLogin() throws Exception { @Test @SuppressWarnings("unchecked") - public void resetPasswordByEmail() throws Exception { + public void resetPasswordByEmail() { properties.getPasswordReset().setPasswordResetUrlFormat(PASSWORD_RESET_URL_FORMAT); User user = createUser(TEST_USERID, TEST_USERNAME, TEST_CURRENT_PASSWORD, TEST_CURRENT_EMAIL); @@ -347,7 +348,7 @@ public void resetPasswordByEmail() throws Exception { } @Test - public void resetPasswordUnknownUsernameAndEmail() throws Exception { + public void resetPasswordUnknownUsernameAndEmail() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.UNKNOWN_IDENTIFIER)); when(userRepository.findOneByEmailIgnoreCase(TEST_CURRENT_EMAIL)).thenReturn(Optional.empty()); @@ -356,7 +357,7 @@ public void resetPasswordUnknownUsernameAndEmail() throws Exception { } @Test - public void claimPasswordResetToken() throws Exception { + public void claimPasswordResetToken() { when(fafTokenService.resolveToken(FafTokenType.PASSWORD_RESET, TOKEN_VALUE)) .thenReturn(ImmutableMap.of(KEY_USER_ID, "5", KEY_PASSWORD, TEST_NEW_PASSWORD)); @@ -375,7 +376,7 @@ public void claimPasswordResetToken() throws Exception { @Test @SuppressWarnings("unchecked") - public void buildSteamLinkUrl() throws Exception { + public void buildSteamLinkUrl() { when(steamService.buildLoginUrl(any())).thenReturn("steamLoginUrl"); User user = createUser(TEST_USERID, TEST_USERNAME, TEST_CURRENT_PASSWORD, TEST_CURRENT_EMAIL); @@ -401,7 +402,7 @@ public void buildSteamLinkUrl() throws Exception { } @Test - public void buildSteamLinkUrlAlreadLinked() throws Exception { + public void buildSteamLinkUrlAlreadLinked() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.STEAM_ID_UNCHANGEABLE)); User user = createUser(TEST_USERID, TEST_USERNAME, TEST_CURRENT_PASSWORD, TEST_CURRENT_EMAIL); @@ -411,7 +412,7 @@ public void buildSteamLinkUrlAlreadLinked() throws Exception { } @Test - public void linkToSteam() throws Exception { + public void linkToSteam() { when(fafTokenService.resolveToken(FafTokenType.LINK_TO_STEAM, TOKEN_VALUE)) .thenReturn(ImmutableMap.of( KEY_USER_ID, "5", @@ -431,7 +432,7 @@ public void linkToSteam() throws Exception { } @Test - public void linkToSteamUnknownUser() throws Exception { + public void linkToSteamUnknownUser() { expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.TOKEN_INVALID)); when(fafTokenService.resolveToken(FafTokenType.LINK_TO_STEAM, TOKEN_VALUE)).thenReturn(ImmutableMap.of(KEY_USER_ID, "5")); @@ -442,7 +443,7 @@ public void linkToSteamUnknownUser() throws Exception { } @Test - public void linkToSteamNoGame() throws Exception { + public void linkToSteamNoGame() { when(fafTokenService.resolveToken(FafTokenType.LINK_TO_STEAM, TOKEN_VALUE)) .thenReturn(ImmutableMap.of( KEY_USER_ID, "5",