Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Nov 13, 2018
1 parent d74edf6 commit 3d0ab26
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package edu.internet2.tier.shibboleth.admin.ui;

import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.model.AdminRole;
import edu.internet2.tier.shibboleth.admin.ui.security.model.AdminUser;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.AdminRoleRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.AdminUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
Expand All @@ -18,10 +22,15 @@
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@SpringBootApplication
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "edu.internet2.tier.shibboleth.admin.ui.configuration.auto.*"))
@EntityScan(basePackages = "edu.internet2.tier.shibboleth.admin.ui.domain")
@EntityScan(basePackages = {"edu.internet2.tier.shibboleth.admin.ui.domain", "edu.internet2.tier.shibboleth.admin.ui.security.model"})
@EnableJpaAuditing
@EnableScheduling
@EnableWebSecurity
Expand Down Expand Up @@ -50,4 +59,32 @@ void showMetadataResolversResourceIds(ApplicationStartedEvent e) {
}
}

@Component
@Profile("dev")
public static class SampleAdminUsersCreator {

@Autowired
AdminUserRepository adminUserRepository;

@Autowired
AdminRoleRepository adminRoleRepository;

@EventListener
void createSampleAdminUsers(ApplicationStartedEvent e) {
//TODO: this is wip. Having a hard time with many-to-many saving with Hibernate's detatched entity exceptions, etc.
if(adminUserRepository.count() == 0L) {
AdminRole role = new AdminRole();
role.setName("ADMIN");

Arrays.asList("1", "2").forEach(it -> {
AdminUser user = new AdminUser();
user.setUsername(String.format("admin%s", it));
user.setPassword(String.format("{noop}adminpass%s", it));
//role.getAdmins().add(user);
//user.getRoles().add(role);
adminUserRepository.save(user);
});
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration.auto;

import edu.internet2.tier.shibboleth.admin.ui.security.DefaultAuditorAware;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.AdminUserRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.springsecurity.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -13,6 +16,8 @@
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
Expand All @@ -34,6 +39,9 @@ public class WebSecurityConfig {
@Value("${shibui.default-password:}")
private String defaultPassword;

@Autowired
private AdminUserRepository adminUserRepository;

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
Expand Down Expand Up @@ -62,12 +70,15 @@ protected void configure(HttpSecurity http) throws Exception {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO: more configurable authentication
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
if (defaultPassword != null && !"".equals(defaultPassword)) {
auth
.inMemoryAuthentication()
.withUser("user").password(defaultPassword).roles("USER");
.withUser("user")
.password(passwordEncoder.encode(defaultPassword))
.roles("USER");
} else {
super.configure(auth);
auth.userDetailsService(adminUserService(adminUserRepository)).passwordEncoder(passwordEncoder);
}
}

Expand All @@ -85,6 +96,12 @@ public AuditorAware<String> defaultAuditorAware() {
return new DefaultAuditorAware();
}

@Bean
@Profile("!no-auth")
public AdminUserService adminUserService(AdminUserRepository adminUserRepository) {
return new AdminUserService(adminUserRepository);
}

@Bean
@Profile("no-auth")
public WebSecurityConfigurerAdapter noAuthUsedForEaseDevelopment() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package edu.internet2.tier.shibboleth.admin.ui.security.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -11,7 +13,10 @@
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import java.util.HashSet;
import java.util.Set;

/**
Expand All @@ -30,8 +35,7 @@ public class AdminRole extends AbstractAuditable {
@Column(unique = true)
private String name;

@ManyToMany(cascade = CascadeType.ALL, mappedBy = "roles", fetch = FetchType.EAGER)
private Set<AdminUser> admins;

@ManyToMany(cascade = CascadeType.PERSIST, mappedBy = "roles", fetch = FetchType.EAGER)
private Set<AdminUser> admins = new HashSet<>();

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
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;
import java.util.HashSet;
import java.util.Set;

/**
Expand Down Expand Up @@ -37,7 +39,7 @@ public class AdminUser extends AbstractAuditable {
private String lastName;

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@ManyToMany(cascade = CascadeType.ALL)
@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "adminuser_role", joinColumns = @JoinColumn(name = "admin_user_id"), inverseJoinColumns = @JoinColumn(name = "admin_role_id"))
private Set<AdminRole> roles;
private Set<AdminRole> roles = new HashSet<>();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.security.repository;

import edu.internet2.tier.shibboleth.admin.ui.security.model.AdminRole;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

Expand All @@ -9,7 +10,7 @@
*
* @author Dmitriy Kopylenko
*/
public interface AdminRoleRepository {
public interface AdminRoleRepository extends JpaRepository<AdminRole, Long> {

Optional<AdminRole> findByName(final String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import edu.internet2.tier.shibboleth.admin.ui.security.model.AdminUser;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

/**
* Spring Data repository to manage entities of type {@link AdminUser}.
*
* @author Dmitriy Kopylenko
*/
public interface AdminUserRepository extends JpaRepository<AdminUser, Long> {

AdminUser findByUsername(String username);
Optional<AdminUser> findByUsername(String username);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.Set;
import static java.util.stream.Collectors.toSet;

/**
* Spring Security {@link UserDetailsService} implementation for local administration of admin users ins the system.
Expand All @@ -27,14 +28,20 @@ public class AdminUserService implements UserDetailsService {
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
AdminUser user = adminUserRepository.findByUsername(username);
AdminUser user = adminUserRepository
.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException(String.format("User [%s] is not found", username)));

Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (AdminRole role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
Set<GrantedAuthority> grantedAuthorities = user.getRoles().stream()
.map(AdminRole::getName)
.map(SimpleGrantedAuthority::new)
.collect(toSet());

if (grantedAuthorities.isEmpty()) {
throw new UsernameNotFoundException(String.format("No roles are defined for user [%s]", username));
}

return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
}
}

3 changes: 2 additions & 1 deletion backend/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Logging Configuration
#logging.config=classpath:log4j2.xml

logging.level.org.springframework.security=DEBUG
logging.level.org.springframework=INFO
logging.level.edu.internet2.tier.shibboleth.admin.ui=INFO

Expand Down Expand Up @@ -48,7 +49,7 @@ shibui.logout-url=/dashboard

# spring.profiles.active=default

#shibui.default-password=
#shibui.default-password=pass

shibui.metadata-sources-ui-schema-location=classpath:metadata-sources-ui-schema.json
shibui.entity-attributes-filters-ui-schema-location=classpath:entity-attributes-filters-ui-schema.json
Expand Down

0 comments on commit 3d0ab26

Please sign in to comment.