Skip to content

Commit

Permalink
fixed merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Jan 24, 2019
2 parents 42d3e0d + aaaf521 commit 00c231c
Show file tree
Hide file tree
Showing 44 changed files with 1,504 additions and 426 deletions.
25 changes: 23 additions & 2 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
id 'io.franzbecker.gradle-lombok' version '1.13'
id 'com.palantir.docker' version '0.20.1'
id 'com.palantir.docker-run' version '0.20.1'
id 'com.avast.gradle.docker-compose' version '0.8.0'
}

apply plugin: 'io.spring.dependency-management'
Expand Down Expand Up @@ -48,6 +49,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'
Expand Down Expand Up @@ -110,7 +115,7 @@ dependencies {
}

// spring boot auto-config starters
['starter-web', 'starter-data-jpa', 'starter-security', 'starter-actuator', 'devtools', 'starter-webflux'].each {
['starter-web', 'starter-data-jpa', 'starter-security', 'starter-actuator', 'devtools', 'starter-webflux', 'starter-thymeleaf', 'starter-mail'].each {
compile "org.springframework.boot:spring-boot-${it}"
}
// TODO: figure out what this should really be
Expand Down Expand Up @@ -313,4 +318,20 @@ task runChecker << {
sleep 5000
}
}
}
}

/*
* Docker Compose (gradle-docker-compose-plugin) settings.
* Used to start and stop docker containers before running tests.
*/
apply plugin: 'docker-compose'
dockerCompose {
useComposeFiles = ['./src/test/docker-files/docker-compose.yml']
captureContainersOutput = true
waitForTcpPorts = false
}

