diff --git a/build.gradle b/build.gradle index 13559d8a4..b5ae9df72 100644 --- a/build.gradle +++ b/build.gradle @@ -10,10 +10,11 @@ buildscript { } plugins { - id "java" - id "org.springframework.boot" version "3.3.2" - id "idea" - id "com.adarshr.test-logger" version "4.0.0" + id("java") + id("org.springframework.boot") version ("3.3.5") + id("idea") + id("com.adarshr.test-logger") version ("4.0.0") + id("org.openrewrite.rewrite") version("6.26.0") } group = 'faforever' diff --git a/configuration.md b/configuration.md index 8c4fbb5a0..96a6e3836 100644 --- a/configuration.md +++ b/configuration.md @@ -1,7 +1,6 @@ | Env variable | Default value | Optional if env is defined | Default value (local) | | ---- | ---- | ---- | ---- | | ACTIVATION_URL_FORMAT | `https://www.${FAF_DOMAIN}/account/activate?username=%s&token=%s` | `FAF_DOMAIN` | `http://localhost:8020/account/activate?username=%s&token=%s` | -| ANOPE_DATABASE_NAME | `faf-anope` | | | | API_PORT | `8010` | | | | API_PROFILE | `local` | | | | AVATAR_ALLOWED_FILE_EXTENSIONS | `png` | | `png` | diff --git a/src/inttest/java/com/faforever/api/AbstractIntegrationTest.java b/src/inttest/java/com/faforever/api/AbstractIntegrationTest.java index 2c5e547ef..57a0c4107 100644 --- a/src/inttest/java/com/faforever/api/AbstractIntegrationTest.java +++ b/src/inttest/java/com/faforever/api/AbstractIntegrationTest.java @@ -18,7 +18,6 @@ import com.github.jasminb.jsonapi.exceptions.DocumentSerializationException; import org.json.JSONObject; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -27,7 +26,6 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.Sql.ExecutionPhase; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.RequestPostProcessor; @@ -44,7 +42,6 @@ import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; @Testcontainers -@ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles(ApplicationProfile.INTEGRATION_TEST) @Import(OAuthHelper.class) @@ -119,7 +116,7 @@ protected RequestPostProcessor getOAuthTokenForUserId(int userId, String... scop protected void assertApiError(MvcResult mvcResult, ErrorCode errorCode) throws Exception { JSONObject resonseJson = new JSONObject(mvcResult.getResponse().getContentAsString()); - JSONAssert.assertEquals(String.format("{\"errors\":[{\"code\":\"%s\"}]}", errorCode.getCode()), resonseJson, false); + JSONAssert.assertEquals("{\"errors\":[{\"code\":\"%s\"}]}".formatted(errorCode.getCode()), resonseJson, false); } protected byte[] createJsonApiContent(T entity) throws DocumentSerializationException { diff --git a/src/inttest/java/com/faforever/api/avatar/AvatarControllerTest.java b/src/inttest/java/com/faforever/api/avatar/AvatarControllerTest.java index b6b68c815..29e948d1c 100644 --- a/src/inttest/java/com/faforever/api/avatar/AvatarControllerTest.java +++ b/src/inttest/java/com/faforever/api/avatar/AvatarControllerTest.java @@ -19,7 +19,7 @@ import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; import java.util.Optional; import static org.hamcrest.MatcherAssert.assertThat; @@ -57,8 +57,8 @@ public void canUploadWithScopeAndRole() throws Exception { @Test public void canReuploadWithScopeAndRole() throws Exception { - Files.createDirectories(Paths.get("build/cache/avatars")); - Files.copy(FileHandlingHelper.loadResourceAsStream("/avatars/donator.png"), Paths.get("build/cache/avatars/avatar1.png")); + Files.createDirectories(Path.of("build/cache/avatars")); + Files.copy(FileHandlingHelper.loadResourceAsStream("/avatars/donator.png"), Path.of("build/cache/avatars/avatar1.png")); mockMvc.perform( createAvatarReuploadRequest(1) .with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_AVATAR)) @@ -72,8 +72,8 @@ public void canReuploadWithScopeAndRole() throws Exception { @Test public void canDeleteAvatarWithScopeAndRole() throws Exception { - Files.createDirectories(Paths.get("build/cache/avatars")); - Files.copy(FileHandlingHelper.loadResourceAsStream("/avatars/donator.png"), Paths.get("build/cache/avatars/avatar1.png")); + Files.createDirectories(Path.of("build/cache/avatars")); + Files.copy(FileHandlingHelper.loadResourceAsStream("/avatars/donator.png"), Path.of("build/cache/avatars/avatar1.png")); mockMvc.perform( delete("/avatars/3") .with(getOAuthTokenWithActiveUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_AVATAR)) @@ -138,8 +138,8 @@ public void cannotDeleteWithoutScope() throws Exception { @AfterEach public void tearDown() throws Exception { - Files.deleteIfExists(Paths.get("build/cache/avatars/avatar1.png")); - Files.deleteIfExists(Paths.get("build/cache/avatars/avatar3.png")); + Files.deleteIfExists(Path.of("build/cache/avatars/avatar1.png")); + Files.deleteIfExists(Path.of("build/cache/avatars/avatar3.png")); } private MockMultipartHttpServletRequestBuilder createAvatarUploadRequest() throws IOException { diff --git a/src/inttest/java/com/faforever/api/clan/ClanControllerTest.java b/src/inttest/java/com/faforever/api/clan/ClanControllerTest.java index 5e5aa9995..48c2a4d84 100644 --- a/src/inttest/java/com/faforever/api/clan/ClanControllerTest.java +++ b/src/inttest/java/com/faforever/api/clan/ClanControllerTest.java @@ -16,10 +16,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsNull.nullValue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -40,12 +37,10 @@ public class ClanControllerTest extends AbstractIntegrationTest { PlayerRepository playerRepository; @Autowired ClanRepository clanRepository; - @Autowired - ClanMembershipRepository clanMembershipRepository; @Test public void meDataWithoutClan() throws Exception { - Player player = playerRepository.getById(USERID_USER); + Player player = playerRepository.getReferenceById(USERID_USER); mockMvc.perform(get("/clans/me") .with(getOAuthTokenForUserId(USERID_USER))) @@ -57,8 +52,8 @@ public void meDataWithoutClan() throws Exception { @Test public void meDataWithClan() throws Exception { - Player player = playerRepository.getById(USERID_CLAN_MEMBER); - Clan clan = clanRepository.getById(1); + Player player = playerRepository.getReferenceById(USERID_CLAN_MEMBER); + Clan clan = clanRepository.getReferenceById(1); mockMvc.perform( get("/clans/me") @@ -73,7 +68,7 @@ public void meDataWithClan() throws Exception { @Test public void createClanWithSuccess() throws Exception { - Player player = playerRepository.getById(USERID_USER); + Player player = playerRepository.getReferenceById(USERID_USER); assertNull(player.getClan()); assertFalse(clanRepository.findOneByName(NEW_CLAN_NAME).isPresent()); @@ -111,7 +106,7 @@ public void createClanWithoutAuth() throws Exception { @Test public void createClanWithExistingName() throws Exception { - Player player = playerRepository.getById(USERID_USER); + Player player = playerRepository.getReferenceById(USERID_USER); assertNull(player.getClan()); assertTrue(clanRepository.findOneByName(EXISTING_CLAN).isPresent()); @@ -133,7 +128,7 @@ public void createClanWithExistingName() throws Exception { @Test public void createClanWithExistingTag() throws Exception { - Player player = playerRepository.getById(USERID_USER); + Player player = playerRepository.getReferenceById(USERID_USER); assertNull(player.getClan()); assertFalse(clanRepository.findOneByName(NEW_CLAN_NAME).isPresent()); @@ -155,7 +150,7 @@ public void createClanWithExistingTag() throws Exception { @Test public void createSecondClan() throws Exception { - Player player = playerRepository.getById(USERID_CLAN_MEMBER); + Player player = playerRepository.getReferenceById(USERID_CLAN_MEMBER); assertNotNull(player.getClan()); assertFalse(clanRepository.findOneByName(NEW_CLAN_NAME).isPresent()); diff --git a/src/inttest/java/com/faforever/api/data/ClanElideTest.java b/src/inttest/java/com/faforever/api/data/ClanElideTest.java index 252a4dd09..6ac676063 100644 --- a/src/inttest/java/com/faforever/api/data/ClanElideTest.java +++ b/src/inttest/java/com/faforever/api/data/ClanElideTest.java @@ -21,10 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; @@ -48,13 +45,13 @@ public class ClanElideTest extends AbstractIntegrationTest { @Test public void canDeleteMemberOfOwnClan() throws Exception { - assertNotNull(playerRepository.getById(USERID_CLAN_MEMBER).getClan()); + assertNotNull(playerRepository.getReferenceById(USERID_CLAN_MEMBER).getClan()); mockMvc.perform( delete("/data/clanMembership/2") // magic value from prepClanData.sql .with(getOAuthTokenForUserId(USERID_CLAN_LEADER))) .andExpect(status().isNoContent()); - assertNull(playerRepository.getById(USERID_CLAN_MEMBER).getClan()); + assertNull(playerRepository.getReferenceById(USERID_CLAN_MEMBER).getClan()); } @Test @@ -77,14 +74,14 @@ public void cannotDeleteLeaderFromClan() throws Exception { @Test public void canLeaveClan() throws Exception { - assertNotNull(playerRepository.getById(USERID_CLAN_MEMBER).getClan()); + assertNotNull(playerRepository.getReferenceById(USERID_CLAN_MEMBER).getClan()); mockMvc.perform( delete("/data/clanMembership/2") // magic value from prepClanData.sql .with(getOAuthTokenForUserId(USERID_CLAN_MEMBER))) .andExpect(status().isNoContent()); - assertNull(playerRepository.getById(USERID_CLAN_MEMBER).getClan()); + assertNull(playerRepository.getReferenceById(USERID_CLAN_MEMBER).getClan()); } @Test @@ -108,7 +105,7 @@ public void getFilteredPlayerForClanInvite() throws Exception { @Test public void canTransferLeadershipAsLeader() throws Exception { - assertThat(clanRepository.getById(1).getLeader().getLogin(), is(AUTH_CLAN_LEADER)); + assertThat(clanRepository.getReferenceById(1).getLeader().getLogin(), is(AUTH_CLAN_LEADER)); mockMvc.perform( patch("/data/clan/1") @@ -117,12 +114,12 @@ public void canTransferLeadershipAsLeader() throws Exception { .content(generateTransferLeadershipContent(1, USERID_CLAN_MEMBER))) // magic value from prepClanData.sql .andExpect(status().isNoContent()); - assertThat(clanRepository.getById(1).getLeader().getLogin(), is(AUTH_CLAN_MEMBER)); + assertThat(clanRepository.getReferenceById(1).getLeader().getLogin(), is(AUTH_CLAN_MEMBER)); } @Test public void cannotTransferLeadershipAsMember() throws Exception { - assertThat(clanRepository.getById(1).getLeader().getLogin(), is(AUTH_CLAN_LEADER)); + assertThat(clanRepository.getReferenceById(1).getLeader().getLogin(), is(AUTH_CLAN_LEADER)); mockMvc.perform( patch("/data/clan/1") @@ -132,7 +129,7 @@ public void cannotTransferLeadershipAsMember() throws Exception { .andExpect(status().isForbidden()) .andExpect(jsonPath("$.errors[0].detail", is("UpdatePermission Denied"))); - assertThat(clanRepository.getById(1).getLeader().getLogin(), is(AUTH_CLAN_LEADER)); + assertThat(clanRepository.getReferenceById(1).getLeader().getLogin(), is(AUTH_CLAN_LEADER)); } @Test @@ -170,11 +167,6 @@ public void canDeleteClanAsLeader() throws Exception { Clan clan = clanRepository.findOneByName("Alpha Clan") .orElseThrow(() -> new IllegalStateException("Alpha Clan could not be found")); - List clanMember = new ArrayList<>(); - clan.getMemberships().stream() - .map(ClanMembership::getPlayer) - .forEach(clanMember::add); - mockMvc.perform( delete("/data/clan/1") .with(getOAuthTokenForUserId(USERID_CLAN_LEADER))) @@ -188,11 +180,6 @@ public void cannotDeleteClanAsMember() throws Exception { Optional clanOptional = clanRepository.findOneByName("Alpha Clan"); assertTrue(clanOptional.isPresent()); - List clanMember = new ArrayList<>(); - clanOptional.get().getMemberships().stream() - .map(ClanMembership::getPlayer) - .forEach(clanMember::add); - mockMvc.perform( delete("/data/clan/1") .with(getOAuthTokenForUserId(USERID_CLAN_MEMBER))) diff --git a/src/inttest/java/com/faforever/api/data/MapElideTest.java b/src/inttest/java/com/faforever/api/data/MapElideTest.java index 16efa8257..2707311b7 100644 --- a/src/inttest/java/com/faforever/api/data/MapElideTest.java +++ b/src/inttest/java/com/faforever/api/data/MapElideTest.java @@ -68,7 +68,7 @@ public void canUpdateMapRecommendationToTrueWithScopeAndRole() throws Exception .content(MAP_RECOMMENDED_TRUE_ID_1)) .andExpect(status().isNoContent()); - assertThat(mapRepository.getById(1).getRecommended(), is(true)); + assertThat(mapRepository.getReferenceById(1).getRecommended(), is(true)); } @Test @@ -81,7 +81,7 @@ public void cannotUpdateMapRecommendationToTrueWithoutScope() throws Exception { .content(MAP_RECOMMENDED_TRUE_ID_1)) .andExpect(status().isForbidden()); - assertThat(mapRepository.getById(1).getRecommended(), is(false)); + assertThat(mapRepository.getReferenceById(1).getRecommended(), is(false)); } @Test @@ -94,7 +94,7 @@ public void cannotUpdateMapRecommendationToTrueWithoutRole() throws Exception { .content(MAP_RECOMMENDED_TRUE_ID_1)) .andExpect(status().isForbidden()); - assertThat(mapRepository.getById(1).getRecommended(), is(false)); + assertThat(mapRepository.getReferenceById(1).getRecommended(), is(false)); } @Test @@ -107,7 +107,7 @@ public void canUpdateMapRecommendationToFalseWithScopeAndRole() throws Exception .content(MAP_RECOMMENDED_FALSE_ID_1)) .andExpect(status().isNoContent()); - assertThat(mapRepository.getById(1).getRecommended(), is(false)); + assertThat(mapRepository.getReferenceById(1).getRecommended(), is(false)); } @Test diff --git a/src/inttest/java/com/faforever/api/data/MapVersionElideTest.java b/src/inttest/java/com/faforever/api/data/MapVersionElideTest.java index 458058764..c86b26749 100644 --- a/src/inttest/java/com/faforever/api/data/MapVersionElideTest.java +++ b/src/inttest/java/com/faforever/api/data/MapVersionElideTest.java @@ -20,42 +20,50 @@ @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepMapVersion.sql") public class MapVersionElideTest extends AbstractIntegrationTest { - private static final String MAP_VERSION_HIDE_FALSE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"mapVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"hidden\": false\n" + - " }\n" + - " } \n" + - "}"; - private static final String MAP_VERSION_HIDE_TRUE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"mapVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"hidden\": true\n" + - " }\n" + - " } \n" + - "}"; - private static final String MAP_VERSION_RANKED_FALSE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"mapVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"ranked\": false\n" + - " }\n" + - " } \n" + - "}"; - private static final String MAP_VERSION_RANKED_TRUE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"mapVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"ranked\": true\n" + - " }\n" + - " } \n" + - "}"; + private static final String MAP_VERSION_HIDE_FALSE_ID_1 = """ + { + "data": { + "type": "mapVersion", + "id": "1", + "attributes": { + "hidden": false + } + }\s + }\ + """; + private static final String MAP_VERSION_HIDE_TRUE_ID_1 = """ + { + "data": { + "type": "mapVersion", + "id": "1", + "attributes": { + "hidden": true + } + }\s + }\ + """; + private static final String MAP_VERSION_RANKED_FALSE_ID_1 = """ + { + "data": { + "type": "mapVersion", + "id": "1", + "attributes": { + "ranked": false + } + }\s + }\ + """; + private static final String MAP_VERSION_RANKED_TRUE_ID_1 = """ + { + "data": { + "type": "mapVersion", + "id": "1", + "attributes": { + "ranked": true + } + }\s + }\ + """; @Test diff --git a/src/inttest/java/com/faforever/api/data/ModElideTest.java b/src/inttest/java/com/faforever/api/data/ModElideTest.java index 3ff62e3ca..9b7198d3b 100644 --- a/src/inttest/java/com/faforever/api/data/ModElideTest.java +++ b/src/inttest/java/com/faforever/api/data/ModElideTest.java @@ -68,7 +68,7 @@ public void canUpdateModRecommendationToTrueWithScopeAndRole() throws Exception .content(MOD_RECOMMENDED_TRUE_ID_1)) .andExpect(status().isNoContent()); - assertThat(modRepository.getById(1).getRecommended(), is(true)); + assertThat(modRepository.getReferenceById(1).getRecommended(), is(true)); } @Test @@ -81,7 +81,7 @@ public void cannotUpdateModRecommendationToTrueWithoutScope() throws Exception { .content(MOD_RECOMMENDED_TRUE_ID_1)) .andExpect(status().isForbidden()); - assertThat(modRepository.getById(1).getRecommended(), is(false)); + assertThat(modRepository.getReferenceById(1).getRecommended(), is(false)); } @Test @@ -94,7 +94,7 @@ public void cannotUpdateModRecommendationToTrueWithoutRole() throws Exception { .content(MOD_RECOMMENDED_TRUE_ID_1)) .andExpect(status().isForbidden()); - assertThat(modRepository.getById(1).getRecommended(), is(false)); + assertThat(modRepository.getReferenceById(1).getRecommended(), is(false)); } @Test @@ -107,7 +107,7 @@ public void canUpdateModRecommendationToFalseWithScopeAndRole() throws Exception .content(MOD_RECOMMENDED_FALSE_ID_1)) .andExpect(status().isNoContent()); - assertThat(modRepository.getById(1).getRecommended(), is(false)); + assertThat(modRepository.getReferenceById(1).getRecommended(), is(false)); } @Test diff --git a/src/inttest/java/com/faforever/api/data/ModVersionElideTest.java b/src/inttest/java/com/faforever/api/data/ModVersionElideTest.java index 3d517d93d..ec031430c 100644 --- a/src/inttest/java/com/faforever/api/data/ModVersionElideTest.java +++ b/src/inttest/java/com/faforever/api/data/ModVersionElideTest.java @@ -20,42 +20,50 @@ @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepModData.sql") public class ModVersionElideTest extends AbstractIntegrationTest { - private static final String MOD_VERSION_HIDE_FALSE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"modVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"hidden\": false\n" + - " }\n" + - " } \n" + - "}"; - private static final String MOD_VERSION_HIDE_TRUE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"modVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"hidden\": true\n" + - " }\n" + - " } \n" + - "}"; - private static final String MOD_VERSION_RANKED_FALSE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"modVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"ranked\": false\n" + - " }\n" + - " } \n" + - "}"; - private static final String MOD_VERSION_RANKED_TRUE_ID_1 = "{\n" + - " \"data\": {\n" + - " \"type\": \"modVersion\",\n" + - " \"id\": \"1\",\n" + - " \"attributes\": {\n" + - " \t\"ranked\": true\n" + - " }\n" + - " } \n" + - "}"; + private static final String MOD_VERSION_HIDE_FALSE_ID_1 = """ + { + "data": { + "type": "modVersion", + "id": "1", + "attributes": { + "hidden": false + } + }\s + }\ + """; + private static final String MOD_VERSION_HIDE_TRUE_ID_1 = """ + { + "data": { + "type": "modVersion", + "id": "1", + "attributes": { + "hidden": true + } + }\s + }\ + """; + private static final String MOD_VERSION_RANKED_FALSE_ID_1 = """ + { + "data": { + "type": "modVersion", + "id": "1", + "attributes": { + "ranked": false + } + }\s + }\ + """; + private static final String MOD_VERSION_RANKED_TRUE_ID_1 = """ + { + "data": { + "type": "modVersion", + "id": "1", + "attributes": { + "ranked": true + } + }\s + }\ + """; @Test diff --git a/src/inttest/java/com/faforever/api/data/UserNoteTest.java b/src/inttest/java/com/faforever/api/data/UserNoteTest.java index 61a40857e..ca4c2299d 100644 --- a/src/inttest/java/com/faforever/api/data/UserNoteTest.java +++ b/src/inttest/java/com/faforever/api/data/UserNoteTest.java @@ -117,7 +117,7 @@ public void cannotCreateUserNoteWithoutRole() throws Exception { @Test public void canCreateUserNoteWithScopeAndRole() throws Exception { - assertThat(playerRepository.getById(3).getUserNotes().size(), is(0)); + assertThat(playerRepository.getReferenceById(3).getUserNotes().size(), is(0)); mockMvc.perform(post("/data/userNote") .with(getOAuthTokenWithActiveUser(OAuthScope._READ_SENSIBLE_USERDATA, GroupPermission.ROLE_ADMIN_ACCOUNT_NOTE)) @@ -125,6 +125,6 @@ public void canCreateUserNoteWithScopeAndRole() throws Exception { .content(testPost)) .andExpect(status().isCreated()); - assertThat(playerRepository.getById(3).getUserNotes().size(), is(1)); + assertThat(playerRepository.getReferenceById(3).getUserNotes().size(), is(1)); } } diff --git a/src/inttest/java/com/faforever/api/data/VotingElideTest.java b/src/inttest/java/com/faforever/api/data/VotingElideTest.java index 4288100d5..1a09f9e66 100644 --- a/src/inttest/java/com/faforever/api/data/VotingElideTest.java +++ b/src/inttest/java/com/faforever/api/data/VotingElideTest.java @@ -199,10 +199,10 @@ public void canRevealWinnerOnEndedSubjectWorksWithScopeAndRole() throws Exceptio .header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE) .content(PATCH_VOTING_SUBJECT_REVEAL_ID_2)) .andExpect(status().isNoContent()); - VotingQuestion question = votingQuestionRepository.getById(2); + VotingQuestion question = votingQuestionRepository.getReferenceById(2); List winners = question.getWinners(); assertThat(winners, hasSize(1)); - assertThat(winners.get(0).getId(), is(3)); + assertThat(winners.getFirst().getId(), is(3)); } @Test diff --git a/src/inttest/java/com/faforever/api/deployment/ExeUploadControllerTest.java b/src/inttest/java/com/faforever/api/deployment/ExeUploadControllerTest.java index 5feb6e053..54dd96de7 100644 --- a/src/inttest/java/com/faforever/api/deployment/ExeUploadControllerTest.java +++ b/src/inttest/java/com/faforever/api/deployment/ExeUploadControllerTest.java @@ -8,9 +8,9 @@ import org.springframework.test.context.jdbc.Sql.ExecutionPhase; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -33,7 +33,7 @@ public void testSuccessUploadBeta() throws Exception { .param("modName", "fafbeta") .param("apiKey", SUPER_SECRET) ).andExpect(status().isOk()); - assertTrue(Files.exists(Paths.get("build/exe/beta/ForgedAlliance.3706.exe"))); + assertTrue(Files.exists(Path.of("build/exe/beta/ForgedAlliance.3706.exe"))); } @Test @@ -43,7 +43,7 @@ public void testSuccessUploadDevelop() throws Exception { .param("modName", "fafdevelop") .param("apiKey", SUPER_SECRET) ).andExpect(status().isOk()); - assertTrue(Files.exists(Paths.get("build/exe/develop/ForgedAlliance.3707.exe"))); + assertTrue(Files.exists(Path.of("build/exe/develop/ForgedAlliance.3707.exe"))); } @Test diff --git a/src/inttest/java/com/faforever/api/user/UsersControllerTest.java b/src/inttest/java/com/faforever/api/user/UsersControllerTest.java index b00211c8b..d1da1e82b 100644 --- a/src/inttest/java/com/faforever/api/user/UsersControllerTest.java +++ b/src/inttest/java/com/faforever/api/user/UsersControllerTest.java @@ -119,7 +119,7 @@ public void changePasswordWithSuccess() throws Exception { .params(params)) .andExpect(status().isOk()); - User user = userRepository.getById(USERID_USER); + User user = userRepository.getReferenceById(USERID_USER); assertEquals(user.getPassword(), "5c29a959abce4eda5f0e7a4e7ea53dce4fa0f0abbe8eaa63717e2fed5f193d31"); } @@ -308,7 +308,7 @@ public void linkToSteam() throws Exception { when(steamService.ownsForgedAlliance(anyString())).thenReturn(true); mockMvc.perform( - get(String.format("/users/linkToSteam?callbackUrl=%s&token=%s&openid.identity=http://steamcommunity.com/openid/id/%s", callbackUrl, token, steamId))) + get("/users/linkToSteam?callbackUrl=%s&token=%s&openid.identity=http://steamcommunity.com/openid/id/%s".formatted(callbackUrl, token, steamId))) .andExpect(status().isFound()) .andExpect(redirectedUrl(callbackUrl)); @@ -334,7 +334,7 @@ public void linkToSteamAlreadyLinkedAccount() throws Exception { when(steamService.ownsForgedAlliance(anyString())).thenReturn(true); mockMvc.perform( - get(String.format("/users/linkToSteam?callbackUrl=%s&token=%s&openid.identity=http://steamcommunity.com/openid/id/%s", callbackUrl, token, steamId))) + get("/users/linkToSteam?callbackUrl=%s&token=%s&openid.identity=http://steamcommunity.com/openid/id/%s".formatted(callbackUrl, token, steamId))) .andExpect(status().isFound()) .andExpect(redirectedUrlPattern(callbackUrl + "?errors=*" + ErrorCode.STEAM_ID_ALREADY_LINKED.getCode() + "*" + userThatOwnsSteamId.getLogin() + "*")); //We expect and error with code STEAM_ID_ALREADY_LINKED and that the error message contains the user that this steam account was linked to already which is MODERATOR with id 2 @@ -367,7 +367,7 @@ public void changeUsernameWithWrongScope() throws Exception { @Test public void changeUsernameSuccess() throws Exception { - assertThat(userRepository.getById(1).getLogin(), is(AUTH_USER)); + assertThat(userRepository.getReferenceById(1).getLogin(), is(AUTH_USER)); MultiValueMap params = new HttpHeaders(); params.add("newUsername", NEW_USER); @@ -378,12 +378,12 @@ public void changeUsernameSuccess() throws Exception { .params(params)) .andExpect(status().isOk()); - assertThat(userRepository.getById(1).getLogin(), is(NEW_USER)); + assertThat(userRepository.getReferenceById(1).getLogin(), is(NEW_USER)); } @Test public void changeUsernameForcedByUser() throws Exception { - assertThat(userRepository.getById(1).getLogin(), is(AUTH_USER)); + assertThat(userRepository.getReferenceById(1).getLogin(), is(AUTH_USER)); MultiValueMap params = new HttpHeaders(); params.add("newUsername", NEW_USER); @@ -395,7 +395,7 @@ public void changeUsernameForcedByUser() throws Exception { .andExpect(status().is4xxClientError()) .andReturn(); - assertThat(userRepository.getById(1).getLogin(), is(not(NEW_USER))); + assertThat(userRepository.getReferenceById(1).getLogin(), is(not(NEW_USER))); } @Test @@ -409,7 +409,7 @@ public void changeUsernameForcedByModerator() throws Exception { .params(params)) .andExpect(status().isOk()); - assertThat(userRepository.getById(2).getLogin(), is(NEW_USER)); + assertThat(userRepository.getReferenceById(2).getLogin(), is(NEW_USER)); } @Test @@ -438,7 +438,7 @@ public void changeUsernameForcedByModeratorWithoutRole() throws Exception { @Test public void changeUsernameTooEarly() throws Exception { - assertThat(userRepository.getById(2).getLogin(), is(AUTH_MODERATOR)); + assertThat(userRepository.getReferenceById(2).getLogin(), is(AUTH_MODERATOR)); MultiValueMap params = new HttpHeaders(); params.add("newUsername", NEW_USER); @@ -452,7 +452,7 @@ public void changeUsernameTooEarly() throws Exception { assertApiError(result, ErrorCode.USERNAME_CHANGE_TOO_EARLY); - assertThat(userRepository.getById(2).getLogin(), is(AUTH_MODERATOR)); + assertThat(userRepository.getReferenceById(2).getLogin(), is(AUTH_MODERATOR)); } @Test @@ -467,7 +467,7 @@ public void changeUsernameTooEarlyButForced() throws Exception { .andExpect(status().isOk()) .andReturn(); - assertThat(userRepository.getById(2).getLogin(), is(NEW_USER)); + assertThat(userRepository.getReferenceById(2).getLogin(), is(NEW_USER)); } @Test diff --git a/src/inttest/resources/config/application.yml b/src/inttest/resources/config/application.yml index e90cb1b7d..cded3cd4a 100644 --- a/src/inttest/resources/config/application.yml +++ b/src/inttest/resources/config/application.yml @@ -34,6 +34,9 @@ spring: resourceserver: jwt: jwk-set-uri: http://localhost + threads: + virtual: + enabled: true faf-api: jwt: diff --git a/src/main/java/com/faforever/api/avatar/AvatarController.java b/src/main/java/com/faforever/api/avatar/AvatarController.java index 8eb92dfae..74edbf5da 100644 --- a/src/main/java/com/faforever/api/avatar/AvatarController.java +++ b/src/main/java/com/faforever/api/avatar/AvatarController.java @@ -11,9 +11,10 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -42,7 +43,7 @@ public AvatarController(AvatarService avatarService) { @ApiResponse(responseCode = "422", description = "Invalid input", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), @ApiResponse(responseCode = "500", description = "Failure", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))}) @ResponseStatus(value = HttpStatus.CREATED) - @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PreAuthorize("hasScope('" + OAuthScope._ADMINISTRATIVE_ACTION + "') and hasAnyRole('" + ROLE_WRITE_AVATAR + "', 'ROLE_ADMINISTRATOR')") public void uploadAvatar( @Parameter(name = "metadata") @RequestPart("metadata") AvatarMetadata avatarMetaData, @@ -59,10 +60,10 @@ public void uploadAvatar( @ApiResponse(responseCode = "422", description = "Invalid input", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), @ApiResponse(responseCode = "500", description = "Failure", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))}) @ResponseStatus(value = HttpStatus.OK) - @RequestMapping(value = "{avatarId}/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "{avatarId}/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PreAuthorize("hasScope('" + OAuthScope._ADMINISTRATIVE_ACTION + "') and hasAnyRole('" + ROLE_WRITE_AVATAR + "', 'ROLE_ADMINISTRATOR')") public void reuploadAvatar( - @Parameter(name = "avatarId") @PathVariable("avatarId") Integer avatarId, + @Parameter(name = "avatarId") @PathVariable Integer avatarId, @Parameter(name = "metadata") @RequestPart(value = "metadata") AvatarMetadata avatarMetaData, @Parameter(name = "file") @RequestPart("file") MultipartFile avatarImageFile) throws IOException { avatarService.updateAvatar(avatarId, avatarMetaData, avatarImageFile.getOriginalFilename(), avatarImageFile.getInputStream(), avatarImageFile.getSize()); @@ -74,10 +75,10 @@ public void reuploadAvatar( @ApiResponse(responseCode = "422", description = "Invalid input", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), @ApiResponse(responseCode = "500", description = "Failure", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))}) @ResponseStatus(value = HttpStatus.NO_CONTENT) - @RequestMapping(value = "/{avatarId}", method = RequestMethod.DELETE) + @DeleteMapping("/{avatarId}") @PreAuthorize("hasScope('" + OAuthScope._ADMINISTRATIVE_ACTION + "') and hasAnyRole('" + ROLE_WRITE_AVATAR + "', 'ROLE_ADMINISTRATOR')") public void deleteAvatar( - @Parameter(name = "avatarId") @PathVariable("avatarId") Integer avatarId) throws IOException { + @Parameter(name = "avatarId") @PathVariable Integer avatarId) { avatarService.deleteAvatar(avatarId); } diff --git a/src/main/java/com/faforever/api/avatar/AvatarService.java b/src/main/java/com/faforever/api/avatar/AvatarService.java index 331b36592..05d41e0be 100644 --- a/src/main/java/com/faforever/api/avatar/AvatarService.java +++ b/src/main/java/com/faforever/api/avatar/AvatarService.java @@ -26,7 +26,6 @@ import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Iterator; @@ -96,7 +95,7 @@ public void deleteAvatar(Integer avatarId) { @NotNull private String getFileNameFromUrl(@NotNull String avatarUrl) { - return Paths.get(URI.create(avatarUrl).getPath()).getFileName().toString(); + return Path.of(URI.create(avatarUrl).getPath()).getFileName().toString(); } private void copyAvatarFile(InputStream imageDataInputStream, Path imageTargetPath, boolean overwrite) throws IOException { diff --git a/src/main/java/com/faforever/api/challonge/ChallongeController.java b/src/main/java/com/faforever/api/challonge/ChallongeController.java index fe3119703..032e51f0c 100644 --- a/src/main/java/com/faforever/api/challonge/ChallongeController.java +++ b/src/main/java/com/faforever/api/challonge/ChallongeController.java @@ -14,6 +14,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Async; import org.springframework.security.access.annotation.Secured; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -27,7 +28,6 @@ import java.util.concurrent.CompletableFuture; import static org.springframework.web.bind.annotation.RequestMethod.DELETE; -import static org.springframework.web.bind.annotation.RequestMethod.GET; import static org.springframework.web.bind.annotation.RequestMethod.POST; import static org.springframework.web.bind.annotation.RequestMethod.PUT; @@ -62,14 +62,14 @@ private static String translateRoute(HttpServletRequest request) { @Async @Cacheable(cacheNames = CHALLONGE_READ_CACHE_NAME) - @RequestMapping(path = "/**", method = GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @GetMapping(path = "/**", produces = MediaType.APPLICATION_JSON_VALUE) public CompletableFuture> get(HttpServletRequest request) { return CompletableFuture.completedFuture(restTemplate.getForEntity(translateRoute(request), String.class, Map.of())); } @Async @Secured("ROLE_TOURNAMENT_DIRECTOR") - @RequestMapping(path = "/**", method = {POST, PUT, DELETE}, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @RequestMapping(path = "/**", method = {POST, PUT, DELETE}, produces = MediaType.APPLICATION_JSON_VALUE) public CompletableFuture> write(@RequestBody(required = false) Object body, HttpMethod method, HttpServletRequest request) { return CompletableFuture.completedFuture(restTemplate.exchange(translateRoute(request), method, new HttpEntity<>(body), String.class)); } diff --git a/src/main/java/com/faforever/api/clan/ClansController.java b/src/main/java/com/faforever/api/clan/ClansController.java index 6ca28a207..e78cf3d8f 100644 --- a/src/main/java/com/faforever/api/clan/ClansController.java +++ b/src/main/java/com/faforever/api/clan/ClansController.java @@ -60,10 +60,10 @@ public MeResult me(Authentication authentication) { @PostMapping(path = "/create", produces = APPLICATION_JSON_VALUE) @PreAuthorize("hasRole('ROLE_USER')") @Transactional - public Map createClan(@RequestParam(value = "name") String name, - @RequestParam(value = "tag") String tag, - @RequestParam(value = "description", required = false) String description, - Authentication authentication) throws IOException { + public Map createClan(@RequestParam String name, + @RequestParam String tag, + @RequestParam(required = false) String description, + Authentication authentication) { Player player = playerService.getPlayer(authentication); Clan clan = clanService.create(name, tag, description, player); return Map.of("id", clan.getId(), "type", "clan"); @@ -75,9 +75,9 @@ public Map createClan(@RequestParam(value = "name") String @ApiResponse(responseCode = "400", description = "Bad Request")}) @GetMapping(path = "/generateInvitationLink", produces = APPLICATION_JSON_VALUE) public Map generateInvitationLink( - @RequestParam(value = "clanId") int clanId, + @RequestParam int clanId, @RequestParam(value = "playerId") int newMemberId, - Authentication authentication) throws IOException { + Authentication authentication) { Player player = playerService.getPlayer(authentication); String jwtToken = clanService.generatePlayerInvitationToken(player, newMemberId, clanId); return Map.of("jwtToken", jwtToken); @@ -88,7 +88,7 @@ public Map generateInvitationLink( @Transactional public void joinClan( @RequestParam(value = "token") String stringToken, - Authentication authentication) throws IOException { + Authentication authentication) { clanService.acceptPlayerInvitationToken(stringToken, authentication); } } diff --git a/src/main/java/com/faforever/api/config/FafApiProperties.java b/src/main/java/com/faforever/api/config/FafApiProperties.java index 1625ad94c..3ceef27fc 100644 --- a/src/main/java/com/faforever/api/config/FafApiProperties.java +++ b/src/main/java/com/faforever/api/config/FafApiProperties.java @@ -5,7 +5,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import java.nio.file.Path; -import java.nio.file.Paths; import java.time.Duration; import java.util.Set; @@ -81,15 +80,15 @@ public static class Map { /** * The directory in which uploaded map files are stored. */ - private Path targetDirectory = Paths.get("static/maps"); + private Path targetDirectory = Path.of("static/maps"); /** * The directory in which small map previews are stored. */ - private Path directoryPreviewPathSmall = Paths.get("static/map_previews/small"); + private Path directoryPreviewPathSmall = Path.of("static/map_previews/small"); /** * The directory in which large map previews are stored. */ - private Path directoryPreviewPathLarge = Paths.get("static/map_previews/large"); + private Path directoryPreviewPathLarge = Path.of("static/map_previews/large"); /** * The size (in pixels) of small map previews. */ @@ -118,9 +117,9 @@ public static class Mod { /** Allowed file extensions of uploaded mods. */ private Set allowedExtensions = Set.of("zip"); /** The directory in which uploaded mod files are stored. */ - private Path targetDirectory = Paths.get("static/mods"); + private Path targetDirectory = Path.of("static/mods"); /** The directory in which thumbnails of uploaded mod files are stored. */ - private Path thumbnailTargetDirectory = Paths.get("static/mod_thumbnails"); + private Path thumbnailTargetDirectory = Path.of("static/mod_thumbnails"); /** The maximum allowed length of a mod's name. */ @Positive private int maxNameLength = 100; @@ -257,11 +256,6 @@ public static class Smtp { private String password; } - @Data - public static class Anope { - private String databaseName; - } - @Data public static class Rating { private int defaultMean; diff --git a/src/main/java/com/faforever/api/config/elide/ElideSwaggerController.java b/src/main/java/com/faforever/api/config/elide/ElideSwaggerController.java index 9a5a3f312..4bb740faa 100644 --- a/src/main/java/com/faforever/api/config/elide/ElideSwaggerController.java +++ b/src/main/java/com/faforever/api/config/elide/ElideSwaggerController.java @@ -6,7 +6,7 @@ import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -14,14 +14,10 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @RestController +@RequiredArgsConstructor public class ElideSwaggerController { - private EntityDictionary entityDictionary; - - @Autowired - public ElideSwaggerController(EntityDictionary entityDictionary) { - this.entityDictionary = entityDictionary; - } + private final EntityDictionary entityDictionary; @Hidden @GetMapping(value = "/elide/docs", produces = {APPLICATION_JSON_VALUE}) diff --git a/src/main/java/com/faforever/api/config/security/WebSecurityConfig.java b/src/main/java/com/faforever/api/config/security/WebSecurityConfig.java index 920438892..4e7ece2dd 100644 --- a/src/main/java/com/faforever/api/config/security/WebSecurityConfig.java +++ b/src/main/java/com/faforever/api/config/security/WebSecurityConfig.java @@ -42,13 +42,13 @@ public boolean matches(HttpServletRequest request) { return matcher.matches(request) && !allowedMethods.matcher(request.getMethod()).matches(); } })); - http.headers(headersConfig -> headersConfig.cacheControl().disable()); - http.formLogin().disable(); + http.headers(headersConfig -> headersConfig.cacheControl(control -> control.disable())); + http.formLogin(login -> login.disable()); http.oauth2ResourceServer(oauth2Config -> { oauth2Config.bearerTokenResolver(bearerTokenResolver); oauth2Config.jwt(jwtConfig -> jwtConfig.jwtAuthenticationConverter(new FafAuthenticationConverter())); }); - http.authorizeRequests(authorizeConfig -> { + http.authorizeHttpRequests(authorizeConfig -> { authorizeConfig.requestMatchers(HttpMethod.OPTIONS).permitAll(); // Swagger UI authorizeConfig.requestMatchers( diff --git a/src/main/java/com/faforever/api/config/swagger/SwaggerUiRedirect.java b/src/main/java/com/faforever/api/config/swagger/SwaggerUiRedirect.java index bed7e0267..7cb3e2131 100644 --- a/src/main/java/com/faforever/api/config/swagger/SwaggerUiRedirect.java +++ b/src/main/java/com/faforever/api/config/swagger/SwaggerUiRedirect.java @@ -1,8 +1,8 @@ package com.faforever.api.config.swagger; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.view.RedirectView; @@ -10,7 +10,7 @@ @RequestMapping("/") public class SwaggerUiRedirect { - @RequestMapping(method = RequestMethod.GET) + @GetMapping public RedirectView redirectToSwaggerUi(RedirectAttributes attributes) { return new RedirectView("swagger-ui/index.html"); } diff --git a/src/main/java/com/faforever/api/data/domain/Mod.java b/src/main/java/com/faforever/api/data/domain/Mod.java index 0f7323df0..520216ae5 100644 --- a/src/main/java/com/faforever/api/data/domain/Mod.java +++ b/src/main/java/com/faforever/api/data/domain/Mod.java @@ -9,10 +9,11 @@ import org.hibernate.annotations.JoinColumnOrFormula; import org.hibernate.annotations.JoinColumnsOrFormulas; import org.hibernate.annotations.JoinFormula; -import org.hibernate.validator.constraints.NotEmpty; import org.jetbrains.annotations.Nullable; import jakarta.persistence.CascadeType; + +import jakarta.validation.constraints.NotEmpty; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; diff --git a/src/main/java/com/faforever/api/db/SchemaVersionVerifier.java b/src/main/java/com/faforever/api/db/SchemaVersionVerifier.java index 514235372..8de119f68 100644 --- a/src/main/java/com/faforever/api/db/SchemaVersionVerifier.java +++ b/src/main/java/com/faforever/api/db/SchemaVersionVerifier.java @@ -34,8 +34,8 @@ public void afterPropertiesSet() { .orElseThrow(() -> new IllegalStateException("No database version is available")); Assert.state(Objects.equals(requiredVersion, actualVersion), - String.format("Database version is '%s' but this software requires '%s'. If you are sure that this version is " + - "compatible, you can override the expected version by setting the environment variable DATABASE_SCHEMA_VERSION.", + ("Database version is '%s' but this software requires '%s'. If you are sure that this version is " + + "compatible, you can override the expected version by setting the environment variable DATABASE_SCHEMA_VERSION.").formatted( actualVersion, requiredVersion)); } } diff --git a/src/main/java/com/faforever/api/deployment/ExeUploaderController.java b/src/main/java/com/faforever/api/deployment/ExeUploaderController.java index bf91c5836..b936b77d2 100644 --- a/src/main/java/com/faforever/api/deployment/ExeUploaderController.java +++ b/src/main/java/com/faforever/api/deployment/ExeUploaderController.java @@ -9,8 +9,9 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -18,7 +19,7 @@ import java.util.Map; -import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.TEXT_HTML_VALUE; @RestController @@ -36,7 +37,7 @@ public ExeUploaderController( this.exeUploaderService = exeUploaderService; } - @RequestMapping(path = "/upload", method = RequestMethod.GET, produces = TEXT_HTML_VALUE) + @GetMapping(path = "/upload", produces = TEXT_HTML_VALUE) public ModelAndView showValidationForm(Map model) { return new ModelAndView("upload_exe_form.html"); } @@ -46,10 +47,10 @@ public ModelAndView showValidationForm(Map model) { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "Failure")}) - @RequestMapping(path = "/upload", method = RequestMethod.POST, produces = APPLICATION_JSON_UTF8_VALUE) - public void upload(@RequestParam("file") MultipartFile file, - @RequestParam("modName") String modName, - @RequestParam("apiKey") String apiKey + @PostMapping(path = "/upload", produces = APPLICATION_JSON_VALUE) + public void upload(@RequestParam MultipartFile file, + @RequestParam String modName, + @RequestParam String apiKey ) throws Exception { if (!apiKey.equals(apiProperties.getDeployment().getTestingExeUploadKey())) { throw new ApiException(new Error(ErrorCode.API_KEY_INVALID)); diff --git a/src/main/java/com/faforever/api/deployment/ExeUploaderService.java b/src/main/java/com/faforever/api/deployment/ExeUploaderService.java index 77b1321a4..b0bb1a4c0 100644 --- a/src/main/java/com/faforever/api/deployment/ExeUploaderService.java +++ b/src/main/java/com/faforever/api/deployment/ExeUploaderService.java @@ -18,7 +18,6 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; @@ -48,7 +47,7 @@ public ExeUploaderService( public void processUpload(InputStream exeDataInputStream, String modName) { checkAllowedBranchName(modName); FeaturedModFile featuredModFile = featuredModService.getFile(modName, null, "ForgedAlliance.exe"); - featuredModFile.setName(String.format("ForgedAlliance.%d.exe", featuredModFile.getVersion())); + featuredModFile.setName("ForgedAlliance.%d.exe".formatted(featuredModFile.getVersion())); Path uploadedFile = this.upload( exeDataInputStream, featuredModFile.getName(), @@ -89,6 +88,6 @@ private Path getCopyToPath(String modName, String fileName) { default -> throw new ApiException(new Error(ErrorCode.INVALID_FEATURED_MOD, modName)); }; - return Paths.get(copyTo, fileName); + return Path.of(copyTo, fileName); } } diff --git a/src/main/java/com/faforever/api/deployment/GitHubController.java b/src/main/java/com/faforever/api/deployment/GitHubController.java index 2bb7a5747..6db943070 100644 --- a/src/main/java/com/faforever/api/deployment/GitHubController.java +++ b/src/main/java/com/faforever/api/deployment/GitHubController.java @@ -12,10 +12,10 @@ import org.kohsuke.github.GHEventPayload.Push; import org.kohsuke.github.GitHub; import org.springframework.scheduling.annotation.Async; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.crypto.Mac; @@ -44,7 +44,7 @@ public GitHubController(GitHubDeploymentService gitHubDeploymentService, GitHub } @Async - @RequestMapping(path = "/webhook", method = RequestMethod.POST) + @PostMapping("/webhook") @SneakyThrows public void onPush(@RequestBody String body, @RequestHeader("X-Hub-Signature") String signature, diff --git a/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java b/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java index ac3d42930..887648c3f 100644 --- a/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java +++ b/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java @@ -155,7 +155,7 @@ private Optional createPatchedExe(short version, Map packDirectory(Path directory, Short version, Path targetFolder, Map fileIds) { String directoryName = directory.getFileName().toString(); - Path targetNxtFile = targetFolder.resolve(String.format("%s.%d.%s", directoryName, version, featuredMod.getFileExtension())); + Path targetNxtFile = targetFolder.resolve("%s.%d.%s".formatted(directoryName, version, featuredMod.getFileExtension())); Path tmpNxtFile = toTmpFile(targetNxtFile); // E.g. "effects.nx2" - String clientFileName = String.format("%s.%s", directoryName, featuredMod.getFileExtension()); + String clientFileName = "%s.%s".formatted(directoryName, featuredMod.getFileExtension()); Integer fileId = fileIds.get(clientFileName); if (fileId == null) { log.debug("Skipping folder '{}' because there's no file ID available", directoryName); @@ -279,7 +279,7 @@ private Optional packFile(Path file, Short version, Path targetFolde String fullFileName = file.getFileName().toString(); String baseName = FilenameUtils.getBaseName(fullFileName); String extension = FilenameUtils.getExtension(fullFileName); - Path targetFile = targetFolder.resolve(String.format("%s_%d.%s", baseName, version, extension)); + Path targetFile = targetFolder.resolve("%s_%d.%s".formatted(baseName, version, extension)); Path tmpFile = toTmpFile(targetFile); Integer fileId = fileIds.get(fullFileName); diff --git a/src/main/java/com/faforever/api/error/GlobalControllerExceptionHandler.java b/src/main/java/com/faforever/api/error/GlobalControllerExceptionHandler.java index 3ca2a4f2c..5e7685254 100644 --- a/src/main/java/com/faforever/api/error/GlobalControllerExceptionHandler.java +++ b/src/main/java/com/faforever/api/error/GlobalControllerExceptionHandler.java @@ -38,7 +38,7 @@ public ErrorResponse processConstraintViolationException(ConstraintViolationExce ex.getConstraintViolations().forEach(constraintViolation -> { String detail = constraintViolation.getMessage(); if (!constraintViolation.getPropertyPath().toString().isEmpty()) { - detail += String.format(" [property: %s]", constraintViolation.getPropertyPath()); + detail += " [property: %s]".formatted(constraintViolation.getPropertyPath()); } errorResponse.addError(new ErrorResult( String.valueOf(HttpStatus.UNPROCESSABLE_ENTITY.value()), @@ -114,7 +114,7 @@ public ErrorResponse processProgrammingError(ProgrammingError ex) { @ExceptionHandler({AccessDeniedException.class, Forbidden.class}) @ResponseStatus(HttpStatus.FORBIDDEN) @ResponseBody - public ErrorResponse processAccessDeniedException(Throwable ex) throws MissingServletRequestPartException { + public ErrorResponse processAccessDeniedException(Throwable ex) { log.debug("Access denied", ex); ErrorResponse response = new ErrorResponse(); @@ -134,13 +134,13 @@ public void warn(Throwable ex) { @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody - public ErrorResponse processException(Throwable ex) throws MissingServletRequestPartException { + public ErrorResponse processException(Throwable ex) { // If we don't rethrow, oauth authX is broken - if (ex instanceof InsufficientAuthenticationException) { - throw (InsufficientAuthenticationException) ex; + if (ex instanceof InsufficientAuthenticationException exception) { + throw exception; } - if (ex instanceof CompletionException) { - throw (CompletionException) ex; + if (ex instanceof CompletionException exception) { + throw exception; } log.warn("Internal server error", ex); diff --git a/src/main/java/com/faforever/api/featuredmods/FeaturedModsController.java b/src/main/java/com/faforever/api/featuredmods/FeaturedModsController.java index 36647f148..19a329a35 100644 --- a/src/main/java/com/faforever/api/featuredmods/FeaturedModsController.java +++ b/src/main/java/com/faforever/api/featuredmods/FeaturedModsController.java @@ -32,8 +32,8 @@ public class FeaturedModsController { @RequestMapping(path = "/{modId}/files/{version}") @Operation(summary = "Lists the required files for a specific featured mod version") @PreAuthorize("hasScope('" + OAuthScope._LOBBY + "')") - public JsonApiDocument getFiles(@PathVariable("modId") int modId, - @PathVariable("version") String version, + public JsonApiDocument getFiles(@PathVariable int modId, + @PathVariable String version, @RequestParam(value = "page[number]", required = false) Integer page) { Integer innerPage = Optional.ofNullable(page).orElse(0); if (innerPage > 1) { diff --git a/src/main/java/com/faforever/api/featuredmods/LegacyFeaturedModFileRepository.java b/src/main/java/com/faforever/api/featuredmods/LegacyFeaturedModFileRepository.java index 1f36b1ff7..75baf68aa 100644 --- a/src/main/java/com/faforever/api/featuredmods/LegacyFeaturedModFileRepository.java +++ b/src/main/java/com/faforever/api/featuredmods/LegacyFeaturedModFileRepository.java @@ -24,9 +24,9 @@ public FeaturedModFile getFile(String modName, Integer version, String fileName) List files = getFiles(modName, version, fileName); Assert.isTrue( files.size() == 1, - String.format("Unexpected result size %d for modName: %s, version: %d, filename: %s", files.size(), modName, version, fileName) + "Unexpected result size %d for modName: %s, version: %d, filename: %s".formatted(files.size(), modName, version, fileName) ); - return files.get(0); + return files.getFirst(); } public List getFiles(String modName, Integer version) { @@ -39,7 +39,7 @@ public List getFiles(String modName, Integer version, String fi verifyModName(innerModName); // The following joke is sponsored by FAF's patcher mechanism which shouldn't even require a DB. - Query query = entityManager.createNativeQuery(String.format( + Query query = entityManager.createNativeQuery(( "SELECT" + " b.filename AS `name`," + " file.version AS `version`," + @@ -62,7 +62,7 @@ public List getFiles(String modName, Integer version, String fi " ON file.fileId = latest.fileId" + " AND file.version = latest.version" + " INNER JOIN updates_%1$s b" + - " ON b.id = file.fileId %3$s ", + " ON b.id = file.fileId %3$s ").formatted( innerModName, (version == null ? "" : "WHERE version <= :version"), (fileName == null ? "" : " AND filename = :filename") @@ -83,14 +83,12 @@ public void save(String modName, short version, List featuredMo verifyModName(innerModName); // Upsert would be preferred, but the tables have no unique constraints and it's not worth fixing them - Query deleteQuery = entityManager.createNativeQuery(String.format( - "DELETE FROM updates_%s_files WHERE version = :version", innerModName + Query deleteQuery = entityManager.createNativeQuery("DELETE FROM updates_%s_files WHERE version = :version".formatted(innerModName )); deleteQuery.setParameter("version", version); deleteQuery.executeUpdate(); - Query insertQuery = entityManager.createNativeQuery(String.format( - "INSERT INTO updates_%s_files (fileid, version, name, md5) VALUES (:fileId, :version, :name, :md5)", innerModName + Query insertQuery = entityManager.createNativeQuery("INSERT INTO updates_%s_files (fileid, version, name, md5) VALUES (:fileId, :version, :name, :md5)".formatted(innerModName )); featuredModFiles.forEach(featuredModFile -> { @@ -108,7 +106,7 @@ public Map getFileIds(String modName) { String innerModName = "ladder1v1".equals(modName) ? "faf" : modName; verifyModName(innerModName); - Query query = entityManager.createNativeQuery(String.format("SELECT id, filename FROM updates_%s", innerModName)); + Query query = entityManager.createNativeQuery("SELECT id, filename FROM updates_%s".formatted(innerModName)); return ((List) query.getResultList()).stream() .collect(Collectors.toMap(row -> (String) row[1], row -> (int) row[0])); diff --git a/src/main/java/com/faforever/api/game/GameService.java b/src/main/java/com/faforever/api/game/GameService.java index 83614458c..f1d97474e 100644 --- a/src/main/java/com/faforever/api/game/GameService.java +++ b/src/main/java/com/faforever/api/game/GameService.java @@ -13,7 +13,7 @@ public class GameService { public String getReplayDownloadUrl(int replayId) { Assert.state(replayId > 0, "Replay ID must be positive"); - String leadingZeroReplayId = String.format("%010d", replayId); + String leadingZeroReplayId = "%010d".formatted(replayId); StringBuilder sb = new StringBuilder(); diff --git a/src/main/java/com/faforever/api/map/MapService.java b/src/main/java/com/faforever/api/map/MapService.java index 22090ee22..e5e6d733a 100644 --- a/src/main/java/com/faforever/api/map/MapService.java +++ b/src/main/java/com/faforever/api/map/MapService.java @@ -495,7 +495,7 @@ String buildFolderNameWithoutVersion() { String buildFolderName(int version) { if (folderName == null) { - folderName = String.format("%s.v%04d", normalizedDisplayName, version); + folderName = "%s.v%04d".formatted(normalizedDisplayName, version); } return folderName; diff --git a/src/main/java/com/faforever/api/map/MapsController.java b/src/main/java/com/faforever/api/map/MapsController.java index f73ba98af..7a032d68e 100644 --- a/src/main/java/com/faforever/api/map/MapsController.java +++ b/src/main/java/com/faforever/api/map/MapsController.java @@ -15,8 +15,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; @@ -26,7 +27,7 @@ import java.io.IOException; import java.util.Map; -import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @RestController @RequestMapping(path = "/maps") @@ -34,12 +35,11 @@ @AllArgsConstructor public class MapsController { private final MapService mapService; - private final FafApiProperties fafApiProperties; private final ObjectMapper objectMapper; private final PlayerService playerService; - @RequestMapping(path = "/validate", method = RequestMethod.GET, produces = APPLICATION_JSON_UTF8_VALUE) + @GetMapping(path = "/validate", produces = APPLICATION_JSON_VALUE) public ModelAndView showValidationForm(Map model) { return new ModelAndView("validate_map_metadata.html"); } @@ -49,12 +49,11 @@ public ModelAndView showValidationForm(Map model) { @ApiResponse(responseCode = "200", description = "Information about derived names to be used in the scenario.lua"), @ApiResponse(responseCode = "422", description = "A list of reasons why the name is not valid.") }) - @RequestMapping( + @PostMapping( path = "/validateMapName", - method = RequestMethod.POST, - produces = APPLICATION_JSON_UTF8_VALUE + produces = APPLICATION_JSON_VALUE ) - public MapNameValidationResponse validateMapName(@RequestParam("mapName") String mapName) { + public MapNameValidationResponse validateMapName(@RequestParam String mapName) { return mapService.requestMapNameValidation(mapName); } @@ -62,12 +61,11 @@ public MapNameValidationResponse validateMapName(@RequestParam("mapName") String @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Valid without further information"), @ApiResponse(responseCode = "422", description = "A list of errors in the scenario.lua")}) - @RequestMapping( + @PostMapping( path = "/validateScenarioLua", - method = RequestMethod.POST, - produces = APPLICATION_JSON_UTF8_VALUE + produces = APPLICATION_JSON_VALUE ) - public void validateScenarioLua(@RequestParam(name = "scenarioLua") String scenarioLua) { + public void validateScenarioLua(@RequestParam String scenarioLua) { mapService.validateScenarioLua(scenarioLua); } @@ -76,9 +74,9 @@ public void validateScenarioLua(@RequestParam(name = "scenarioLua") String scena @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "Failure")}) - @RequestMapping(path = "/upload", method = RequestMethod.POST, produces = APPLICATION_JSON_UTF8_VALUE) + @PostMapping(path = "/upload", produces = APPLICATION_JSON_VALUE) @PreAuthorize("hasScope('" + OAuthScope._UPLOAD_MAP + "')") - public void uploadMap(@RequestParam("file") MultipartFile file, + public void uploadMap(@RequestParam MultipartFile file, @Deprecated @RequestParam(value = "metadata", required = false) String metadataJsonString, @RequestPart(value = "metadata", required = false) MapUploadMetadata metadata, Authentication authentication) throws IOException { diff --git a/src/main/java/com/faforever/api/mod/ModService.java b/src/main/java/com/faforever/api/mod/ModService.java index c2c72427d..76b8e7a92 100644 --- a/src/main/java/com/faforever/api/mod/ModService.java +++ b/src/main/java/com/faforever/api/mod/ModService.java @@ -35,6 +35,8 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; @@ -135,12 +137,16 @@ private void validateRepositoryUrl(String repositoryUrl) { } try { - URL url = new URL(repositoryUrl); + URI url = new URI(repositoryUrl); String host = url.getHost(); + if(host == null) { + throw ApiException.of(ErrorCode.MALFORMED_URL, repositoryUrl); + } + if (!ALLOWED_REPOSITORY_HOSTS.contains(host)) { throw ApiException.of(ErrorCode.NOT_ALLOWED_URL_HOST, repositoryUrl, String.join(", ", ALLOWED_REPOSITORY_HOSTS)); } - } catch (MalformedURLException e) { + } catch (URISyntaxException e) { throw ApiException.of(ErrorCode.MALFORMED_URL, repositoryUrl); } } @@ -287,7 +293,7 @@ private String generateZipFileName(String displayName, short version) { } private String generateFolderName(String displayName, short version) { - return String.format("%s.v%04d", NameUtil.normalizeFileName(displayName), version); + return "%s.v%04d".formatted(NameUtil.normalizeFileName(displayName), version); } private void store(com.faforever.commons.mod.Mod modInfo, Optional thumbnailPath, Player uploader, String zipFileName, Integer licenseId, String repositoryUrl) { diff --git a/src/main/java/com/faforever/api/mod/ModsController.java b/src/main/java/com/faforever/api/mod/ModsController.java index 0ce07e671..4fe6ae06c 100644 --- a/src/main/java/com/faforever/api/mod/ModsController.java +++ b/src/main/java/com/faforever/api/mod/ModsController.java @@ -9,8 +9,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; @@ -19,7 +19,7 @@ import java.io.IOException; import java.nio.file.Path; -import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @RestController @RequestMapping(path = "/mods") @@ -28,17 +28,16 @@ public class ModsController { private final PlayerService playerService; private final ModService modService; - private final FafApiProperties fafApiProperties; @Operation(summary = "Upload a mod") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "Failure")}) - @RequestMapping(path = "/upload", method = RequestMethod.POST, produces = APPLICATION_JSON_UTF8_VALUE) + @PostMapping(path = "/upload", produces = APPLICATION_JSON_VALUE) @PreAuthorize("hasScope('" + OAuthScope._UPLOAD_MOD + "')") public void uploadMod( - @RequestParam("file") MultipartFile file, + @RequestParam MultipartFile file, @RequestPart(value = "metadata", required = false) ModUploadMetadata metadata, //TODO make required when implemented by client Authentication authentication) throws IOException { diff --git a/src/main/java/com/faforever/api/security/FafServiceAuthenticationToken.java b/src/main/java/com/faforever/api/security/FafServiceAuthenticationToken.java index ca83be565..c9e040244 100644 --- a/src/main/java/com/faforever/api/security/FafServiceAuthenticationToken.java +++ b/src/main/java/com/faforever/api/security/FafServiceAuthenticationToken.java @@ -31,6 +31,6 @@ public Object getPrincipal() { @Override public String getName() { - return String.format("Service %s", serviceName); + return "Service %s".formatted(serviceName); } } diff --git a/src/main/java/com/faforever/api/security/FafUserAuthenticationToken.java b/src/main/java/com/faforever/api/security/FafUserAuthenticationToken.java index c884577b3..a9fe02c8e 100644 --- a/src/main/java/com/faforever/api/security/FafUserAuthenticationToken.java +++ b/src/main/java/com/faforever/api/security/FafUserAuthenticationToken.java @@ -36,6 +36,6 @@ public Object getPrincipal() { @Override public String getName() { - return String.format("User %s", userId); + return "User %s".formatted(userId); } } diff --git a/src/main/java/com/faforever/api/user/MeController.java b/src/main/java/com/faforever/api/user/MeController.java index 8bf23e2bc..df99a53cc 100644 --- a/src/main/java/com/faforever/api/user/MeController.java +++ b/src/main/java/com/faforever/api/user/MeController.java @@ -14,8 +14,7 @@ import lombok.RequiredArgsConstructor; import lombok.Value; import org.springframework.security.access.annotation.Secured; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @@ -33,7 +32,7 @@ public class MeController { private final PlayerService playerService; private final UserSupplier userSupplier; - @RequestMapping(method = RequestMethod.GET, value = "/me") + @GetMapping("/me") @Operation(summary = "Returns the authentication object of the current user") @ApiResponse(responseCode = "200", description = "Success with JsonApi compliant MeResult") @Secured("ROLE_USER") diff --git a/src/main/java/com/faforever/api/user/UsersController.java b/src/main/java/com/faforever/api/user/UsersController.java index 02775d380..9ce5dd5dc 100644 --- a/src/main/java/com/faforever/api/user/UsersController.java +++ b/src/main/java/com/faforever/api/user/UsersController.java @@ -33,7 +33,6 @@ @RequestMapping(path = "/users") @RequiredArgsConstructor public class UsersController { - private final FafApiProperties fafApiProperties; private final UserService userService; private final SteamService steamService; private final GogService gogService; @@ -43,9 +42,9 @@ public class UsersController { @Operation(summary = "Registers a new account that needs to be activated.") @PostMapping(path = "/register", produces = APPLICATION_JSON_VALUE) public void register(HttpServletRequest request, - @RequestParam("username") String username, - @RequestParam("email") String email, - @RequestParam(value = "recaptchaResponse", required = false) String recaptchaResponse) { + @RequestParam String username, + @RequestParam String email, + @RequestParam(required = false) String recaptchaResponse) { if (request.isUserInRole("USER")) { throw new ApiException(new Error(ErrorCode.ALREADY_REGISTERED)); } @@ -58,15 +57,15 @@ public void register(HttpServletRequest request, @PostMapping(path = "/activate", produces = APPLICATION_JSON_VALUE) public void activate(HttpServletRequest request, @RequestParam("token") String registrationToken, - @RequestParam("password") String password) { + @RequestParam String password) { userService.activate(registrationToken, password, RemoteAddressUtil.getRemoteAddress(request)); } @PreAuthorize("hasScope('" + OAuthScope._WRITE_ACCOUNT_DATA + "') and hasRole('ROLE_USER')") @Operation(summary = "Changes the password of a previously registered account.") @PostMapping(path = "/changePassword", produces = APPLICATION_JSON_VALUE) - public void changePassword(@RequestParam("currentPassword") String currentPassword, - @RequestParam("newPassword") String newPassword, + public void changePassword(@RequestParam String currentPassword, + @RequestParam String newPassword, Authentication authentication) { userService.changePassword(currentPassword, newPassword, userService.getUser(authentication)); } @@ -75,7 +74,7 @@ public void changePassword(@RequestParam("currentPassword") String currentPasswo @Operation(summary = "Changes the login of a previously registered account.") @PostMapping(path = "/changeUsername", produces = APPLICATION_JSON_VALUE) public void changeLogin(HttpServletRequest request, - @RequestParam("newUsername") String newUsername, + @RequestParam String newUsername, Authentication authentication) { userService.changeLogin( newUsername, @@ -87,8 +86,8 @@ public void changeLogin(HttpServletRequest request, @Operation(summary = "Force the change of the login of a user with the given userId.") @PostMapping(path = "/{userId}/forceChangeUsername", produces = APPLICATION_JSON_VALUE) public void forceChangeLogin(HttpServletRequest request, - @RequestParam("newUsername") String newUsername, - @PathVariable("userId") int userId) { + @RequestParam String newUsername, + @PathVariable int userId) { User user = userService.getUser(userId); userService.changeLoginForced(newUsername, user, RemoteAddressUtil.getRemoteAddress(request)); } @@ -97,8 +96,8 @@ public void forceChangeLogin(HttpServletRequest request, @Operation(summary = "Changes the email of a previously registered account.") @PostMapping(path = "/changeEmail", produces = APPLICATION_JSON_VALUE) public void changeEmail(HttpServletRequest request, - @RequestParam("currentPassword") String currentPassword, - @RequestParam("newEmail") String newEmail, Authentication authentication) { + @RequestParam String currentPassword, + @RequestParam String newEmail, Authentication authentication) { userService.changeEmail( currentPassword, newEmail, @@ -110,8 +109,8 @@ public void changeEmail(HttpServletRequest request, @Operation(summary = "Sends a password reset request to the username OR email linked by this account.") @PostMapping(path = "/requestPasswordReset", produces = APPLICATION_JSON_VALUE) - public void requestPasswordReset(@RequestParam("identifier") String identifier, - @RequestParam(value = "recaptchaResponse", required = false) String recaptchaResponse) { + public void requestPasswordReset(@RequestParam String identifier, + @RequestParam(required = false) String recaptchaResponse) { recaptchaService.validateResponse(recaptchaResponse); userService.requestPasswordReset(identifier); } @@ -119,8 +118,8 @@ public void requestPasswordReset(@RequestParam("identifier") String identifier, @Operation(summary = "Sets a new password for an account.") @PostMapping(path = "/performPasswordReset", produces = APPLICATION_JSON_VALUE) public void performPasswordReset(HttpServletResponse response, - @RequestParam("token") String token, - @RequestParam("newPassword") String newPassword) { + @RequestParam String token, + @RequestParam String newPassword) { userService.performPasswordReset(token, newPassword); } @@ -128,7 +127,7 @@ public void performPasswordReset(HttpServletResponse response, @Operation(summary = "Creates an URL to the steam platform to initiate the Link To Steam process.") @PostMapping(path = "/buildSteamLinkUrl", produces = APPLICATION_JSON_VALUE) public Map buildSteamLinkUrl(Authentication authentication, - @RequestParam("callbackUrl") String callbackUrl) { + @RequestParam String callbackUrl) { String steamUrl = userService.buildSteamLinkUrl(userService.getUser(authentication), callbackUrl); return Map.of("steamUrl", steamUrl); } @@ -154,7 +153,7 @@ public void requestPasswordResetViaSteam(HttpServletRequest request, @GetMapping(path = "/linkToSteam", produces = APPLICATION_JSON_VALUE) public void linkToSteam(HttpServletRequest request, HttpServletResponse response, - @RequestParam("token") String token) { + @RequestParam String token) { steamService.validateSteamRedirect(request); CallbackResult result = userService.linkToSteam(token, steamService.parseSteamIdFromLoginRedirect(request)); redirectCallbackResult(response, result); @@ -178,7 +177,7 @@ public Map buildGogProfileToken(Authentication authenticat @PreAuthorize("hasScope('" + OAuthScope._WRITE_ACCOUNT_DATA + "') and hasRole('ROLE_USER')") @Operation(summary = "Attempt to link a GOG account to this account.") @PostMapping(path = "/linkToGog", produces = APPLICATION_JSON_VALUE) - public void linkToGog(@RequestParam("gogUsername") String gogUsername, + public void linkToGog(@RequestParam String gogUsername, Authentication authentication) { userService.linkToGogAccount(gogUsername, userService.getUser(authentication)); } diff --git a/src/main/java/com/faforever/api/utils/NameUtil.java b/src/main/java/com/faforever/api/utils/NameUtil.java index da07d0875..887c94c35 100644 --- a/src/main/java/com/faforever/api/utils/NameUtil.java +++ b/src/main/java/com/faforever/api/utils/NameUtil.java @@ -2,7 +2,7 @@ import org.apache.commons.lang3.StringUtils; -import java.nio.file.Paths; +import java.nio.file.Path; import java.text.Normalizer; import java.text.Normalizer.Form; import java.util.Locale; @@ -27,7 +27,7 @@ public static String normalizeWhitespaces(String anyName) { public static String normalizeFileName(String originalFileName) { return StringUtils.strip( Normalizer.normalize( - Paths.get(originalFileName + Path.of(originalFileName .replaceAll("[^\\w\\d.-]", "_") .toLowerCase(Locale.US)) .getFileName() diff --git a/src/main/java/com/faforever/api/voting/VotingController.java b/src/main/java/com/faforever/api/voting/VotingController.java index 71d46ddf5..3d42b64d9 100644 --- a/src/main/java/com/faforever/api/voting/VotingController.java +++ b/src/main/java/com/faforever/api/voting/VotingController.java @@ -10,9 +10,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import jakarta.servlet.http.HttpServletRequest; @@ -30,13 +31,13 @@ public class VotingController { @Operation(summary = "Post a vote") @PreAuthorize("hasScope('" + OAuthScope._VOTE + "')") - @RequestMapping(path = "/vote", method = RequestMethod.POST, produces = JsonApiMediaType.JSON_API_MEDIA_TYPE) + @PostMapping(path = "/vote", produces = JsonApiMediaType.JSON_API_MEDIA_TYPE) public void postVote(@RequestBody Vote vote, Authentication authentication) { votingService.saveVote(vote, playerService.getPlayer(authentication)); } @Operation(summary = "See if user can vote on a subject") - @RequestMapping(path = "/votingSubjectsAbleToVote", method = RequestMethod.GET, produces = JsonApiMediaType.JSON_API_MEDIA_TYPE) + @GetMapping(path = "/votingSubjectsAbleToVote", produces = JsonApiMediaType.JSON_API_MEDIA_TYPE) public void votingSubjectsAbleTo(HttpServletResponse response, Authentication authentication, HttpServletRequest request) throws IOException { List votingSubjects = votingService.votingSubjectsAbleToVote(playerService.getPlayer(authentication)); redirectToFilteredVotingSubjects(response, votingSubjects, request); @@ -64,9 +65,9 @@ private void redirectToFilteredVotingSubjects(HttpServletResponse response, List String queryString = request.getQueryString(); if (!Strings.isNullOrEmpty(queryString)) { - response.sendRedirect(String.format("/data/votingSubject?%s&filter=%s", queryString, filter)); + response.sendRedirect("/data/votingSubject?%s&filter=%s".formatted(queryString, filter)); } else { - response.sendRedirect(String.format("/data/votingSubject?filter=%s", filter)); + response.sendRedirect("/data/votingSubject?filter=%s".formatted(filter)); } } } diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 3d5ec7ff5..12b624e8d 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -148,6 +148,9 @@ spring: resourceserver: jwt: issuer-uri: ${JWT_FAF_HYDRA_ISSUER:https://hydra.${FAF_DOMAIN}/} + threads: + virtual: + enabled: true server: # Mind that this is configured in the docker compose file as well (that is, in the gradle script that generates it) @@ -175,7 +178,7 @@ logging: console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%36.36X{requestId:- no request context}]){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" level: com.faforever: ${LOG_LEVEL:info} - file: + file.name: path: ${LOG_FILE_DIRECTORY:} springdoc: swagger-ui: diff --git a/src/test/java/com/faforever/api/avatar/AvatarServiceTest.java b/src/test/java/com/faforever/api/avatar/AvatarServiceTest.java index 5936f506f..cf9d305bd 100644 --- a/src/test/java/com/faforever/api/avatar/AvatarServiceTest.java +++ b/src/test/java/com/faforever/api/avatar/AvatarServiceTest.java @@ -53,7 +53,7 @@ public class AvatarServiceTest { private static final int EXISTING_AVATAR_ID = 1; private static final int NON_EXISTING_AVATAR_ID = 2; private static final Optional AVATAR = Optional.of(new Avatar() - .setUrl(String.format(DOWNLOAD_URL_FORMAT, EXISTING_VALID_AVATAR_FILENAME)) + .setUrl(DOWNLOAD_URL_FORMAT.formatted(EXISTING_VALID_AVATAR_FILENAME)) .setTooltip(EXISTING_AVATAR_NAME) ); @@ -116,7 +116,7 @@ public void existingAvatarReuploadWithDifferentValidName() throws Exception { verify(avatarRepository, times(1)).save(avatarCaptor.capture()); final Avatar storedAvatar = avatarCaptor.getValue(); - assertEquals(String.format(DOWNLOAD_URL_FORMAT, EXISTING_VALID_AVATAR_FILENAME), storedAvatar.getUrl()); + assertEquals(DOWNLOAD_URL_FORMAT.formatted(EXISTING_VALID_AVATAR_FILENAME), storedAvatar.getUrl()); assertEquals(AVATAR_NAME, storedAvatar.getTooltip()); assertThat(avatarsPath.resolve(EXISTING_VALID_AVATAR_FILENAME).toFile().length(), is(imageResource.openConnection().getContentLengthLong())); } @@ -125,7 +125,7 @@ public void existingAvatarReuploadWithDifferentValidName() throws Exception { @Test public void duplicateAvatarUpload() throws Exception { final String avatarFileName = VALID_AVATAR_FILENAME; - when(avatarRepository.findOneByFilename(String.format(avatarFileName))).thenReturn(Optional.of(new Avatar())); + when(avatarRepository.findOneByFilename(avatarFileName.formatted())).thenReturn(Optional.of(new Avatar())); try (final InputStream imageInputStream = loadResource(avatarFileName).openStream()) { ApiException result = assertThrows(ApiException.class, () -> avatarService.createAvatar(AVATAR_METADATA, avatarFileName, imageInputStream, VALID_FILE_SIZE)); assertThat(result, hasErrorCode(ErrorCode.AVATAR_NAME_CONFLICT)); diff --git a/src/test/java/com/faforever/api/clan/ClanServiceTest.java b/src/test/java/com/faforever/api/clan/ClanServiceTest.java index 7888d747e..f525fe744 100644 --- a/src/test/java/com/faforever/api/clan/ClanServiceTest.java +++ b/src/test/java/com/faforever/api/clan/ClanServiceTest.java @@ -29,8 +29,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -212,7 +212,7 @@ public void acceptPlayerInvitationTokenExpire() throws IOException { String stringToken = "1234"; long expire = System.currentTimeMillis(); - when(jwtService.decodeAndVerify(any())).thenReturn(String.format("{\"expire\":%s}", expire)); + when(jwtService.decodeAndVerify(any())).thenReturn("{\"expire\":%s}".formatted(expire)); ApiException result = assertThrows(ApiException.class, () -> instance.acceptPlayerInvitationToken(stringToken, null)); assertThat(result, hasErrorCode(ErrorCode.CLAN_ACCEPT_TOKEN_EXPIRE)); @@ -225,7 +225,7 @@ public void acceptPlayerInvitationTokenInvalidClan() throws IOException { String stringToken = "1234"; long expire = System.currentTimeMillis() + 1000 * 3; - when(jwtService.decodeAndVerify(any())).thenReturn(String.format("{\"expire\":%s,\"clan\":{\"id\":42}}", expire)); + when(jwtService.decodeAndVerify(any())).thenReturn("{\"expire\":%s,\"clan\":{\"id\":42}}".formatted(expire)); ApiException result = assertThrows(ApiException.class, () -> instance.acceptPlayerInvitationToken(stringToken, null)); assertThat(result, hasErrorCode(ErrorCode.CLAN_NOT_EXISTS)); @@ -240,7 +240,7 @@ public void acceptPlayerInvitationTokenInvalidPlayer() throws IOException { Clan clan = ClanFactory.builder().build(); long expire = System.currentTimeMillis() + 1000 * 3; - String tokenResult = String.format("{\"expire\":%s,\"newMember\":{\"id\":2},\"clan\":{\"id\":%s}}", + String tokenResult = "{\"expire\":%s,\"newMember\":{\"id\":2},\"clan\":{\"id\":%s}}".formatted( expire, clan.getId()); when(jwtService.decodeAndVerify(any())).thenReturn(tokenResult); when(clanRepository.findById(clan.getId())).thenReturn(Optional.of(clan)); @@ -264,7 +264,7 @@ public void acceptPlayerInvitationTokenWrongPlayer() throws IOException { otherPlayer.setId(3); long expire = System.currentTimeMillis() + 1000 * 3; - String tokenResult = String.format("{\"expire\":%s,\"newMember\":{\"id\":%s},\"clan\":{\"id\":%s}}", + String tokenResult = "{\"expire\":%s,\"newMember\":{\"id\":%s},\"clan\":{\"id\":%s}}".formatted( expire, newMember.getId(), clan.getId()); when(jwtService.decodeAndVerify(any())).thenReturn(tokenResult); when(clanRepository.findById(clan.getId())).thenReturn(Optional.of(clan)); @@ -288,7 +288,7 @@ public void acceptPlayerInvitationTokenPlayerIAlreadyInAClan() throws IOExceptio newMember.setClanMembership(new ClanMembership().setClan(clan).setPlayer(newMember)); long expire = System.currentTimeMillis() + 1000 * 3; - String tokenResult = String.format("{\"expire\":%s,\"newMember\":{\"id\":%s},\"clan\":{\"id\":%s}}", + String tokenResult = "{\"expire\":%s,\"newMember\":{\"id\":%s},\"clan\":{\"id\":%s}}".formatted( expire, newMember.getId(), clan.getId()); when(jwtService.decodeAndVerify(any())).thenReturn(tokenResult); @@ -309,7 +309,7 @@ public void acceptPlayerInvitationToken() throws IOException { Player newMember = new Player(); newMember.setId(2); long expire = System.currentTimeMillis() + 1000 * 3; - String tokenResult = String.format("{\"expire\":%s,\"newMember\":{\"id\":%s},\"clan\":{\"id\":%s}}", + String tokenResult = "{\"expire\":%s,\"newMember\":{\"id\":%s},\"clan\":{\"id\":%s}}".formatted( expire, newMember.getId(), clan.getId()); when(jwtService.decodeAndVerify(any())).thenReturn(tokenResult); diff --git a/src/test/java/com/faforever/api/config/TestWebSecurityConfig.java b/src/test/java/com/faforever/api/config/TestWebSecurityConfig.java index 5736cd089..3037eaff4 100644 --- a/src/test/java/com/faforever/api/config/TestWebSecurityConfig.java +++ b/src/test/java/com/faforever/api/config/TestWebSecurityConfig.java @@ -10,7 +10,7 @@ public class TestWebSecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http.csrf().disable(); + http.csrf(csrf -> csrf.disable()); return http.build(); } } diff --git a/src/test/java/com/faforever/api/deployment/ExeUploaderControllerTest.java b/src/test/java/com/faforever/api/deployment/ExeUploaderControllerTest.java index eb86d4d92..c0f8f905b 100644 --- a/src/test/java/com/faforever/api/deployment/ExeUploaderControllerTest.java +++ b/src/test/java/com/faforever/api/deployment/ExeUploaderControllerTest.java @@ -4,13 +4,11 @@ import com.faforever.api.config.TestWebSecurityConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import jakarta.inject.Inject; @@ -20,7 +18,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ExtendWith(SpringExtension.class) @WebMvcTest(ExeUploaderController.class) @Import(TestWebSecurityConfig.class) public class ExeUploaderControllerTest { diff --git a/src/test/java/com/faforever/api/deployment/ExeUploaderServiceTest.java b/src/test/java/com/faforever/api/deployment/ExeUploaderServiceTest.java index b8a83c3a6..df13149c5 100644 --- a/src/test/java/com/faforever/api/deployment/ExeUploaderServiceTest.java +++ b/src/test/java/com/faforever/api/deployment/ExeUploaderServiceTest.java @@ -21,7 +21,6 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; @@ -95,7 +94,7 @@ public void testProcessUploadBeta() { featuredModFile); instance.processUpload(exeDataInputStream, modName); - assertTrue(Files.exists(Paths.get(finalExeDestination))); + assertTrue(Files.exists(Path.of(finalExeDestination))); ArgumentCaptor> modFilesCaptor = ArgumentCaptor.forClass(List.class); verify(featuredModService).save(eq(modName), eq((short) featuredModFile.getVersion()), modFilesCaptor.capture()); assertThat(modFilesCaptor.getValue().size(), is(1)); @@ -119,7 +118,7 @@ public void testProcessUploadDevelop() { featuredModFile); instance.processUpload(exeDataInputStream, modName); - assertTrue(Files.exists(Paths.get(finalExeDestination))); + assertTrue(Files.exists(Path.of(finalExeDestination))); ArgumentCaptor> modFilesCaptor = ArgumentCaptor.forClass(List.class); verify(featuredModService).save(eq(modName), eq((short) featuredModFile.getVersion()), modFilesCaptor.capture()); assertThat(modFilesCaptor.getValue().size(), is(1)); diff --git a/src/test/java/com/faforever/api/error/GlobalControllerExceptionHandlerTest.java b/src/test/java/com/faforever/api/error/GlobalControllerExceptionHandlerTest.java index 573692e56..d237cd5ff 100644 --- a/src/test/java/com/faforever/api/error/GlobalControllerExceptionHandlerTest.java +++ b/src/test/java/com/faforever/api/error/GlobalControllerExceptionHandlerTest.java @@ -27,8 +27,8 @@ import java.util.Set; import java.util.stream.Stream; -import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; public class GlobalControllerExceptionHandlerTest { private static final String COMMON_MESSAGE = "Error"; @@ -46,7 +46,7 @@ public void testErrorFormatting() { ErrorResponse response = instance.processApiException(ex); assertEquals(1, response.getErrors().size()); - final ErrorResult errorResult = response.getErrors().get(0); + final ErrorResult errorResult = response.getErrors().getFirst(); assertEquals(ErrorCode.CLAN_NAME_EXISTS.getTitle(), errorResult.getTitle()); assertEquals(MessageFormat.format(ErrorCode.CLAN_NAME_EXISTS.getDetail(), "My Clan"), errorResult.getDetail()); assertEquals(String.valueOf(ErrorCode.CLAN_NAME_EXISTS.getCode()), errorResult.getAppCode()); @@ -59,7 +59,7 @@ public void testErrorFormattingNull() { ErrorResponse response = instance.processApiException(ex); assertEquals(1, response.getErrors().size()); - final ErrorResult errorResult = response.getErrors().get(0); + final ErrorResult errorResult = response.getErrors().getFirst(); assertEquals(ErrorCode.CLAN_NAME_EXISTS.getTitle(), errorResult.getTitle()); assertEquals(MessageFormat.format(ErrorCode.CLAN_NAME_EXISTS.getDetail(), new Object[0]), errorResult.getDetail()); assertEquals(String.valueOf(ErrorCode.CLAN_NAME_EXISTS.getCode()), errorResult.getAppCode()); @@ -72,7 +72,7 @@ public void testProgrammingError() { ErrorResponse response = instance.processProgrammingError(ex); assertEquals(1, response.getErrors().size()); - final ErrorResult errorResult = response.getErrors().get(0); + final ErrorResult errorResult = response.getErrors().getFirst(); assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), errorResult.getTitle()); assertEquals(COMMON_MESSAGE, errorResult.getDetail()); } @@ -83,7 +83,7 @@ public void testProcessResourceNotFoundException(final ServletException ex) { ErrorResponse response = instance.processResourceNotFoundException(ex); assertEquals(1, response.getErrors().size()); - final ErrorResult errorResult = response.getErrors().get(0); + final ErrorResult errorResult = response.getErrors().getFirst(); assertAll( () -> assertEquals(HttpStatus.NOT_FOUND.getReasonPhrase(), errorResult.getTitle()), @@ -98,7 +98,7 @@ public void testValidationException() { ErrorResponse response = instance.processValidationException(ex); assertEquals(1, response.getErrors().size()); - final ErrorResult errorResult = response.getErrors().get(0); + final ErrorResult errorResult = response.getErrors().getFirst(); assertEquals(ErrorCode.VALIDATION_FAILED.getTitle(), errorResult.getTitle()); assertEquals(COMMON_MESSAGE, errorResult.getDetail()); assertEquals(String.valueOf(ErrorCode.VALIDATION_FAILED.getCode()), errorResult.getAppCode()); @@ -125,7 +125,7 @@ public void testConstraintViolationException() { ErrorResponse response = instance.processConstraintViolationException(ex); assertEquals(3, response.getErrors().size()); - final ErrorResult errorResult = response.getErrors().get(0); + final ErrorResult errorResult = response.getErrors().getFirst(); assertEquals(ErrorCode.VALIDATION_FAILED.getTitle(), errorResult.getTitle()); assertEquals(String.valueOf(ErrorCode.VALIDATION_FAILED.getCode()), errorResult.getAppCode()); } diff --git a/src/test/java/com/faforever/api/map/MapServiceTest.java b/src/test/java/com/faforever/api/map/MapServiceTest.java index 9ae49a609..48e104874 100644 --- a/src/test/java/com/faforever/api/map/MapServiceTest.java +++ b/src/test/java/com/faforever/api/map/MapServiceTest.java @@ -53,10 +53,7 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.never; @@ -387,7 +384,7 @@ void positiveUploadTest() throws Exception { assertEquals("FFA", mapCaptor.getValue().getBattleType()); assertEquals(1, mapCaptor.getValue().getVersions().size()); - MapVersion mapVersion = mapCaptor.getValue().getVersions().get(0); + MapVersion mapVersion = mapCaptor.getValue().getVersions().getFirst(); assertEquals("For example on map crazyrush. Universal Command Conquer 3 modification by RuCommunity. Prealpha test", mapVersion.getDescription()); assertEquals(7, mapVersion.getVersion()); assertEquals(256, mapVersion.getHeight()); diff --git a/src/test/java/com/faforever/api/mod/ModServiceTest.java b/src/test/java/com/faforever/api/mod/ModServiceTest.java index 3820031f8..c7a389a1d 100644 --- a/src/test/java/com/faforever/api/mod/ModServiceTest.java +++ b/src/test/java/com/faforever/api/mod/ModServiceTest.java @@ -99,7 +99,7 @@ public void processUploadedMod() throws Exception { assertThat(savedMod.getUploader(), is(uploader)); assertThat(savedMod.getRepositoryUrl(), is(repositoryUrl)); - ModVersion savedModVersion = savedMod.getVersions().get(0); + ModVersion savedModVersion = savedMod.getVersions().getFirst(); assertThat(savedModVersion.getId(), is(nullValue())); assertThat(savedModVersion.getIcon(), is("no_friendly_fire.v0003.png")); diff --git a/src/test/java/com/faforever/api/security/FafTokenServiceTest.java b/src/test/java/com/faforever/api/security/FafTokenServiceTest.java index bebb973ce..a5707b1d7 100644 --- a/src/test/java/com/faforever/api/security/FafTokenServiceTest.java +++ b/src/test/java/com/faforever/api/security/FafTokenServiceTest.java @@ -15,7 +15,7 @@ import org.junit.jupiter.api.Test; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; import java.security.interfaces.RSAPublicKey; import java.time.Duration; import java.util.Map; @@ -64,8 +64,8 @@ public class FafTokenServiceTest { private FafTokenService instance; public FafTokenServiceTest() throws Exception { - String secretKey = Files.readString(Paths.get("test-pki-private.key")); - String publicKey = Files.readString(Paths.get("test-pki-public.key")); + String secretKey = Files.readString(Path.of("test-pki-private.key")); + String publicKey = Files.readString(Path.of("test-pki-public.key")); RSAKey parsedSecretKey = (RSAKey) RSAKey.parseFromPEMEncodedObjects(secretKey); RSAPublicKey parsedPublicKey = CertificateUtils.parseSSHPublicKey(publicKey); @@ -80,8 +80,8 @@ public void setUp() throws Exception { objectMapper.registerModule(new JavaTimeModule()); FafApiProperties properties = new FafApiProperties(); - properties.getJwt().setSecretKeyPath(Paths.get("test-pki-private.key")); - properties.getJwt().setPublicKeyPath(Paths.get("test-pki-public.key")); + properties.getJwt().setSecretKeyPath(Path.of("test-pki-private.key")); + properties.getJwt().setPublicKeyPath(Path.of("test-pki-public.key")); instance = new FafTokenService(objectMapper, properties); } diff --git a/src/test/java/com/faforever/api/user/GogServiceTest.java b/src/test/java/com/faforever/api/user/GogServiceTest.java index a590ceb3f..89f28501c 100644 --- a/src/test/java/com/faforever/api/user/GogServiceTest.java +++ b/src/test/java/com/faforever/api/user/GogServiceTest.java @@ -174,9 +174,9 @@ void verifyProfileTokenSuccess() { void verifyGameOwnershipSuccess() { when(fafApiProperties.getGog().getGamesListUrl()).thenReturn(GAME_LIST_PAGE_URL); - when(restTemplate.getForObject(String.format(GAME_LIST_PAGE_URL, GOG_USERNAME, 1), GogService.GogGamesListPage.class)) + when(restTemplate.getForObject(GAME_LIST_PAGE_URL.formatted(GOG_USERNAME, 1), GogService.GogGamesListPage.class)) .thenReturn(new GogService.GogGamesListPage(2, new GogService.GogGamesListEmbeddedList(List.of()))); - when(restTemplate.getForObject(String.format(GAME_LIST_PAGE_URL, GOG_USERNAME, 2), GogService.GogGamesListPage.class)) + when(restTemplate.getForObject(GAME_LIST_PAGE_URL.formatted(GOG_USERNAME, 2), GogService.GogGamesListPage.class)) .thenReturn(new GogService.GogGamesListPage(2, new GogService.GogGamesListEmbeddedList( List.of( new GogService.GogGamesListEntry(new GogService.GogGamesListEntryGameDetails("12345")), @@ -191,7 +191,7 @@ void verifyGameOwnershipSuccess() { void verifyGameOwnershipGameNotPresent() { when(fafApiProperties.getGog().getGamesListUrl()).thenReturn(GAME_LIST_PAGE_URL); - when(restTemplate.getForObject(String.format(GAME_LIST_PAGE_URL, GOG_USERNAME, 1), GogService.GogGamesListPage.class)) + when(restTemplate.getForObject(GAME_LIST_PAGE_URL.formatted(GOG_USERNAME, 1), GogService.GogGamesListPage.class)) .thenReturn(new GogService.GogGamesListPage(1, new GogService.GogGamesListEmbeddedList(List.of()))); ApiException result = assertThrows(ApiException.class, () -> instance.verifyGameOwnership(GOG_USERNAME)); @@ -202,7 +202,7 @@ void verifyGameOwnershipGameNotPresent() { void verifyGameOwnershipGameNotPublic() { when(fafApiProperties.getGog().getGamesListUrl()).thenReturn(GAME_LIST_PAGE_URL); - when(restTemplate.getForObject(String.format(GAME_LIST_PAGE_URL, GOG_USERNAME, 1), GogService.GogGamesListPage.class)) + when(restTemplate.getForObject(GAME_LIST_PAGE_URL.formatted(GOG_USERNAME, 1), GogService.GogGamesListPage.class)) .thenThrow(HttpClientErrorException.create(HttpStatus.FORBIDDEN, "", HttpHeaders.EMPTY, null, null)); ApiException result = assertThrows(ApiException.class, () -> instance.verifyGameOwnership(GOG_USERNAME)); @@ -213,7 +213,7 @@ void verifyGameOwnershipGameNotPublic() { void verifyGameOwnershipGameNotFound() { when(fafApiProperties.getGog().getGamesListUrl()).thenReturn(GAME_LIST_PAGE_URL); - when(restTemplate.getForObject(String.format(GAME_LIST_PAGE_URL, GOG_USERNAME, 1), GogService.GogGamesListPage.class)) + when(restTemplate.getForObject(GAME_LIST_PAGE_URL.formatted(GOG_USERNAME, 1), GogService.GogGamesListPage.class)) .thenThrow(HttpClientErrorException.create(HttpStatus.NOT_FOUND, "", HttpHeaders.EMPTY, null, null)); ApiException result = assertThrows(ApiException.class, () -> instance.verifyGameOwnership(GOG_USERNAME)); diff --git a/src/test/java/com/faforever/api/user/UserServiceTest.java b/src/test/java/com/faforever/api/user/UserServiceTest.java index b89901f9c..5b13e3c74 100644 --- a/src/test/java/com/faforever/api/user/UserServiceTest.java +++ b/src/test/java/com/faforever/api/user/UserServiceTest.java @@ -136,7 +136,7 @@ public void register() throws Exception{ ArgumentCaptor urlCaptor = ArgumentCaptor.forClass(String.class); verify(emailService).sendActivationMail(eq(TEST_USERNAME), eq(TEST_CURRENT_EMAIL), urlCaptor.capture()); - assertThat(urlCaptor.getValue(), is(String.format(ACTIVATION_URL_FORMAT, TEST_USERNAME, TOKEN_VALUE))); + assertThat(urlCaptor.getValue(), is(ACTIVATION_URL_FORMAT.formatted(TEST_USERNAME, TOKEN_VALUE))); verifyNoMoreInteractions(eventPublisher); } @@ -345,7 +345,7 @@ public void resetPasswordByLogin() throws Exception { ArgumentCaptor urlCaptor = ArgumentCaptor.forClass(String.class); verify(emailService).sendPasswordResetMail(eq(TEST_USERNAME), eq(TEST_CURRENT_EMAIL), urlCaptor.capture()); - assertThat(urlCaptor.getValue(), is(String.format(PASSWORD_RESET_URL_FORMAT, TEST_USERNAME, TOKEN_VALUE))); + assertThat(urlCaptor.getValue(), is(PASSWORD_RESET_URL_FORMAT.formatted(TEST_USERNAME, TOKEN_VALUE))); ArgumentCaptor> attributesMapCaptor = ArgumentCaptor.forClass(Map.class); verify(fafTokenService).createToken(eq(FafTokenType.PASSWORD_RESET), any(), attributesMapCaptor.capture()); @@ -368,7 +368,7 @@ public void resetPasswordByEmail() throws Exception { ArgumentCaptor urlCaptor = ArgumentCaptor.forClass(String.class); verify(emailService).sendPasswordResetMail(eq(TEST_USERNAME), eq(TEST_CURRENT_EMAIL), urlCaptor.capture()); - assertThat(urlCaptor.getValue(), is(String.format(PASSWORD_RESET_URL_FORMAT, TEST_USERNAME, TOKEN_VALUE))); + assertThat(urlCaptor.getValue(), is(PASSWORD_RESET_URL_FORMAT.formatted(TEST_USERNAME, TOKEN_VALUE))); ArgumentCaptor> attributesMapCaptor = ArgumentCaptor.forClass(Map.class); verify(fafTokenService).createToken(eq(FafTokenType.PASSWORD_RESET), any(), attributesMapCaptor.capture()); diff --git a/src/test/resources/config/application.yml b/src/test/resources/config/application.yml index 4159defb7..037556dc8 100644 --- a/src/test/resources/config/application.yml +++ b/src/test/resources/config/application.yml @@ -22,6 +22,9 @@ spring: jwt: # Using this config, we avoid lookup of the uri - it's just a temporary fix until all calls are mocked jwk-set-uri: "http://localhost" + threads: + virtual: + enabled: true security: oauth2: