diff --git a/backend/build.gradle b/backend/build.gradle index 63170b7fa..2b67f5d00 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -48,6 +48,10 @@ configurations { processResources.dependsOn(':ui:npm_run_buildProd') +jar { + enabled = true +} + //Integration of the frontend and backend into the build to have all of the UI resources available in the app's executable war bootWar.dependsOn(':ui:npm_run_buildProd') bootWar.baseName = 'shibui' diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java index 18bb1b9bc..0d9f6b723 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java @@ -1,8 +1,17 @@ package net.unicon.shibui.pac4j; +import com.fasterxml.jackson.databind.ObjectMapper; +import edu.internet2.tier.shibboleth.admin.ui.controller.ErrorResponse; +import edu.internet2.tier.shibboleth.admin.ui.security.model.Role; +import edu.internet2.tier.shibboleth.admin.ui.security.model.User; +import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.commons.lang.RandomStringUtils; +import org.apache.http.entity.ContentType; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCrypt; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -10,40 +19,68 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.security.Principal; +import java.util.Optional; /** * @author Bill Smith (wsmith@unicon.net) */ public class AddNewUserFilter implements Filter { - private static final Logger logger = LoggerFactory.getLogger(AddNewUserFilter.class); + private static final String ROLE_NONE = "ROLE_NONE"; private UserRepository userRepository; + private RoleRepository roleRepository; - public AddNewUserFilter(UserRepository userRepository) { + public AddNewUserFilter(UserRepository userRepository, RoleRepository roleRepository) { this.userRepository = userRepository; + this.roleRepository = roleRepository; } @Override public void init(FilterConfig filterConfig) throws ServletException { - logger.info("WOO! INIT!"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - logger.info("WOO! Doing filter..."); - Principal principal = ((HttpServletRequest) request).getUserPrincipal(); - String username = principal.getName(); - logger.info("WOO! Principal: " + username); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null) { + String username = authentication.getName(); + if (username != null) { + Optional persistedUser = userRepository.findByUsername(username); + User user; + if (!persistedUser.isPresent()) { + user = new User(); + user.setUsername(username); + user.setPassword(BCrypt.hashpw(RandomStringUtils.randomAlphanumeric(20), BCrypt.gensalt())); + Role noRole = roleRepository.findByName(ROLE_NONE).orElse(new Role(ROLE_NONE)); + user.getRoles().add(noRole); + userRepository.save(user); + //TODO: Add call to email service here + } else { + user = persistedUser.get(); + } + if (user.getRole().equals(ROLE_NONE)) { + response.setContentType(ContentType.APPLICATION_JSON.getMimeType()); + ((HttpServletResponse) response).setStatus(HttpStatus.FORBIDDEN.value()); + response.getOutputStream().write(getJsonResponseBytes( + new ErrorResponse(String.valueOf(HttpStatus.FORBIDDEN.value()), + "Your account is not yet authorized to access ShibUI."))); + return; + } // else, user is in the system already, carry on + } + } chain.doFilter(request, response); } @Override public void destroy() { - logger.info("WOO! DESTROY!"); + } + + private byte[] getJsonResponseBytes(ErrorResponse eErrorResponse) throws IOException { + String errorResponseJson = new ObjectMapper().writeValueAsString(eErrorResponse); + return errorResponseJson.getBytes(); } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 186b053d1..02106124e 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -1,5 +1,6 @@ package net.unicon.shibui.pac4j; +import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import org.pac4j.core.config.Config; import org.pac4j.springframework.security.web.CallbackFilter; @@ -18,8 +19,8 @@ @AutoConfigureOrder(-1) public class WebSecurity { @Bean("webSecurityConfig") - public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository) { - return new Pac4jWebSecurityConfigurerAdapter(config, userRepository); + public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository) { + return new Pac4jWebSecurityConfigurerAdapter(config, userRepository, roleRepository); } @Configuration @@ -35,10 +36,12 @@ protected void configure(HttpSecurity http) throws Exception { public static class Pac4jWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { private final Config config; private UserRepository userRepository; + private RoleRepository roleRepository; - public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository userRepository) { + public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository) { this.config = config; this.userRepository = userRepository; + this.roleRepository = roleRepository; } @Override @@ -52,7 +55,7 @@ protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(securityFilter, BasicAuthenticationFilter.class); - http.addFilterBefore(new AddNewUserFilter(userRepository), BasicAuthenticationFilter.class); + http.addFilterAfter(new AddNewUserFilter(userRepository, roleRepository), BasicAuthenticationFilter.class); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);