Skip to content

Commit

Permalink
[SHIBUI-975]
Browse files Browse the repository at this point in the history
refactor
  • Loading branch information
jj committed Nov 19, 2018
1 parent cd03dd3 commit 022c4f1
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 94 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration

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.UserRepository
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional

import javax.annotation.PostConstruct

@Component
@Profile('dev')
class DevConfig {
private final UserRepository adminUserRepository

DevConfig(UserRepository adminUserRepository) {
this.adminUserRepository = adminUserRepository
}

@Transactional
@PostConstruct
void createDevAdminUsers() {
if (adminUserRepository.count() == 0) {
def user = new User().with {
username = 'admin'
password = '{noop}adminpass'
roles.add(new Role(name: 'ROLE_ADMIN'))
it
}

adminUserRepository.save(user)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
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.model.AdminRole;
import edu.internet2.tier.shibboleth.admin.ui.security.model.AdminUser;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.AdminUserRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.springsecurity.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -24,10 +22,6 @@
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;

/**
* Web security configuration.
Expand All @@ -46,7 +40,7 @@ public class WebSecurityConfig {
private String defaultPassword;

@Autowired
private AdminUserRepository adminUserRepository;
private UserRepository userRepository;

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
Expand Down Expand Up @@ -80,11 +74,11 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if (defaultPassword != null && !"".equals(defaultPassword)) {
auth
.inMemoryAuthentication()
.withUser("user")
.withUser("root")
.password(defaultPassword)
.roles("USER");
.roles("ADMIN");
}
auth.userDetailsService(adminUserService(adminUserRepository)).passwordEncoder(passwordEncoder);
auth.userDetailsService(adminUserService(userRepository)).passwordEncoder(passwordEncoder);
}

@Override
Expand All @@ -103,8 +97,8 @@ public AuditorAware<String> defaultAuditorAware() {

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

@Bean
Expand All @@ -124,32 +118,5 @@ public void configure(WebSecurity web) throws Exception {
}
};
}

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

@Autowired
AdminUserRepository adminUserRepository;

@Transactional
@PostConstruct
public void createSampleAdminUsers() {
if (adminUserRepository.count() == 0L) {
AdminRole role = new AdminRole();
role.setName("ROLE_ADMIN");
AdminUser user = new AdminUser();
user.setUsername("admin");
user.setPassword("{noop}adminpass");

//The complexity of managing bi-directional many-to-many. TODO: encapsulate this association
//managing logic into domain model itself
role.getAdmins().add(user);
user.getRoles().add(role);

adminUserRepository.save(user);
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(callSuper = true, exclude = "admins")
@ToString(exclude = "admins")
public class AdminRole extends AbstractAuditable {
@EqualsAndHashCode(callSuper = true, exclude = "users")
@ToString(exclude = "users")
public class Role extends AbstractAuditable {

@Column(unique = true)
private String name;

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
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 All @@ -25,7 +24,7 @@
@Setter
@EqualsAndHashCode(callSuper = true, exclude = "roles")
@ToString(exclude = "roles")
public class AdminUser extends AbstractAuditable {
public class User extends AbstractAuditable {

@Column(nullable = false, unique = true)
private String username;
Expand All @@ -40,6 +39,6 @@ public class AdminUser extends AbstractAuditable {

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "adminuser_role", joinColumns = @JoinColumn(name = "admin_user_id"), inverseJoinColumns = @JoinColumn(name = "admin_role_id"))
private Set<AdminRole> roles = new HashSet<>();
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package edu.internet2.tier.shibboleth.admin.ui.security.repository;

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

import java.util.Optional;

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

Optional<Role> findByName(final String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package edu.internet2.tier.shibboleth.admin.ui.security.repository;

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

import java.util.Optional;

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

Optional<User> findByUsername(String username);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package edu.internet2.tier.shibboleth.admin.ui.security.springsecurity;

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.AdminUserRepository;
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.UserRepository;
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;
Expand All @@ -23,17 +22,17 @@
@RequiredArgsConstructor
public class AdminUserService implements UserDetailsService {

private final AdminUserRepository adminUserRepository;
private final UserRepository userRepository;

@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
AdminUser user = adminUserRepository
User user = userRepository
.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException(String.format("User [%s] is not found", username)));

Set<GrantedAuthority> grantedAuthorities = user.getRoles().stream()
.map(AdminRole::getName)
.map(Role::getName)
.map(SimpleGrantedAuthority::new)
.collect(toSet());

Expand All @@ -42,7 +41,7 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
throw new UsernameNotFoundException(String.format("No roles are defined for user [%s]", username));
}

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

Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package edu.internet2.tier.shibboleth.admin.ui.security.springsecurity

import edu.internet2.tier.shibboleth.admin.ui.security.repository.AdminRoleRepository
import edu.internet2.tier.shibboleth.admin.ui.security.repository.AdminUserRepository
import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository
import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.Profile
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ActiveProfiles
import spock.lang.Specification

Expand All @@ -23,10 +21,10 @@ class AdminUserServiceTests extends Specification {
AdminUserService adminUserService

@Autowired
AdminRoleRepository adminRoleRepository
RoleRepository adminRoleRepository

@Autowired
AdminUserRepository adminUserRepository
UserRepository adminUserRepository


def "Loading existing admin user with admin role"() {
Expand Down
8 changes: 8 additions & 0 deletions docs/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Security

Security in the system is controlled by Spring Security.

Currently, the following roles are recognized:

1. `ADMIN`
1. `USER`

0 comments on commit 022c4f1

Please sign in to comment.