test {
dependsOn 'composeUp'
finalizedBy 'composeDown'
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ReloadableMetadat
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
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 edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions
import org.springframework.context.annotation.Bean
Expand All @@ -24,39 +25,65 @@ import javax.annotation.PostConstruct
@Profile('dev')
class DevConfig {
private final UserRepository adminUserRepository
private final RoleRepository roleRepository

private final MetadataResolverRepository metadataResolverRepository

DevConfig(UserRepository adminUserRepository, MetadataResolverRepository metadataResolverRepository) {
DevConfig(UserRepository adminUserRepository, MetadataResolverRepository metadataResolverRepository, RoleRepository roleRepository) {
this.adminUserRepository = adminUserRepository
this.metadataResolverRepository = metadataResolverRepository
this.roleRepository = roleRepository
}

@Transactional
@PostConstruct
void createDevUsers() {
if (roleRepository.count() == 0) {
def roles = [new Role().with {
name = 'ROLE_ADMIN'
it
}, new Role().with {
name = 'ROLE_USER'
it
}, new Role().with {
name = 'ROLE_NONE'
it
}]
roles.each {
roleRepository.save(it)
}
}
roleRepository.flush()
if (adminUserRepository.count() == 0) {
def users = [new User().with {
username = 'admin'
password = '{noop}adminpass'
firstName = 'Joe'
lastName = 'Doe'
emailAddress = 'joe@institution.edu'
roles.add(new Role(name: 'ROLE_ADMIN'))
roles.add(roleRepository.findByName('ROLE_ADMIN').get())
it
}, new User().with {
username = 'nonadmin'
password = '{noop}nonadminpass'
firstName = 'Peter'
lastName = 'Vandelay'
emailAddress = 'peter@institution.edu'
roles.add(new Role(name: 'ROLE_USER'))
roles.add(roleRepository.findByName('ROLE_USER').get())
it
}, new User().with {
username = 'anonymousUser'
password = '{noop}anotheradmin'
firstName = 'Anon'
lastName = 'Ymous'
emailAddress = 'anonymous@institution.edu'
roles.add(roleRepository.findByName('ROLE_ADMIN').get())
it
}]
users.each {
adminUserRepository.save(it)
}

adminUserRepository.flush()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ class UserBootstrap {
if (shibUIConfiguration.userBootstrapResource) {
log.info("configuring users from ${shibUIConfiguration.userBootstrapResource.URI}")
new CSVReader(new InputStreamReader(shibUIConfiguration.userBootstrapResource.inputStream)).each { it ->
def (username, password, firstName, lastName, roleName) = it
def (username, password, firstName, lastName, roleName, email) = it
def role = roleRepository.findByName(roleName).orElse(new Role(name: roleName))
roleRepository.saveAndFlush(role)
def user = userRepository.findByUsername(username).orElse(new User(username: username)).with {
it.password = password
it.firstName = firstName
it.lastName = lastName
it.roles.add(role)
it.emailAddress = email
it
}
userRepository.saveAndFlush(user)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
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.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;

import java.util.Collections;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
@Configuration
@ConfigurationProperties("shibui.mail")
public class EmailConfiguration {

private static final String EMAIL_TEMPLATE_ENCODING = "UTF-8";

//Configured via @ConfigurationProperties (using setter method) with 'shibui.mail.text-email-template-path-prefix' property and
// default value set here if that property is not explicitly set in application.properties
@Setter
private String textEmailTemplatePathPrefix = "/mail/text/";

//Configured via @ConfigurationProperties (using setter method) with 'shibui.mail.html-email-template-path-prefix' property and
// default value set here if that property is not explicitly set in application.properties
@Setter
private String htmlEmailTemplatePathPrefix = "/mail/html/";

//Configured via @ConfigurationProperties (using setter method) with 'shibui.mail.system-email-address' property and
// default value set here if that property is not explicitly set in application.properties
@Setter
private String systemEmailAddress = "doNotReply@shibui.org";

@Autowired
private JavaMailSender javaMailSender;

@Autowired
private UserRepository userRepository;

@Bean
public ResourceBundleMessageSource emailMessageSource() {
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("mail/mailMessages");
return messageSource;
}

@Bean
public TemplateEngine textEmailTemplateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(textTemplateResolver());
templateEngine.setTemplateEngineMessageSource(emailMessageSource());
return templateEngine;
}

@Bean
public TemplateEngine htmlEmailTemplateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(htmlTemplateResolver());
templateEngine.setTemplateEngineMessageSource(emailMessageSource());
return templateEngine;
}

private ITemplateResolver textTemplateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setOrder(1);
templateResolver.setResolvablePatterns(Collections.singleton("*"));
templateResolver.setPrefix(textEmailTemplatePathPrefix);
templateResolver.setSuffix(".txt");
templateResolver.setTemplateMode(TemplateMode.TEXT);
templateResolver.setCharacterEncoding(EMAIL_TEMPLATE_ENCODING);
templateResolver.setCacheable(false);
return templateResolver;
}

private ITemplateResolver htmlTemplateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setOrder(1);
templateResolver.setResolvablePatterns(Collections.singleton("*"));
templateResolver.setPrefix(htmlEmailTemplatePathPrefix);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding(EMAIL_TEMPLATE_ENCODING);
templateResolver.setCacheable(false);
return templateResolver;
}

@Bean
public EmailService emailService() {
return new EmailServiceImpl(javaMailSender,
emailMessageSource(),
textEmailTemplateEngine(),
htmlEmailTemplateEngine(),
systemEmailAddress,
userRepository);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ public ResponseEntity<?> getOne(@PathVariable String username) {
return ResponseEntity.ok(findUserOrThrowHttp404(username));
}

@Transactional
@GetMapping("/role/{rolename}")
public ResponseEntity<?> getUsersWithRole(@PathVariable String rolename) {
return ResponseEntity.ok(userRepository.findByRoles_Name(rolename));
}

@Transactional
@DeleteMapping("/{username}")
public ResponseEntity<?> deleteOne(@PathVariable String username) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public Role(String name, int rank) {

//Ignore properties annotation here is to prevent stack overflow recursive error during JSON serialization
@JsonIgnoreProperties("roles")
@ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER)
@ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY)
private Set<User> users = new HashSet<>();

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import lombok.ToString;
import org.apache.commons.lang.StringUtils;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
Expand Down Expand Up @@ -50,7 +50,7 @@ public class User extends AbstractAuditable {
private String role;

@JsonIgnore
@ManyToMany(cascade = CascadeType.PERSIST)
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
Expand All @@ -13,4 +14,5 @@
public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findByUsername(String username);
Set<User> findByRoles_Name(String roleName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import javax.mail.MessagingException;
import java.util.Locale;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
public interface EmailService {
void sendMail(String emailTemplate, String fromAddress, String[] recipients, String subject, Locale locale) throws MessagingException;
void sendNewUserMail(String newUsername) throws MessagingException;
String[] getSystemAdminEmailAddresses();
}
Loading

0 comments on commit 00c231c

Please sign in to comment.