Implement support for user consent #4

Manually merged
ansv7779 merged 13 commits from user-consent into main 2025-04-25 10:22:44 +02:00
6 changed files with 9 additions and 26 deletions
Showing only changes of commit c48eee489b - Show all commits

View File

@ -175,14 +175,11 @@ public class AuthorizationServer extends SpringBootServletInitializer {
*/ */
@Bean @Bean
@Order(2) @Order(2)
public SecurityFilterChain defaultSecurityFilterChain( public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
HttpSecurity http,
Config config)
throws Exception throws Exception
{ {
http.authorizeHttpRequests(authorize -> authorize http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/admin/**").hasAuthority(Entitlement.asAuthority(config.adminEntitlement()))
.anyRequest().authenticated()); .anyRequest().authenticated());
http.exceptionHandling(exceptions -> exceptions http.exceptionHandling(exceptions -> exceptions

View File

@ -3,7 +3,7 @@ package se.su.dsv.oauth2;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("se.su.dsv.oauth2") @ConfigurationProperties("se.su.dsv.oauth2")
public record Config(String adminEntitlement, String developerEntitlement, RSAKeyPair rsaKeyPair) { public record Config(String developerEntitlement, RSAKeyPair rsaKeyPair) {
record RSAKeyPair(String kid, String modulus, String privateExponent, String publicExponent) { record RSAKeyPair(String kid, String modulus, String privateExponent, String publicExponent) {
} }
} }

View File

@ -13,7 +13,7 @@ import se.su.dsv.oauth2.Config;
public class DevConfiguration { public class DevConfiguration {
@Bean @Bean
public FilterRegistrationBean<HttpFilter> fakeSSO(SecurityProperties securityProperties, Config config) { public FilterRegistrationBean<HttpFilter> fakeSSO(SecurityProperties securityProperties, Config config) {
var filter = new FilterRegistrationBean<HttpFilter>(new FakeSSOFilter(config.adminEntitlement(), config.developerEntitlement())); var filter = new FilterRegistrationBean<HttpFilter>(new FakeSSOFilter(config.developerEntitlement()));
filter.setOrder(securityProperties.getFilter().getOrder() - 1); filter.setOrder(securityProperties.getFilter().getOrder() - 1);
return filter; return filter;
} }

View File

@ -1,4 +1,3 @@
se.su.dsv.oauth2.admin-entitlement=oauth2-admin
se.su.dsv.oauth2.developer-entitlement=oauth2-developer se.su.dsv.oauth2.developer-entitlement=oauth2-developer
gg.jte.templateLocation=src/main/resources/templates gg.jte.templateLocation=src/main/resources/templates
gg.jte.developmentMode=true gg.jte.developmentMode=true

View File

@ -9,22 +9,15 @@ import org.springframework.test.web.servlet.MockMvc;
import org.testcontainers.containers.MariaDBContainer; import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.junit.jupiter.Testcontainers;
import se.su.dsv.oauth2.shibboleth.Entitlement;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest( @SpringBootTest
properties = {
"se.su.dsv.oauth2.admin-entitlement=" + AdminControllerTest.ADMIN_ENTITLEMENT
}
)
@Testcontainers @Testcontainers
@AutoConfigureMockMvc @AutoConfigureMockMvc
class AdminControllerTest { class AdminControllerTest {
static final String ADMIN_ENTITLEMENT = "ADMIN";
@Container @Container
@ServiceConnection @ServiceConnection
static MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:10.11"); static MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:10.11");
@ -39,9 +32,9 @@ class AdminControllerTest {
} }
@Test @Test
void is_accessible_with_admin_authority() throws Exception { void is_accessible_when_logged_in() throws Exception {
mockMvc.perform(get("/admin") mockMvc.perform(get("/admin")
.with(user("admin").authorities(new Entitlement(ADMIN_ENTITLEMENT)))) .with(user("admin")))
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
} }

View File

@ -26,14 +26,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static se.su.dsv.oauth2.ShibbolethRequestProcessor.remoteUser; import static se.su.dsv.oauth2.ShibbolethRequestProcessor.remoteUser;
@SpringBootTest(properties = { @SpringBootTest(properties = {
"se.su.dsv.oauth2.admin-entitlement=" + ClientAdminControllerTest.ADMIN_ENTITLEMENT,
"se.su.dsv.oauth2.developer-entitlement=" + ClientAdminControllerTest.DEVELOPER_ENTITLEMENT "se.su.dsv.oauth2.developer-entitlement=" + ClientAdminControllerTest.DEVELOPER_ENTITLEMENT
}) })
@AutoConfigureMockMvc @AutoConfigureMockMvc
@Transactional @Transactional
@Rollback @Rollback
public class ClientAdminControllerTest { public class ClientAdminControllerTest {
public static final String ADMIN_ENTITLEMENT = "admin";
public static final String DEVELOPER_ENTITLEMENT = "developer"; public static final String DEVELOPER_ENTITLEMENT = "developer";
@ServiceConnection @ServiceConnection
@ -54,8 +52,7 @@ public class ClientAdminControllerTest {
MvcResult creationResult = mockMvc.perform(post("/admin/client/new") MvcResult creationResult = mockMvc.perform(post("/admin/client/new")
.with(csrf()) .with(csrf())
.with(remoteUser("admin") .with(remoteUser("admin"))
.entitlement(ADMIN_ENTITLEMENT))
.formField("name", name) .formField("name", name)
.formField("contact", contactEmail) .formField("contact", contactEmail)
.formField("redirectUri", redirectUri) .formField("redirectUri", redirectUri)
@ -68,8 +65,7 @@ public class ClientAdminControllerTest {
assertNotNull(viewClientUrl); assertNotNull(viewClientUrl);
mockMvc.perform(get(viewClientUrl) mockMvc.perform(get(viewClientUrl)
.with(remoteUser("admin") .with(remoteUser("admin")))
.entitlement(ADMIN_ENTITLEMENT)))
.andExpect(content().string(containsString(name))) .andExpect(content().string(containsString(name)))
.andExpect(content().string(containsString(contactEmail))) .andExpect(content().string(containsString(contactEmail)))
.andExpect(content().string(containsString(redirectUri))) .andExpect(content().string(containsString(redirectUri)))
@ -85,8 +81,7 @@ public class ClientAdminControllerTest {
MvcResult creationResult = mockMvc.perform(post("/admin/client/new") MvcResult creationResult = mockMvc.perform(post("/admin/client/new")
.with(csrf()) .with(csrf())
.with(remoteUser(principal) .with(remoteUser(principal))
.entitlement(ADMIN_ENTITLEMENT))
.formField("name", name) .formField("name", name)
.formField("contact", contactEmail) .formField("contact", contactEmail)
.formField("redirectUri", redirectUri)) .formField("redirectUri", redirectUri))
@ -114,7 +109,6 @@ public class ClientAdminControllerTest {
MvcResult creationResult = mockMvc.perform(post("/admin/client/new") MvcResult creationResult = mockMvc.perform(post("/admin/client/new")
.with(csrf()) .with(csrf())
.with(remoteUser(principal) .with(remoteUser(principal)
.entitlement(ADMIN_ENTITLEMENT)
.entitlement(DEVELOPER_ENTITLEMENT)) .entitlement(DEVELOPER_ENTITLEMENT))
.formField("name", name) .formField("name", name)
.formField("contact", contactEmail) .formField("contact", contactEmail)