From f475fb8b5f4c3629c2a66382e4205812dc7c4c54 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Fri, 11 Jan 2019 14:26:16 -0700 Subject: [PATCH] [SHIBUI-1030] Added query to get users by role name. Added simple email test. Updated gradle build to spin up docker compose before the test task and shut down after. In theory. --- backend/build.gradle | 5 +++ .../ui/configuration/EmailConfiguration.java | 13 +++++-- .../controller/ConfigurationController.java | 17 ++++++++ .../security/repository/UserRepository.java | 2 + .../admin/ui/service/EmailServiceImpl.java | 18 +++++++-- .../ui/configuration/TestConfiguration.groovy | 11 ++++++ .../ui/service/EmailServiceImplTests.groovy | 39 +++++++++++++++++++ 7 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImplTests.groovy diff --git a/backend/build.gradle b/backend/build.gradle index d5dd5f394..ec6171fed 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -325,4 +325,9 @@ dockerCompose { useComposeFiles = ['./src/main/docker-files/docker-compose.yml'] captureContainersOutput = true waitForTcpPorts = false +} + +task test(overwrite: true) { + dependsOn 'composeUp' + finalizedBy 'composeDown' } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/EmailConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/EmailConfiguration.java index e84551685..8377acc7b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/EmailConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/EmailConfiguration.java @@ -1,11 +1,11 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration; +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; import edu.internet2.tier.shibboleth.admin.ui.service.EmailServiceImpl; import lombok.Setter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; @@ -43,10 +43,10 @@ public class EmailConfiguration { private String systemEmailAddress = "doNotReply@shibui.org"; @Autowired - private ApplicationContext applicationContext; + private JavaMailSender javaMailSender; @Autowired - private JavaMailSender javaMailSender; + private UserRepository userRepository; @Bean public ResourceBundleMessageSource emailMessageSource() { @@ -97,6 +97,11 @@ private ITemplateResolver htmlTemplateResolver() { @Bean public EmailService emailService() { - return new EmailServiceImpl(javaMailSender, emailMessageSource(), textEmailTemplateEngine(), htmlEmailTemplateEngine(), systemEmailAddress); + return new EmailServiceImpl(javaMailSender, + emailMessageSource(), + textEmailTemplateEngine(), + htmlEmailTemplateEngine(), + systemEmailAddress, + userRepository); } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java index 3f85175e1..313bee981 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java @@ -3,12 +3,15 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration; import edu.internet2.tier.shibboleth.admin.ui.security.model.Role; import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository; +import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import javax.mail.MessagingException; import java.util.stream.Collectors; /** @@ -24,6 +27,14 @@ public class ConfigurationController { @Autowired RoleRepository roleRepository; + @Autowired + EmailService emailService; + + @ExceptionHandler(MessagingException.class) + public ResponseEntity handleMessagingExcepgtion() { + return ResponseEntity.badRequest().body(new ErrorResponse("12345", "Something exploded.")); + } + @GetMapping(value = "/customAttributes") public ResponseEntity getCustomAttributes() { return ResponseEntity.ok(customPropertiesConfiguration.getAttributes()); @@ -33,4 +44,10 @@ public ResponseEntity getCustomAttributes() { public ResponseEntity getSupportedRoles() { return ResponseEntity.ok(roleRepository.findAll().stream().map(Role::getName).collect(Collectors.toList())); } + + @GetMapping(value = "/foo") + public ResponseEntity getFoo() throws MessagingException { + emailService.sendNewUserMail("foobar"); + return ResponseEntity.ok().build(); + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserRepository.java index f19ceb1b7..380e8501a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserRepository.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserRepository.java @@ -4,6 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; +import java.util.Set; /** * Spring Data repository to manage entities of type {@link User}. @@ -13,4 +14,5 @@ public interface UserRepository extends JpaRepository { Optional findByUsername(String username); + Set findByRoles_Name(String roleName); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImpl.java index 90fa8b33b..601ad48a0 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImpl.java @@ -1,5 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.service; +import edu.internet2.tier.shibboleth.admin.ui.security.model.User; +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.support.ResourceBundleMessageSource; @@ -10,7 +12,9 @@ import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; /** * @author Bill Smith (wsmith@unicon.net) @@ -23,17 +27,20 @@ public class EmailServiceImpl implements EmailService { private ResourceBundleMessageSource emailMessageSource; private TemplateEngine textEmailTemplateEngine; private TemplateEngine htmlEmailTemplateEngine; + private UserRepository userRepository; public EmailServiceImpl(JavaMailSender emailSender, ResourceBundleMessageSource emailMessageSource, TemplateEngine textEmailTemplateEngine, TemplateEngine htmlEmailTemplateEngine, - String systemEmailAddress) { + String systemEmailAddress, + UserRepository userRepository) { this.emailSender = emailSender; this.emailMessageSource = emailMessageSource; this.textEmailTemplateEngine = textEmailTemplateEngine; this.htmlEmailTemplateEngine = htmlEmailTemplateEngine; this.systemEmailAddress = systemEmailAddress; + this.userRepository = userRepository; } public void sendMail(String emailTemplate, String fromAddress, String[] recipients, String subject, Locale locale) throws MessagingException { @@ -50,7 +57,6 @@ public void sendMail(String emailTemplate, String fromAddress, String[] recipien String htmlContent = htmlEmailTemplateEngine.process(emailTemplate, context); message.setText(textContent, htmlContent); - // TODO: Uncomment when we're ready to actually send emails emailSender.send(mimeMessage); } @@ -60,6 +66,12 @@ public void sendNewUserMail(String newUsername) throws MessagingException { } private String[] getSystemAdmins() { - return new String[]{"admin1@shibui.org", "admin2@shibui.org"}; + Set systemAdmins = userRepository.findByRoles_Name("ROLE_ADMIN"); + if (systemAdmins == null || systemAdmins.size() == 0) { + //TODO: Should this be an exception? + logger.warn("No users with ROLE_ADMIN were found! Check your configuration!"); + systemAdmins = new HashSet<>(); + } + return systemAdmins.stream().map(User::getEmailAddress).distinct().toArray(String[]::new); } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy index 1796e3b70..a01645a09 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy @@ -20,6 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.io.ClassPathResource +import org.springframework.mail.javamail.JavaMailSender +import org.springframework.mail.javamail.JavaMailSenderImpl @Configuration class TestConfiguration { @@ -35,6 +37,15 @@ class TestConfiguration { this.metadataResolverRepository = metadataResolverRepository } + @Bean + JavaMailSender javaMailSender() { + return new JavaMailSenderImpl().with { + it.host = 'localhost' + it.port = 1025 + it + } + } + @Bean MetadataResolver metadataResolver() { ChainingMetadataResolver metadataResolver = new OpenSamlChainingMetadataResolver() diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImplTests.groovy new file mode 100644 index 000000000..f40c9fa3c --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/EmailServiceImplTests.groovy @@ -0,0 +1,39 @@ +package edu.internet2.tier.shibboleth.admin.ui.service + +import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.DevConfig +import edu.internet2.tier.shibboleth.admin.ui.configuration.EmailConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.data.jpa.repository.config.EnableJpaRepositories +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +@SpringBootTest +@DataJpaTest +@ContextConfiguration(classes=[CoreShibUiConfiguration, EmailConfiguration, TestConfiguration, InternationalizationConfiguration, SearchConfiguration, DevConfig]) +@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) +@EntityScan("edu.internet2.tier.shibboleth.admin.ui") +@ActiveProfiles(["no-auth", "dev"]) +class EmailServiceImplTests extends Specification { + + @Autowired + EmailService emailService + + def "emailService can successfully send an email"() { + when: + emailService.sendNewUserMail("foobar") + + then: + noExceptionThrown() + } +}