-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🚚 : create specific package for security config
- Loading branch information
1 parent
26e21f4
commit 09e61de
Showing
8 changed files
with
251 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
src/main/java/io/codeka/gaia/config/security/SuccessHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package io.codeka.gaia.config.security; | ||
|
||
import io.codeka.gaia.teams.User; | ||
import io.codeka.gaia.teams.repository.UserRepository; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; | ||
import org.springframework.security.web.savedrequest.DefaultSavedRequest; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
|
||
@Component | ||
public class SuccessHandler implements AuthenticationSuccessHandler { | ||
|
||
protected UserRepository userRepository; | ||
|
||
@Autowired | ||
public SuccessHandler(UserRepository userRepository) { | ||
this.userRepository = userRepository; | ||
} | ||
|
||
@Override | ||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { | ||
if (!userRepository.existsById(authentication.getName())) { | ||
// enter this case especially for people authenticated with ldap | ||
userRepository.save(new User(authentication.getName(), null)); | ||
} | ||
redirect(request, response); | ||
} | ||
|
||
protected void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException { | ||
var savedRequest = (DefaultSavedRequest) request.getSession().getAttribute("SPRING_SECURITY_SAVED_REQUEST"); | ||
if (savedRequest == null) { | ||
// redirect to home page | ||
response.sendRedirect("/"); | ||
} else { | ||
// redirect to asked page | ||
response.sendRedirect(savedRequest.getRequestURI()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
src/main/java/io/codeka/gaia/config/security/ldap/LdapSecurityConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package io.codeka.gaia.config.security.ldap; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.annotation.Order; | ||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | ||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||
|
||
@Configuration | ||
@ConditionalOnProperty(prefix = "gaia", name = "ldap.enabled", havingValue = "true") | ||
@Order(60) | ||
public class LdapSecurityConfig extends WebSecurityConfigurerAdapter { | ||
|
||
@Value("${gaia.ldap.userDnPatterns}") | ||
private String userDnPatterns; | ||
|
||
@Value("${gaia.ldap.url}") | ||
private String url; | ||
|
||
@Override | ||
public void configure(AuthenticationManagerBuilder auth) throws Exception { | ||
auth | ||
.ldapAuthentication() | ||
.userDnPatterns(userDnPatterns) | ||
.contextSource() | ||
.url(url); | ||
} | ||
} |
23 changes: 14 additions & 9 deletions
23
...odeka/gaia/config/SecurityConfigTest.java → ...aia/config/security/SecurityConfigIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,36 @@ | ||
package io.codeka.gaia.config; | ||
package io.codeka.gaia.config.security; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.test.annotation.DirtiesContext; | ||
import org.springframework.test.context.TestPropertySource; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
|
||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.verify; | ||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; | ||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; | ||
|
||
@SpringBootTest(classes = {EmptyController.class, SecurityConfig.class}) | ||
@SpringBootTest(classes = SecurityConfig.class) | ||
@DirtiesContext | ||
@AutoConfigureMockMvc | ||
@TestPropertySource(properties = "gaia.admin-password=admin456") | ||
class SecurityConfigTest { | ||
class SecurityConfigIT { | ||
|
||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@MockBean | ||
SuccessHandler successHandler; | ||
|
||
@Test | ||
void adminUserPassword_shouldBeConfigurable() throws Exception { | ||
mockMvc.perform(formLogin().user("admin").password("admin456")) | ||
.andExpect(authenticated().withUsername("admin")); | ||
} | ||
|
||
} | ||
|
||
@Controller | ||
class EmptyController{} | ||
verify(successHandler).onAuthenticationSuccess(any(), any(), any()); | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
src/test/java/io/codeka/gaia/config/security/SuccessHandlerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package io.codeka.gaia.config.security; | ||
|
||
import io.codeka.gaia.teams.User; | ||
import io.codeka.gaia.teams.repository.UserRepository; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.web.savedrequest.DefaultSavedRequest; | ||
|
||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import javax.servlet.http.HttpSession; | ||
import java.io.IOException; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.Mockito.*; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
class SuccessHandlerTest { | ||
|
||
@Mock | ||
UserRepository userRepository; | ||
|
||
@Mock | ||
HttpServletRequest request; | ||
|
||
@Mock | ||
HttpServletResponse response; | ||
|
||
@Mock | ||
Authentication authentication; | ||
|
||
@Mock | ||
HttpSession httpSession; | ||
|
||
@InjectMocks | ||
SuccessHandler successHandler; | ||
|
||
@BeforeEach | ||
void setup() { | ||
when(authentication.getName()).thenReturn("spencer"); | ||
when(request.getSession()).thenReturn(httpSession); | ||
} | ||
|
||
@Test | ||
void onAuthenticationSuccess_shouldCreateUser_whenNotExists() throws IOException { | ||
// when | ||
when(userRepository.existsById(anyString())).thenReturn(false); | ||
successHandler.onAuthenticationSuccess(request, response, authentication); | ||
|
||
// then | ||
var captor = ArgumentCaptor.forClass(User.class); | ||
verify(userRepository).save(captor.capture()); | ||
assertThat(captor.getValue()).isNotNull() | ||
.hasFieldOrPropertyWithValue("username", "spencer") | ||
.hasFieldOrPropertyWithValue("team", null); | ||
} | ||
|
||
@Test | ||
void onAuthenticationSuccess_shouldNotCreateUser_whenExists() throws IOException { | ||
// when | ||
when(userRepository.existsById(anyString())).thenReturn(true); | ||
successHandler.onAuthenticationSuccess(request, response, authentication); | ||
|
||
// then | ||
verify(userRepository, never()).save(any(User.class)); | ||
} | ||
|
||
@Test | ||
void onAuthenticationSuccess_shouldRedirectToHomePage() throws IOException { | ||
// when | ||
when(userRepository.existsById(anyString())).thenReturn(false); | ||
successHandler.onAuthenticationSuccess(request, response, authentication); | ||
|
||
// then | ||
verify(response).sendRedirect("/"); | ||
} | ||
|
||
@Test | ||
void onAuthenticationSuccess_shouldRedirectToAskedPage_whenSpecified() throws IOException { | ||
// given | ||
var savedRequest = mock(DefaultSavedRequest.class); | ||
|
||
// when | ||
when(userRepository.existsById(anyString())).thenReturn(false); | ||
when(httpSession.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).thenReturn(savedRequest); | ||
when(savedRequest.getRequestURI()).thenReturn("/test_url"); | ||
successHandler.onAuthenticationSuccess(request, response, authentication); | ||
|
||
// then | ||
verify(response).sendRedirect("/test_url"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/test/java/io/codeka/gaia/config/security/ldap/LdapSecurityConfigIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package io.codeka.gaia.config.security.ldap; | ||
|
||
import io.codeka.gaia.test.MongoContainer; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.test.annotation.DirtiesContext; | ||
import org.testcontainers.junit.jupiter.Container; | ||
import org.testcontainers.junit.jupiter.Testcontainers; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
import static org.junit.jupiter.api.Assertions.assertNull; | ||
|
||
@DirtiesContext | ||
@Testcontainers | ||
class LdapSecurityConfigIT { | ||
|
||
@Container | ||
private static MongoContainer mongoContainer = new MongoContainer(); | ||
|
||
@Nested | ||
@SpringBootTest(properties = "gaia.ldap.enabled=false") | ||
class LdapSecurityConfigNotLoadedTest { | ||
@Test | ||
void ldapSecurityConfig_shouldNotBeInstantiated( | ||
@Autowired(required = false) LdapSecurityConfig ldapSecurityConfig) { | ||
assertNull(ldapSecurityConfig); | ||
} | ||
} | ||
|
||
@Nested | ||
@SpringBootTest(properties = { | ||
"gaia.ldap.enabled=true", | ||
"gaia.ldap.userDnPatterns=test_dn", | ||
"gaia.ldap.url=ldap://test_url", | ||
}) | ||
class LdapSecurityConfigLoadedTest { | ||
@Test | ||
void ldapSecurityConfig_shouldBeInstantiated( | ||
@Autowired(required = false) LdapSecurityConfig ldapSecurityConfig) { | ||
assertNotNull(ldapSecurityConfig); | ||
} | ||
} | ||
} |