Public Access
refactor: item 29 cleanup
A10 A11 A12 A13 A14 A15 X10 X11 X12: role check denies outside a request, no API versioning, open-in-view off, no passwords in toString, X-Forwarded-For only from private peers, CORS from APP_FRONTEND_URL, non-root image.
This commit is contained in:
1 parent
89e2fa3df2
commit
9f56742ff6
27 files changed
+134
-85
No files matched your search
@@ -20,8 +20,8 @@ import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class RoleAuthorizationManagerTest extends AbstractUnitTest {
|
||||
|
||||
@@ -62,9 +62,8 @@ class RoleAuthorizationManagerTest extends AbstractUnitTest {
|
||||
|
||||
private boolean granted(Authentication authentication, Object target, String method) throws Exception {
|
||||
MethodInvocation invocation = mock(MethodInvocation.class);
|
||||
// Lenient: without a request the manager does not look at the invocation.
|
||||
lenient().when(invocation.getThis()).thenReturn(target);
|
||||
lenient().when(invocation.getMethod()).thenReturn(target.getClass().getMethod(method));
|
||||
when(invocation.getThis()).thenReturn(target);
|
||||
when(invocation.getMethod()).thenReturn(target.getClass().getMethod(method));
|
||||
return manager.authorize(() -> authentication, invocation).isGranted();
|
||||
}
|
||||
|
||||
@@ -94,7 +93,9 @@ class RoleAuthorizationManagerTest extends AbstractUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void withoutARequest_EverythingRuns() throws Exception {
|
||||
assertTrue(granted(null, new UserMarked(), "audit"));
|
||||
void withoutARequest_OnlyPublicMethodsRun() throws Exception {
|
||||
assertFalse(granted(null, new UserMarked(), "audit"));
|
||||
assertFalse(granted(null, new UserMarked(), "plain"));
|
||||
assertTrue(granted(null, new UserMarked(), "open"));
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
@@ -19,7 +20,7 @@ import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilde
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@@ -138,7 +139,7 @@ class RoleCheckFlowTest extends AbstractIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void outsideARequest_TheServiceRuns() {
|
||||
assertEquals("auditor", probeService.auditor());
|
||||
void outsideARequest_OnlyPublicMethodsRun() {
|
||||
assertThrows(AuthenticationCredentialsNotFoundException.class, probeService::auditor);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@ class SessionFlowTest extends AbstractIntegrationTest {
|
||||
private static final String EMAIL = "session-flow@example.com";
|
||||
private static final String PASSWORD = "correct horse battery";
|
||||
private static final String CLIENT = "web";
|
||||
private static final String FRONTEND = "https://tbp.andreas-dahm.eu";
|
||||
// app.frontend-url in tests; CORS allows only it.
|
||||
private static final String FRONTEND = "http://localhost:5173";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package auth_service.modules.login.model;
|
||||
|
||||
import auth_service.modules.registration.model.Registration;
|
||||
import auth_service.shared.test.AbstractUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class UserTest extends AbstractUnitTest {
|
||||
|
||||
@Test
|
||||
void toString_ShowsNoPassword() {
|
||||
assertThat(User.builder().email("a@example.com").password("hash-secret").build().toString())
|
||||
.contains("a@example.com").doesNotContain("hash-secret");
|
||||
assertThat(Registration.builder().email("a@example.com").rawPassword("raw-secret").encryptedPassword("hash-secret")
|
||||
.build().toString()).doesNotContain("raw-secret").doesNotContain("hash-secret");
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_Success() throws Exception {
|
||||
void getCurrentUser_Success() throws Exception {
|
||||
// Arrange
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark").build();
|
||||
@@ -99,7 +99,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_SteamIdIsSentAsExactString() throws Exception {
|
||||
void getCurrentUser_SteamIdIsSentAsExactString() throws Exception {
|
||||
// Arrange
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark").build();
|
||||
@@ -119,7 +119,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_NoSteamId() throws Exception {
|
||||
void getCurrentUser_NoSteamId() throws Exception {
|
||||
// Arrange
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark").build();
|
||||
@@ -138,7 +138,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_NotFound() throws Exception {
|
||||
void getCurrentUser_NotFound() throws Exception {
|
||||
// Arrange
|
||||
var email = "notfound@example.com";
|
||||
var principal = new UserPrincipal("1", null);
|
||||
@@ -190,7 +190,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_ReturnsDisplayName() throws Exception {
|
||||
void getCurrentUser_ReturnsDisplayName() throws Exception {
|
||||
// Arrange
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark").build();
|
||||
@@ -309,7 +309,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_ShowsPublicProfile() throws Exception {
|
||||
void getCurrentUser_ShowsPublicProfile() throws Exception {
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark").publicProfile(true).build();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
@@ -323,7 +323,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_ShowsAppearance() throws Exception {
|
||||
void getCurrentUser_ShowsAppearance() throws Exception {
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark")
|
||||
.appearance(new Appearance("blue", "round", true, 620L, 1086940L, false)).build();
|
||||
@@ -343,7 +343,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_WithoutBackground_SendsNull() throws Exception {
|
||||
void getCurrentUser_WithoutBackground_SendsNull() throws Exception {
|
||||
var email = "test@example.com";
|
||||
var settings = UserSettings.builder().language("en").theme("dark").build();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
@@ -362,7 +362,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_ShowsTheTileLayouts() throws Exception {
|
||||
void getCurrentUser_ShowsTheTileLayouts() throws Exception {
|
||||
String email = "test@example.com";
|
||||
UserSettings settings = UserSettings.builder().language("en").theme("dark")
|
||||
.dashboardTiles(List.of(new Tile("STATS_TREND", "L")))
|
||||
@@ -382,7 +382,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_NeverChangedDashboard_SendsNullTiles() throws Exception {
|
||||
void getCurrentUser_NeverChangedDashboard_SendsNullTiles() throws Exception {
|
||||
String email = "test@example.com";
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new UsernamePasswordAuthenticationToken(new UserPrincipal("1", null), null, Collections.emptyList())
|
||||
@@ -518,7 +518,7 @@ class UserControllerTest extends AbstractWebMvcTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCurrentUserV1_ShowsTheProfileStyle() throws Exception {
|
||||
void getCurrentUser_ShowsTheProfileStyle() throws Exception {
|
||||
String email = "test@example.com";
|
||||
UserSettings settings = UserSettings.builder().language("en").theme("dark")
|
||||
.profileStyle(new ProfileStyle("red", "sharp", 620L, null)).build();
|
||||
|
||||
@@ -25,4 +25,24 @@ class ClientIpTest extends AbstractUnitTest {
|
||||
|
||||
assertEquals("198.51.100.9", ClientIp.of(request));
|
||||
}
|
||||
|
||||
private static String clientIp(String peer, String forwardedFor) {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRemoteAddr(peer);
|
||||
request.addHeader("X-Forwarded-For", forwardedFor);
|
||||
return ClientIp.of(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void publicPeer_CannotChooseItsIpByTheHeader() {
|
||||
assertEquals("198.51.100.9", clientIp("198.51.100.9", "203.0.113.5"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void proxyInThePrivateNetwork_GivesTheLastHop() {
|
||||
assertEquals("203.0.113.5", clientIp("172.18.0.2", "1.2.3.4, 203.0.113.5"));
|
||||
assertEquals("203.0.113.5", clientIp("10.0.0.3", "203.0.113.5"));
|
||||
assertEquals("203.0.113.5", clientIp("127.0.0.1", "203.0.113.5"));
|
||||
assertEquals("203.0.113.5", clientIp("fd00::2", "203.0.113.5"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user