diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy
index 4ca5b435b..2635f908c 100644
--- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy
+++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy
@@ -6,6 +6,7 @@ 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.ui.security.service.UserService
import groovy.util.logging.Slf4j
import org.springframework.boot.context.event.ApplicationStartedEvent
import org.springframework.context.event.EventListener
@@ -19,11 +20,13 @@ class UserBootstrap {
private final ShibUIConfiguration shibUIConfiguration
private final UserRepository userRepository
private final RoleRepository roleRepository
+ private final UserService userService
- UserBootstrap(ShibUIConfiguration shibUIConfiguration, UserRepository userRepository, RoleRepository roleRepository) {
+ UserBootstrap(ShibUIConfiguration shibUIConfiguration, UserRepository userRepository, RoleRepository roleRepository, UserService userService) {
this.shibUIConfiguration = shibUIConfiguration
this.userRepository = userRepository
this.roleRepository = roleRepository
+ this.userService = userService
}
@Transactional
@@ -50,7 +53,7 @@ class UserBootstrap {
it.emailAddress = email
it
}
- userRepository.saveAndFlush(user)
+ userService.save(user)
}
}
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java
index da33c53f8..c34d8e200 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java
@@ -1,6 +1,27 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.core.io.Resource;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+import org.springframework.web.util.UrlPathHelper;
+
import com.fasterxml.jackson.databind.Module;
+
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects;
import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
@@ -13,7 +34,6 @@
import edu.internet2.tier.shibboleth.admin.ui.service.DefaultMetadataResolversPositionOrderContainerService;
import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryService;
import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryServiceImpl;
-import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService;
import edu.internet2.tier.shibboleth.admin.ui.service.EntityIdsSearchService;
import edu.internet2.tier.shibboleth.admin.ui.service.EntityIdsSearchServiceImpl;
import edu.internet2.tier.shibboleth.admin.ui.service.EntityService;
@@ -21,7 +41,6 @@
import edu.internet2.tier.shibboleth.admin.ui.service.FileWritingService;
import edu.internet2.tier.shibboleth.admin.ui.service.FilterService;
import edu.internet2.tier.shibboleth.admin.ui.service.FilterTargetService;
-import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl;
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl;
import edu.internet2.tier.shibboleth.admin.ui.service.JPAFilterServiceImpl;
import edu.internet2.tier.shibboleth.admin.ui.service.JPAFilterTargetServiceImpl;
@@ -29,33 +48,14 @@
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService;
import edu.internet2.tier.shibboleth.admin.util.AttributeUtility;
+import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils;
import edu.internet2.tier.shibboleth.admin.util.LuceneUtility;
import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions;
-import org.apache.lucene.analysis.Analyzer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.ResourceBundleMessageSource;
-import org.springframework.core.io.Resource;
-import org.springframework.web.servlet.LocaleResolver;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
-import org.springframework.web.util.UrlPathHelper;
-
-import javax.servlet.http.HttpServletRequest;
@Configuration
-@EnableConfigurationProperties({CustomPropertiesConfiguration.class, ShibUIConfiguration.class})
+@ComponentScan(basePackages="{ edu.internet2.tier.shibboleth.admin.ui.service }")
+@EnableConfigurationProperties({ CustomPropertiesConfiguration.class, ShibUIConfiguration.class })
public class CoreShibUiConfiguration {
- private static final Logger logger = LoggerFactory.getLogger(CoreShibUiConfiguration.class);
-
@Bean
public OpenSamlObjects openSamlObjects() {
return new OpenSamlObjects();
@@ -65,12 +65,7 @@ public OpenSamlObjects openSamlObjects() {
public EntityService jpaEntityService() {
return new JPAEntityServiceImpl(openSamlObjects());
}
-
- @Bean
- public EntityDescriptorService jpaEntityDescriptorService(UserService userService) {
- return new JPAEntityDescriptorServiceImpl(openSamlObjects(), jpaEntityService(), userService);
- }
-
+
@Bean
public FilterService jpaFilterService() {
return new JPAFilterServiceImpl();
@@ -99,13 +94,18 @@ public AttributeUtility attributeUtility() {
@Bean
@ConditionalOnProperty(name = "shibui.metadata-dir")
- public EntityDescriptorFilesScheduledTasks entityDescriptorFilesScheduledTasks(EntityDescriptorRepository entityDescriptorRepository, @Value("${shibui.metadata-dir}") final String metadataDir) {
- return new EntityDescriptorFilesScheduledTasks(metadataDir, entityDescriptorRepository, openSamlObjects(), fileWritingService());
+ public EntityDescriptorFilesScheduledTasks entityDescriptorFilesScheduledTasks(
+ EntityDescriptorRepository entityDescriptorRepository,
+ @Value("${shibui.metadata-dir}") final String metadataDir) {
+ return new EntityDescriptorFilesScheduledTasks(metadataDir, entityDescriptorRepository, openSamlObjects(),
+ fileWritingService());
}
@Bean
@ConditionalOnProperty(name = "shibui.metadataProviders.target")
- public MetadataProvidersScheduledTasks metadataProvidersScheduledTasks(@Value("${shibui.metadataProviders.target}") final Resource resource, final MetadataResolverService metadataResolverService) {
+ public MetadataProvidersScheduledTasks metadataProvidersScheduledTasks(
+ @Value("${shibui.metadataProviders.target}") final Resource resource,
+ final MetadataResolverService metadataResolverService) {
return new MetadataProvidersScheduledTasks(resource, metadataResolverService, fileWritingService());
}
@@ -124,7 +124,8 @@ public LocaleChangeInterceptor localeChangeInterceptor() {
/**
* A WebMvcConfigurer that won't mangle the path for the entities endpoint.
*
- * inspired by [ https://stackoverflow.com/questions/13482020/encoded-slash-2f-with-spring-requestmapping-path-param-gives-http-400 ]
+ * inspired by [
+ * https://stackoverflow.com/questions/13482020/encoded-slash-2f-with-spring-requestmapping-path-param-gives-http-400 ]
*
* @return configurer
*/
@@ -166,10 +167,9 @@ public void addInterceptors(InterceptorRegistry registry) {
}
@Bean
- public MetadataResolversPositionOrderContainerService
- metadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository
- positionOrderContainerRepository,
- MetadataResolverRepository resolverRepository) {
+ public MetadataResolversPositionOrderContainerService metadataResolversPositionOrderContainerService(
+ MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository,
+ MetadataResolverRepository resolverRepository) {
return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository);
@@ -209,4 +209,11 @@ public UserService userService(RoleRepository roleRepository, UserRepository use
public FileWritingService fileWritingService() {
return new FileCheckingFileWritingService();
}
+
+ @Bean
+ public EntityDescriptorConverstionUtils EntityDescriptorConverstionUtilsInit(EntityService entityService, OpenSamlObjects oso) {
+ EntityDescriptorConverstionUtils.setEntityService(entityService);
+ EntityDescriptorConverstionUtils.setOpenSamlObjects(oso);
+ return new EntityDescriptorConverstionUtils();
+ }
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java
index f75f323be..3d66de957 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java
@@ -5,6 +5,7 @@
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.ui.security.service.UserService;
import edu.internet2.tier.shibboleth.admin.ui.security.springsecurity.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -28,10 +29,10 @@
import java.util.Collections;
+import javax.transaction.Transactional;
+
/**
* Web security configuration.
- *
- * Workaround for slashes in URL from [https://stackoverflow.com/questions/48453980/spring-5-0-3-requestrejectedexception-the-request-was-rejected-because-the-url]
*/
@Configuration
@ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class)
@@ -46,6 +47,9 @@ public class WebSecurityConfig {
@Autowired
private UserRepository userRepository;
+ @Autowired
+ private UserService userService;
+
@Autowired
private RoleRepository roleRepository;
@@ -82,6 +86,7 @@ protected void configure(HttpSecurity http) throws Exception {
}
@Override
+ @Transactional
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO: more configurable authentication
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
@@ -100,10 +105,10 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
});
u.setRoles(Collections.singleton(adminRole));
u.setEmailAddress("admin@localhost");
- return userRepository.saveAndFlush(u);
+ return userService.save(u);
});
adminUser.setPassword(defaultPassword);
- userRepository.saveAndFlush(adminUser);
+ userService.save(adminUser);
auth
.inMemoryAuthentication()
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptor.java
index d49a5a5f4..dacc88bfc 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptor.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptor.java
@@ -145,7 +145,7 @@ public IDPSSODescriptor getIDPSSODescriptor(String s) {
}
public Group getGroup() {
- return group == null ? Group.DEFAULT_GROUP : group;
+ return group == null ? Group.ADMIN_GROUP : group;
}
@Transient
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/frontend/EntityDescriptorRepresentation.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/frontend/EntityDescriptorRepresentation.java
index 1c757b514..6ca5d7a4d 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/frontend/EntityDescriptorRepresentation.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/frontend/EntityDescriptorRepresentation.java
@@ -110,7 +110,7 @@ public String getId() {
}
public String getGroupId() {
- return groupId == null ? Group.DEFAULT_GROUP.getResourceId() : groupId;
+ return groupId == null ? Group.ADMIN_GROUP.getResourceId() : groupId;
}
public List getLogoutEndpoints() {
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java
index b37b0dcf9..41edbe2fe 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java
@@ -32,5 +32,6 @@ public interface EntityDescriptorRepository extends JpaRepository findAllByGroupIsNull();
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Group.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Group.java
index 62a61ad49..1874e6d36 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Group.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Group.java
@@ -23,9 +23,18 @@
@Entity(name = "user_groups")
@Data
public class Group {
+ public Group() {
+ }
+
+ public Group(User user) {
+ resourceId=user.getUsername();
+ name=user.getUsername();
+ description="default user-group";
+ }
+
@Transient
@JsonIgnore
- public static Group DEFAULT_GROUP;
+ public static Group ADMIN_GROUP;
@Column(name = "group_description", nullable = true)
String description;
@@ -46,7 +55,4 @@ public class Group {
@JsonIgnore
@EqualsAndHashCode.Exclude
Set entityDescriptors;
-
- @Column(name = "default_group", nullable = false)
- boolean defaultGroup = false;
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java
index 1bf4e963f..978c910e8 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java
@@ -70,12 +70,12 @@ public class User extends AbstractAuditable {
private String username;
public Group getGroup() {
- return group == null ? Group.DEFAULT_GROUP : group;
+ return group;
}
public String getGroupId() {
- if (groupId == null && getGroup() != null) {
- groupId = getGroup().getResourceId();
+ if (groupId == null) {
+ groupId = group == null ? null : getGroup().getResourceId();
}
return groupId;
}
@@ -91,10 +91,11 @@ public String getRole() {
return this.role;
}
+ /**
+ * If (for some reason) the incoming group is null, the user is defaulted to their own group
+ */
public void setGroup(Group assignedGroup) {
this.group = assignedGroup;
- if (group != null) {
- groupId = group.getResourceId();
- }
+ this.groupId = getGroup().getResourceId();
}
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepository.java
index 89df994a4..9576184e4 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepository.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepository.java
@@ -13,6 +13,4 @@ public interface GroupsRepository extends JpaRepository {
@SuppressWarnings("unchecked")
Group save(Group group);
-
- Group findByDefaultGroupTrue();
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java
index 2fcfb7587..040db27aa 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java
@@ -1,11 +1,10 @@
package edu.internet2.tier.shibboleth.admin.ui.security.service;
import java.util.List;
-import java.util.UUID;
-import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -16,10 +15,17 @@
import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository;
@Service
-public class GroupServiceImpl implements IGroupService {
+public class GroupServiceImpl implements IGroupService, InitializingBean {
@Autowired
private GroupsRepository repo;
+ public GroupServiceImpl() {
+ }
+
+ public GroupServiceImpl(GroupsRepository repo) {
+ this.repo = repo;
+ }
+
@Override
public Group createGroup(Group group) throws GroupExistsConflictException {
Group foundGroup = find(group.getResourceId());
@@ -63,18 +69,19 @@ public Group updateGroup(Group group) throws EntityNotFoundException {
return repo.save(group);
}
- @PostConstruct
+ /**
+ * Ensure (mostly for migrations) that we have defined a default admin group
+ */
+ @Override
@Transactional
- private void ensureDefaultGroupExists() {
- // This is something of a migration piece to ensure there is a default group that users and entity descriptors
- // can be assigned to out of the box.
- Group g = repo.findByDefaultGroupTrue();
+ public void afterPropertiesSet() {
+ Group g = repo.findByResourceId("admingroup");
if (g == null) {
g = new Group();
- g.setDefaultGroup(true);
- g.setName("DEFAULT-GROUP");
+ g.setName("ADMIN-GROUP");
+ g.setResourceId("admingroup");
g = repo.save(g);
}
- Group.DEFAULT_GROUP = g;
+ Group.ADMIN_GROUP = g;
}
}
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java
index 74849f5a5..25ca49f46 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java
@@ -1,26 +1,55 @@
package edu.internet2.tier.shibboleth.admin.ui.security.service;
+import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException;
import edu.internet2.tier.shibboleth.admin.ui.security.model.Group;
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.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.DependsOn;
import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
-public class UserService {
+import javax.annotation.PostConstruct;
+import javax.transaction.Transactional;
+
+@Service
+public class UserService implements InitializingBean {
+ @Autowired
+ private IGroupService groupService;
+
+ @Autowired
private RoleRepository roleRepository;
+
+ @Autowired
private UserRepository userRepository;
+ /**
+ * Primarily for testing purposes so we can control the injections
+ */
public UserService(RoleRepository roleRepository, UserRepository userRepository) {
this.roleRepository = roleRepository;
this.userRepository = userRepository;
}
+
+ public boolean currentUserIsAdmin() {
+ User user = getCurrentUser();
+ return user != null && user.getRole().equals("ROLE_ADMIN");
+ }
+ @Override
+ @Transactional
+ public void afterPropertiesSet() {
+ // TODO: Ensure all the db users have a group - migration task
+ }
+
public User getCurrentUser() {
//TODO: Consider returning an Optional here
User user = null;
@@ -35,6 +64,15 @@ public User getCurrentUser() {
}
return user;
}
+
+ public Group getCurrentUserGroup() {
+ switch (getCurrentUserAccess()) {
+ case ADMIN:
+ return Group.ADMIN_GROUP;
+ default:
+ return getCurrentUser().getGroup();
+ }
+ }
public UserAccess getCurrentUserAccess() {
User user = getCurrentUser();
@@ -44,18 +82,17 @@ public UserAccess getCurrentUserAccess() {
if (user.getRole().equals("ROLE_ADMIN")) {
return UserAccess.ADMIN;
}
- if (user.getGroup() != null) {
+ if (user.getRole().equals("ROLE_USER")) {
return UserAccess.GROUP;
}
return UserAccess.NONE;
}
-
+
public boolean isAuthorizedFor(Group objectGroup) {
- String groupId = objectGroup == null ? "" : objectGroup.getResourceId();
- return isAuthorizedFor(groupId);
+ String objectGroupId = objectGroup == null ? Group.ADMIN_GROUP.getResourceId() : objectGroup.getResourceId();
+ return isAuthorizedFor(objectGroupId);
}
-
public boolean isAuthorizedFor(String objectGroupResourceId) {
switch (getCurrentUserAccess()) { // no user returns NONE
case ADMIN:
@@ -69,6 +106,26 @@ public boolean isAuthorizedFor(String objectGroupResourceId) {
return false;
}
}
+
+ /**
+ * Creating users should always have a group. If the user isn't assigned to a group, create one
+ */
+ public User save(User user) {
+ if (user.getRole().equalsIgnoreCase("ROLE_ADMIN")) {
+ user.setGroup(Group.ADMIN_GROUP);
+ }
+ else if (user.getGroupId() == null) {
+ Group g = new Group(user);
+ try {
+ g = groupService.createGroup(g);
+ }
+ catch (GroupExistsConflictException e) {
+ g = groupService.find(user.getUsername());
+ }
+ user.setGroup(g);
+ }
+ return userRepository.save(user);
+ }
/**
* Given a user with a defined User.role, update the User.roles collection with that role.
@@ -92,9 +149,4 @@ public void updateUserRole(User user) {
throw new RuntimeException(String.format("User with username [%s] has no role defined and therefor cannot be updated!", user.getUsername()));
}
}
-
- public boolean currentUserIsAdmin() {
- User user = getCurrentUser();
- return user != null && user.getRole().equals("ROLE_ADMIN");
- }
}
\ No newline at end of file
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java
index 1ebdd7a6d..236622255 100644
--- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java
@@ -1,6 +1,5 @@
package edu.internet2.tier.shibboleth.admin.ui.service;
-
import com.google.common.base.Strings;
import edu.internet2.tier.shibboleth.admin.ui.controller.ErrorResponse;
@@ -9,7 +8,6 @@
import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeValue;
import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPerson;
-import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPersonBuilder;
import edu.internet2.tier.shibboleth.admin.ui.domain.Description;
import edu.internet2.tier.shibboleth.admin.ui.domain.DisplayName;
import edu.internet2.tier.shibboleth.admin.ui.domain.EmailAddress;
@@ -62,9 +60,11 @@
import org.opensaml.xmlsec.signature.KeyInfo;
import org.opensaml.xmlsec.signature.X509Certificate;
import org.opensaml.xmlsec.signature.X509Data;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
@@ -79,34 +79,40 @@
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
-import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.getStringListOfAttributeValues;
-
+import static edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils.*;
+import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.*;
-/**
- * Default implementation of {@link EntityDescriptorService}
- *
- * @since 1.0
- */
@Slf4j
-public class JPAEntityDescriptorServiceImpl implements EntityDescriptorService {
+@Service
+public class JPAEntityDescriptorServiceImpl implements EntityDescriptorService, InitializingBean {
@Autowired
- private EntityDescriptorRepository entityDescriptorRepository;
+ EntityDescriptorRepository entityDescriptorRepository;
@Autowired
- private EntityService entityService;
-
- @Autowired
- private IGroupService groupService;
+ IGroupService groupService;
@Autowired
private OpenSamlObjects openSamlObjects;
- private UserService userService;
-
- public JPAEntityDescriptorServiceImpl(OpenSamlObjects openSamlObjects, EntityService entityService, UserService userService) {
- this.openSamlObjects = openSamlObjects;
- this.entityService = entityService;
- this.userService = userService;
+ @Autowired
+ UserService userService;
+
+ @Override
+ @Transactional
+ public void afterPropertiesSet() {
+ // SHIBUI-1740: Adding admin group to all existing entity descriptors that do not have a group already.
+ // Because this class has a GroupService, we assume the ADMIN_GROUP has already been setup prior to being
+ // autowired into this class.
+ try {
+ entityDescriptorRepository.findAllByGroupIsNull().forEach(ed -> {
+ ed.setGroup(Group.ADMIN_GROUP);
+ entityDescriptorRepository.save(ed);
+ });
+ }
+ catch (NullPointerException e) {
+ // This block was added due to a number of mock test where NPEs happened. Rather than wire more mock junk
+ // into tests that are only trying to compensate for this migration, this is here
+ }
}
private EntityDescriptor buildDescriptorFromRepresentation(final EntityDescriptor ed, final EntityDescriptorRepresentation representation) {
@@ -137,35 +143,11 @@ public EntityDescriptor createDescriptorFromRepresentation(final EntityDescripto
return buildDescriptorFromRepresentation(ed, representation);
}
- KeyDescriptor createKeyDescriptor(String name, String type, String value) {
- KeyDescriptor keyDescriptor = openSamlObjects.buildDefaultInstanceOfType(KeyDescriptor.class);
-
- if (!Strings.isNullOrEmpty(name)) {
- keyDescriptor.setName(name);
- }
-
- if (!"both".equals(type)) {
- keyDescriptor.setUsageType(type);
- }
-
- KeyInfo keyInfo = openSamlObjects.buildDefaultInstanceOfType(KeyInfo.class);
- keyDescriptor.setKeyInfo(keyInfo);
-
- X509Data x509Data = openSamlObjects.buildDefaultInstanceOfType(X509Data.class);
- keyInfo.getXMLObjects().add(x509Data);
-
- X509Certificate x509Certificate = openSamlObjects.buildDefaultInstanceOfType(X509Certificate.class);
- x509Data.getXMLObjects().add(x509Certificate);
- x509Certificate.setValue(value);
-
- return keyDescriptor;
- }
-
@Override
public EntityDescriptorRepresentation createNew(EntityDescriptor ed) throws ForbiddenException, EntityIdExistsException {
return createNew(createRepresentationFromDescriptor(ed));
}
-
+
@Override
public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep) throws ForbiddenException, EntityIdExistsException {
if (edRep.isServiceEnabled() && !userService.currentUserIsAdmin()) {
@@ -177,10 +159,10 @@ public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation e
}
EntityDescriptor ed = (EntityDescriptor) createDescriptorFromRepresentation(edRep);
- ed.setGroup(userService.getCurrentUser().getGroup());
+ ed.setGroup(userService.getCurrentUserGroup());
return createRepresentationFromDescriptor(entityDescriptorRepository.save(ed));
}
-
+
@Override
public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.opensaml.saml.saml2.metadata.EntityDescriptor entityDescriptor) {
EntityDescriptor ed = (EntityDescriptor) entityDescriptor;
@@ -195,7 +177,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope
representation.setVersion(ed.hashCode());
representation.setCreatedBy(ed.getCreatedBy());
representation.setCurrent(ed.isCurrent());
- representation.setGroupId(ed.getGroup() != null ? ed.getGroup().getResourceId() : Group.DEFAULT_GROUP.getResourceId());
+ representation.setGroupId(ed.getGroup().getResourceId());
if (ed.getSPSSODescriptor("") != null && ed.getSPSSODescriptor("").getSupportedProtocols().size() > 0) {
ServiceProviderSsoDescriptorRepresentation serviceProviderSsoDescriptorRepresentation = representation.getServiceProviderSsoDescriptor(true);
@@ -353,7 +335,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope
if (jpaAttribute.getAttributeValues().size() != 1) {
throw new RuntimeException("Multiple/No values detected where one is expected!");
}
- attributeValues = getValueFromXMLObject(jpaAttribute.getAttributeValues().get(0));
+ attributeValues = ModelRepresentationConversions.getValueFromXMLObject(jpaAttribute.getAttributeValues().get(0));
break;
case INTEGER:
if (jpaAttribute.getAttributeValues().size() != 1) {
@@ -367,7 +349,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope
}
if (overrideProperty.getPersistType() != null &&
!overrideProperty.getPersistType().equals(overrideProperty.getDisplayType())) {
- attributeValues = overrideProperty.getPersistValue().equals(getValueFromXMLObject(jpaAttribute.getAttributeValues().get(0)));
+ attributeValues = overrideProperty.getPersistValue().equals(ModelRepresentationConversions.getValueFromXMLObject(jpaAttribute.getAttributeValues().get(0)));
} else {
attributeValues = Boolean.valueOf(overrideProperty.getInvert()) ^ Boolean.valueOf(((XSBoolean) jpaAttribute.getAttributeValues()
.get(0)).getStoredValue());
@@ -377,7 +359,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope
case LIST:
case SELECTION_LIST:
attributeValues = jpaAttribute.getAttributeValues().stream()
- .map(attributeValue -> getValueFromXMLObject(attributeValue))
+ .map(attributeValue -> ModelRepresentationConversions.getValueFromXMLObject(attributeValue))
.collect(Collectors.toList());
}
relyingPartyOverrides.put(((IRelyingPartyOverrideProperty) override.get()).getName(), attributeValues);
@@ -431,32 +413,6 @@ public List getAttributeReleaseListFromAttributeList(List att
return ModelRepresentationConversions.getAttributeReleaseListFromAttributeList(attributeList);
}
- private EntityAttributes getEntityAttributes(EntityDescriptor ed) {
- return getEntityAttributes(ed, true);
- }
-
- private EntityAttributes getEntityAttributes(EntityDescriptor ed, boolean create) {
- Extensions extensions = ed.getExtensions();
- if (extensions == null && !create) {
- return null;
- }
- if (extensions == null) {
- extensions = openSamlObjects.buildDefaultInstanceOfType(Extensions.class);
- ed.setExtensions(extensions);
- }
-
- EntityAttributes entityAttributes = null;
- if (extensions.getUnknownXMLObjects(EntityAttributes.DEFAULT_ELEMENT_NAME).size() > 0) {
- entityAttributes = (EntityAttributes) extensions.getUnknownXMLObjects(EntityAttributes.DEFAULT_ELEMENT_NAME).get(0);
- } else {
- if (create) {
- entityAttributes = ((EntityAttributesBuilder) openSamlObjects.getBuilderFactory().getBuilder(EntityAttributes.DEFAULT_ELEMENT_NAME)).buildObject();
- extensions.getUnknownXMLObjects().add(entityAttributes);
- }
- }
- return entityAttributes;
- }
-
@Override
public EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws EntityNotFoundException, ForbiddenException {
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
@@ -468,306 +424,12 @@ public EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throw
}
return ed;
}
-
- private Optional getOptionalEntityAttributes(EntityDescriptor ed) {
- return Optional.ofNullable(getEntityAttributes(ed, false));
- }
-
+
@Override
public Map getRelyingPartyOverridesRepresentationFromAttributeList(List attributeList) {
return ModelRepresentationConversions.getRelyingPartyOverridesRepresentationFromAttributeList(attributeList);
}
-
- private SPSSODescriptor getSPSSODescriptorFromEntityDescriptor(EntityDescriptor entityDescriptor) {
- return getSPSSODescriptorFromEntityDescriptor(entityDescriptor, true);
- }
-
- private SPSSODescriptor getSPSSODescriptorFromEntityDescriptor(EntityDescriptor entityDescriptor, boolean create) {
- if (entityDescriptor.getSPSSODescriptor("") == null && create) {
- SPSSODescriptor spssoDescriptor = openSamlObjects.buildDefaultInstanceOfType(SPSSODescriptor.class);
- entityDescriptor.getRoleDescriptors().add(spssoDescriptor);
- }
- return entityDescriptor.getSPSSODescriptor("");
- }
-
- private UIInfo getUIInfo(EntityDescriptor ed) {
- Extensions extensions = getSPSSODescriptorFromEntityDescriptor(ed).getExtensions();
- if (extensions == null) {
- extensions = openSamlObjects.buildDefaultInstanceOfType(Extensions.class);
- ed.getSPSSODescriptor("").setExtensions(extensions);
- }
-
- UIInfo uiInfo;
- if (extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).size() > 0) {
- uiInfo = (UIInfo) extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).get(0);
- } else {
- uiInfo = openSamlObjects.buildDefaultInstanceOfType(UIInfo.class);
- extensions.getUnknownXMLObjects().add(uiInfo);
- }
- return uiInfo;
- }
-
- @PostConstruct
- @Transactional
- private void migration() {
- // SHIBUI-1740: Adding default group to all existing entity descriptors that do not have a group already.
- // Because this class has a GroupService, we assume the DEFAULT_GROUP has already been setup prior to being
- // autowired into this class.
- try {
- entityDescriptorRepository.findAllByGroupIsNull().forEach(ed -> {
- ed.setGroup(Group.DEFAULT_GROUP);
- entityDescriptorRepository.save(ed);
- });
- }
- catch (NullPointerException e) {
- // This block was added due to a number of mock test where NPEs happened. Rather than wire more mock junk
- // into tests that are only trying to compensate for this migration, this is here
- }
- }
-
- // TODO: remove
- private String getValueFromXMLObject(XMLObject xmlObject) {
- return ModelRepresentationConversions.getValueFromXMLObject(xmlObject);
- }
-
- private void removeUIInfo(EntityDescriptor ed) {
- SPSSODescriptor spssoDescriptor = getSPSSODescriptorFromEntityDescriptor(ed, false);
- if (spssoDescriptor != null) {
- Extensions extensions = spssoDescriptor.getExtensions();
- if (extensions == null) {
- return;
- }
- if (extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).size() > 0) {
- extensions.getUnknownXMLObjects().remove(extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).get(0));
- }
- }
- }
-
- void setupACSs(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // setup ACSs
- if (representation.getAssertionConsumerServices() != null && representation.getAssertionConsumerServices().size() > 0) {
- // TODO: review if we need more than a naive implementation
- ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getAssertionConsumerServices().clear());
- for (AssertionConsumerServiceRepresentation acsRepresentation : representation.getAssertionConsumerServices()) {
- AssertionConsumerService assertionConsumerService = openSamlObjects.buildDefaultInstanceOfType(AssertionConsumerService.class);
- getSPSSODescriptorFromEntityDescriptor(ed).getAssertionConsumerServices().add(assertionConsumerService);
- if (acsRepresentation.isMakeDefault()) {
- assertionConsumerService.setIsDefault(true);
- }
- assertionConsumerService.setBinding(acsRepresentation.getBinding());
- assertionConsumerService.setLocation(acsRepresentation.getLocationUrl());
- assertionConsumerService.setIndex(acsRepresentation.getIndex());
- }
- } else {
- ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getAssertionConsumerServices().clear());
- }
- }
-
- void setupContacts(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // set up contacts
- if (representation.getContacts() != null && representation.getContacts().size() > 0) {
- ed.getContactPersons().clear();
- for (ContactRepresentation contactRepresentation : representation.getContacts()) {
- ContactPerson contactPerson = ((ContactPersonBuilder) openSamlObjects.getBuilderFactory().getBuilder(ContactPerson.DEFAULT_ELEMENT_NAME)).buildObject();
-
- contactPerson.setType(contactRepresentation.getType());
-
- GivenName givenName = openSamlObjects.buildDefaultInstanceOfType(GivenName.class);
- givenName.setName(contactRepresentation.getName());
- contactPerson.setGivenName(givenName);
-
- EmailAddress emailAddress = openSamlObjects.buildDefaultInstanceOfType(EmailAddress.class);
- emailAddress.setAddress(contactRepresentation.getEmailAddress());
- contactPerson.addEmailAddress(emailAddress);
-
- ed.addContactPerson(contactPerson);
- }
- } else {
- ed.getContactPersons().clear();
- }
- }
-
- void setupLogout(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // setup logout
- if (representation.getLogoutEndpoints() != null && !representation.getLogoutEndpoints().isEmpty()) {
- // TODO: review if we need more than a naive implementation
- ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getSingleLogoutServices().clear());
- for (LogoutEndpointRepresentation logoutEndpointRepresentation : representation.getLogoutEndpoints()) {
- SingleLogoutService singleLogoutService = openSamlObjects.buildDefaultInstanceOfType(SingleLogoutService.class);
- singleLogoutService.setBinding(logoutEndpointRepresentation.getBindingType());
- singleLogoutService.setLocation(logoutEndpointRepresentation.getUrl());
-
- getSPSSODescriptorFromEntityDescriptor(ed).getSingleLogoutServices().add(singleLogoutService);
- }
- } else {
- ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getSingleLogoutServices().clear());
- }
- }
-
- void setupOrganization(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // set up organization
- if (representation.getOrganization() != null && representation.getOrganization().getName() != null && representation.getOrganization().getDisplayName() != null && representation.getOrganization().getUrl() != null) {
- OrganizationRepresentation organizationRepresentation = representation.getOrganization();
- Organization organization = openSamlObjects.buildDefaultInstanceOfType(Organization.class);
-
- OrganizationName organizationName = openSamlObjects.buildDefaultInstanceOfType(OrganizationName.class);
- organizationName.setXMLLang("en");
- organizationName.setValue(organizationRepresentation.getName());
- organization.getOrganizationNames().add(organizationName);
-
- OrganizationDisplayName organizationDisplayName = openSamlObjects.buildDefaultInstanceOfType(OrganizationDisplayName.class);
- organizationDisplayName.setXMLLang("en");
- organizationDisplayName.setValue(organizationRepresentation.getDisplayName());
- organization.getDisplayNames().add(organizationDisplayName);
-
- OrganizationURL organizationURL = openSamlObjects.buildDefaultInstanceOfType(OrganizationURL.class);
- organizationURL.setXMLLang("en");
- organizationURL.setValue(organizationRepresentation.getUrl());
- organization.getURLs().add(organizationURL);
-
- ed.setOrganization(organization);
- } else {
- ed.setOrganization(null);
- }
- }
-
- void setupRelyingPartyOverrides(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- if (representation.getRelyingPartyOverrides() != null || (representation.getAttributeRelease() != null && representation.getAttributeRelease().size() > 0)) {
- // TODO: review if we need more than a naive implementation
- getOptionalEntityAttributes(ed).ifPresent(entityAttributes -> entityAttributes.getAttributes().clear());
- getEntityAttributes(ed).getAttributes().addAll(entityService.getAttributeListFromEntityRepresentation(representation));
- } else {
- getOptionalEntityAttributes(ed).ifPresent(entityAttributes -> entityAttributes.getAttributes().clear());
- }
- }
-
- void setupSecurity(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // setup security
- if (representation.getSecurityInfo() != null) {
- SecurityInfoRepresentation securityInfoRepresentation = representation.getSecurityInfo();
- if (securityInfoRepresentation.isAuthenticationRequestsSigned()) {
- getSPSSODescriptorFromEntityDescriptor(ed).setAuthnRequestsSigned(true);
- }
- if (securityInfoRepresentation.isWantAssertionsSigned()) {
- getSPSSODescriptorFromEntityDescriptor(ed).setWantAssertionsSigned(true);
- }
- // TODO: review if we need more than a naive implementation
- ed.getOptionalSPSSODescriptor().ifPresent( i -> i.getKeyDescriptors().clear());
- if (securityInfoRepresentation.isX509CertificateAvailable()) {
- for (SecurityInfoRepresentation.X509CertificateRepresentation x509CertificateRepresentation : securityInfoRepresentation.getX509Certificates()) {
- KeyDescriptor keyDescriptor = createKeyDescriptor(x509CertificateRepresentation.getName(), x509CertificateRepresentation.getType(), x509CertificateRepresentation.getValue());
- getSPSSODescriptorFromEntityDescriptor(ed).addKeyDescriptor(keyDescriptor);
- }
- }
- } else {
- ed.getOptionalSPSSODescriptor().ifPresent( spssoDescriptor -> {
- spssoDescriptor.setAuthnRequestsSigned((Boolean) null);
- spssoDescriptor.setWantAssertionsSigned((Boolean) null);
- spssoDescriptor.getKeyDescriptors().clear();
- });
- }
- }
-
- void setupSPSSODescriptor(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // setup SPSSODescriptor
- if (representation.getServiceProviderSsoDescriptor() != null) {
- SPSSODescriptor spssoDescriptor = getSPSSODescriptorFromEntityDescriptor(ed);
-
- spssoDescriptor.setSupportedProtocols(Collections.EMPTY_LIST);
- if (!Strings.isNullOrEmpty(representation.getServiceProviderSsoDescriptor().getProtocolSupportEnum())) {
- spssoDescriptor.setSupportedProtocols(
- Arrays.stream(representation.getServiceProviderSsoDescriptor().getProtocolSupportEnum().split(",")).map(p -> MDDCConstants.PROTOCOL_BINDINGS.get(p.trim())).collect(Collectors.toList())
- );
- }
-
- spssoDescriptor.getNameIDFormats().clear();
- if (representation.getServiceProviderSsoDescriptor() != null && representation.getServiceProviderSsoDescriptor().getNameIdFormats() != null && representation.getServiceProviderSsoDescriptor().getNameIdFormats().size() > 0) {
- for (String nameidFormat : representation.getServiceProviderSsoDescriptor().getNameIdFormats()) {
- NameIDFormat nameIDFormat = openSamlObjects.buildDefaultInstanceOfType(NameIDFormat.class);
-
- nameIDFormat.setFormat(nameidFormat);
-
- spssoDescriptor.getNameIDFormats().add(nameIDFormat);
- }
- }
- } else {
- ed.setRoleDescriptors(null);
- }
- }
-
- void setupUIInfo(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
- // set up mdui
- if (representation.getMdui() != null) {
- // TODO: check if we need more than a naive implementation
- removeUIInfo(ed);
- MduiRepresentation mduiRepresentation = representation.getMdui();
-
- if (!Strings.isNullOrEmpty(mduiRepresentation.getDisplayName())) {
- DisplayName displayName = openSamlObjects.buildDefaultInstanceOfType(DisplayName.class);
- getUIInfo(ed).addDisplayName(displayName);
- displayName.setValue(mduiRepresentation.getDisplayName());
- displayName.setXMLLang("en");
- } else {
- ed.getOptionalSPSSODescriptor()
- .flatMap(SPSSODescriptor::getOptionalExtensions)
- .flatMap(Extensions::getOptionalUIInfo)
- .ifPresent(u -> u.getXMLObjects().removeAll(u.getDisplayNames()));
- }
-
- if (!Strings.isNullOrEmpty(mduiRepresentation.getInformationUrl())) {
- InformationURL informationURL = openSamlObjects.buildDefaultInstanceOfType(InformationURL.class);
- getUIInfo(ed).addInformationURL(informationURL);
- informationURL.setValue(mduiRepresentation.getInformationUrl());
- informationURL.setXMLLang("en");
- } else {
- ed.getOptionalSPSSODescriptor()
- .flatMap(SPSSODescriptor::getOptionalExtensions)
- .flatMap(Extensions::getOptionalUIInfo)
- .ifPresent(u -> u.getXMLObjects().removeAll(u.getInformationURLs()));
- }
-
- if (!Strings.isNullOrEmpty(mduiRepresentation.getPrivacyStatementUrl())) {
- PrivacyStatementURL privacyStatementURL = openSamlObjects.buildDefaultInstanceOfType(PrivacyStatementURL.class);
- getUIInfo(ed).addPrivacyStatementURL(privacyStatementURL);
- privacyStatementURL.setValue(mduiRepresentation.getPrivacyStatementUrl());
- privacyStatementURL.setXMLLang("en");
- } else {
- ed.getOptionalSPSSODescriptor()
- .flatMap(SPSSODescriptor::getOptionalExtensions)
- .flatMap(Extensions::getOptionalUIInfo)
- .ifPresent(u -> u.getXMLObjects().removeAll(u.getPrivacyStatementURLs()));
- }
-
- if (!Strings.isNullOrEmpty(mduiRepresentation.getDescription())) {
- Description description = openSamlObjects.buildDefaultInstanceOfType(Description.class);
- getUIInfo(ed).addDescription(description);
- description.setValue(mduiRepresentation.getDescription());
- description.setXMLLang("en");
- } else {
- ed.getOptionalSPSSODescriptor()
- .flatMap(SPSSODescriptor::getOptionalExtensions)
- .flatMap(Extensions::getOptionalUIInfo)
- .ifPresent(u -> u.getXMLObjects().removeAll(u.getDescriptions()));
- }
-
- if (!Strings.isNullOrEmpty(mduiRepresentation.getLogoUrl())) {
- Logo logo = openSamlObjects.buildDefaultInstanceOfType(Logo.class);
- getUIInfo(ed).addLogo(logo);
- logo.setURL(mduiRepresentation.getLogoUrl());
- logo.setHeight(mduiRepresentation.getLogoHeight());
- logo.setWidth(mduiRepresentation.getLogoWidth());
- logo.setXMLLang("en");
- } else {
- ed.getOptionalSPSSODescriptor()
- .flatMap(SPSSODescriptor::getOptionalExtensions)
- .flatMap(Extensions::getOptionalUIInfo)
- .ifPresent(u -> u.getXMLObjects().removeAll(u.getLogos()));
- }
- } else {
- removeUIInfo(ed);
- }
- }
-
+
@Override
public EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRep) throws ForbiddenException, EntityNotFoundException {
EntityDescriptor existingEd = entityDescriptorRepository.findByResourceId(edRep.getId());
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/EntityDescriptorConverstionUtils.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/EntityDescriptorConverstionUtils.java
new file mode 100644
index 000000000..843567496
--- /dev/null
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/EntityDescriptorConverstionUtils.java
@@ -0,0 +1,378 @@
+package edu.internet2.tier.shibboleth.admin.util;
+
+import static edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils.getEntityAttributes;
+import static edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils.getOptionalEntityAttributes;
+import static edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils.getSPSSODescriptorFromEntityDescriptor;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.opensaml.xmlsec.signature.KeyInfo;
+import org.opensaml.xmlsec.signature.X509Certificate;
+import org.opensaml.xmlsec.signature.X509Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.google.common.base.Strings;
+
+import edu.internet2.tier.shibboleth.admin.ui.domain.AssertionConsumerService;
+import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPerson;
+import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPersonBuilder;
+import edu.internet2.tier.shibboleth.admin.ui.domain.Description;
+import edu.internet2.tier.shibboleth.admin.ui.domain.DisplayName;
+import edu.internet2.tier.shibboleth.admin.ui.domain.EmailAddress;
+import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributes;
+import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesBuilder;
+import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor;
+import edu.internet2.tier.shibboleth.admin.ui.domain.Extensions;
+import edu.internet2.tier.shibboleth.admin.ui.domain.GivenName;
+import edu.internet2.tier.shibboleth.admin.ui.domain.InformationURL;
+import edu.internet2.tier.shibboleth.admin.ui.domain.KeyDescriptor;
+import edu.internet2.tier.shibboleth.admin.ui.domain.Logo;
+import edu.internet2.tier.shibboleth.admin.ui.domain.NameIDFormat;
+import edu.internet2.tier.shibboleth.admin.ui.domain.Organization;
+import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationDisplayName;
+import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationName;
+import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationURL;
+import edu.internet2.tier.shibboleth.admin.ui.domain.PrivacyStatementURL;
+import edu.internet2.tier.shibboleth.admin.ui.domain.SPSSODescriptor;
+import edu.internet2.tier.shibboleth.admin.ui.domain.SingleLogoutService;
+import edu.internet2.tier.shibboleth.admin.ui.domain.UIInfo;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.AssertionConsumerServiceRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ContactRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.LogoutEndpointRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.MduiRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.OrganizationRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation;
+import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects;
+import edu.internet2.tier.shibboleth.admin.ui.service.EntityService;
+import lombok.Setter;
+
+@Service
+public class EntityDescriptorConverstionUtils {
+ @Autowired
+ @Setter
+ private static OpenSamlObjects openSamlObjects;
+
+ @Autowired
+ @Setter
+ private static EntityService entityService;
+
+ public static KeyDescriptor createKeyDescriptor(String name, String type, String value) {
+ KeyDescriptor keyDescriptor = openSamlObjects.buildDefaultInstanceOfType(KeyDescriptor.class);
+
+ if (!Strings.isNullOrEmpty(name)) {
+ keyDescriptor.setName(name);
+ }
+
+ if (!"both".equals(type)) {
+ keyDescriptor.setUsageType(type);
+ }
+
+ KeyInfo keyInfo = openSamlObjects.buildDefaultInstanceOfType(KeyInfo.class);
+ keyDescriptor.setKeyInfo(keyInfo);
+
+ X509Data x509Data = openSamlObjects.buildDefaultInstanceOfType(X509Data.class);
+ keyInfo.getXMLObjects().add(x509Data);
+
+ X509Certificate x509Certificate = openSamlObjects.buildDefaultInstanceOfType(X509Certificate.class);
+ x509Data.getXMLObjects().add(x509Certificate);
+ x509Certificate.setValue(value);
+
+ return keyDescriptor;
+ }
+
+ public static EntityAttributes getEntityAttributes(EntityDescriptor ed) {
+ return getEntityAttributes(ed, true);
+ }
+
+ public static EntityAttributes getEntityAttributes(EntityDescriptor ed, boolean create) {
+ Extensions extensions = ed.getExtensions();
+ if (extensions == null && !create) {
+ return null;
+ }
+ if (extensions == null) {
+ extensions = openSamlObjects.buildDefaultInstanceOfType(Extensions.class);
+ ed.setExtensions(extensions);
+ }
+
+ EntityAttributes entityAttributes = null;
+ if (extensions.getUnknownXMLObjects(EntityAttributes.DEFAULT_ELEMENT_NAME).size() > 0) {
+ entityAttributes = (EntityAttributes) extensions.getUnknownXMLObjects(EntityAttributes.DEFAULT_ELEMENT_NAME).get(0);
+ } else {
+ if (create) {
+ entityAttributes = ((EntityAttributesBuilder) openSamlObjects.getBuilderFactory().getBuilder(EntityAttributes.DEFAULT_ELEMENT_NAME)).buildObject();
+ extensions.getUnknownXMLObjects().add(entityAttributes);
+ }
+ }
+ return entityAttributes;
+ }
+
+ public static Optional getOptionalEntityAttributes(EntityDescriptor ed) {
+ return Optional.ofNullable(getEntityAttributes(ed, false));
+ }
+
+ public static SPSSODescriptor getSPSSODescriptorFromEntityDescriptor(EntityDescriptor entityDescriptor) {
+ return getSPSSODescriptorFromEntityDescriptor(entityDescriptor, true);
+ }
+
+ public static SPSSODescriptor getSPSSODescriptorFromEntityDescriptor(EntityDescriptor entityDescriptor, boolean create) {
+ if (entityDescriptor.getSPSSODescriptor("") == null && create) {
+ SPSSODescriptor spssoDescriptor = openSamlObjects.buildDefaultInstanceOfType(SPSSODescriptor.class);
+ entityDescriptor.getRoleDescriptors().add(spssoDescriptor);
+ }
+ return entityDescriptor.getSPSSODescriptor("");
+ }
+
+ private static UIInfo getUIInfo(EntityDescriptor ed) {
+ Extensions extensions = getSPSSODescriptorFromEntityDescriptor(ed).getExtensions();
+ if (extensions == null) {
+ extensions = openSamlObjects.buildDefaultInstanceOfType(Extensions.class);
+ ed.getSPSSODescriptor("").setExtensions(extensions);
+ }
+
+ UIInfo uiInfo;
+ if (extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).size() > 0) {
+ uiInfo = (UIInfo) extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).get(0);
+ } else {
+ uiInfo = openSamlObjects.buildDefaultInstanceOfType(UIInfo.class);
+ extensions.getUnknownXMLObjects().add(uiInfo);
+ }
+ return uiInfo;
+ }
+
+ private static void removeUIInfo(EntityDescriptor ed) {
+ SPSSODescriptor spssoDescriptor = getSPSSODescriptorFromEntityDescriptor(ed, false);
+ if (spssoDescriptor != null) {
+ Extensions extensions = spssoDescriptor.getExtensions();
+ if (extensions == null) {
+ return;
+ }
+ if (extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).size() > 0) {
+ extensions.getUnknownXMLObjects().remove(extensions.getUnknownXMLObjects(UIInfo.DEFAULT_ELEMENT_NAME).get(0));
+ }
+ }
+ }
+
+ public static void setupACSs(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getAssertionConsumerServices() != null && representation.getAssertionConsumerServices().size() > 0) {
+ // TODO: review if we need more than a naive implementation
+ ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getAssertionConsumerServices().clear());
+ for (AssertionConsumerServiceRepresentation acsRepresentation : representation.getAssertionConsumerServices()) {
+ AssertionConsumerService assertionConsumerService = openSamlObjects.buildDefaultInstanceOfType(AssertionConsumerService.class);
+ getSPSSODescriptorFromEntityDescriptor(ed).getAssertionConsumerServices().add(assertionConsumerService);
+ if (acsRepresentation.isMakeDefault()) {
+ assertionConsumerService.setIsDefault(true);
+ }
+ assertionConsumerService.setBinding(acsRepresentation.getBinding());
+ assertionConsumerService.setLocation(acsRepresentation.getLocationUrl());
+ assertionConsumerService.setIndex(acsRepresentation.getIndex());
+ }
+ } else {
+ ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getAssertionConsumerServices().clear());
+ }
+ }
+
+ public static void setupContacts(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getContacts() != null && representation.getContacts().size() > 0) {
+ ed.getContactPersons().clear();
+ for (ContactRepresentation contactRepresentation : representation.getContacts()) {
+ ContactPerson contactPerson = ((ContactPersonBuilder) openSamlObjects.getBuilderFactory().getBuilder(ContactPerson.DEFAULT_ELEMENT_NAME)).buildObject();
+
+ contactPerson.setType(contactRepresentation.getType());
+
+ GivenName givenName = openSamlObjects.buildDefaultInstanceOfType(GivenName.class);
+ givenName.setName(contactRepresentation.getName());
+ contactPerson.setGivenName(givenName);
+
+ EmailAddress emailAddress = openSamlObjects.buildDefaultInstanceOfType(EmailAddress.class);
+ emailAddress.setAddress(contactRepresentation.getEmailAddress());
+ contactPerson.addEmailAddress(emailAddress);
+
+ ed.addContactPerson(contactPerson);
+ }
+ } else {
+ ed.getContactPersons().clear();
+ }
+ }
+
+ public static void setupLogout(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ // setup logout
+ if (representation.getLogoutEndpoints() != null && !representation.getLogoutEndpoints().isEmpty()) {
+ // TODO: review if we need more than a naive implementation
+ ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getSingleLogoutServices().clear());
+ for (LogoutEndpointRepresentation logoutEndpointRepresentation : representation.getLogoutEndpoints()) {
+ SingleLogoutService singleLogoutService = openSamlObjects.buildDefaultInstanceOfType(SingleLogoutService.class);
+ singleLogoutService.setBinding(logoutEndpointRepresentation.getBindingType());
+ singleLogoutService.setLocation(logoutEndpointRepresentation.getUrl());
+
+ getSPSSODescriptorFromEntityDescriptor(ed).getSingleLogoutServices().add(singleLogoutService);
+ }
+ } else {
+ ed.getOptionalSPSSODescriptor().ifPresent(spssoDescriptor -> spssoDescriptor.getSingleLogoutServices().clear());
+ }
+ }
+
+ public static void setupOrganization(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getOrganization() != null && representation.getOrganization().getName() != null && representation.getOrganization().getDisplayName() != null && representation.getOrganization().getUrl() != null) {
+ OrganizationRepresentation organizationRepresentation = representation.getOrganization();
+ Organization organization = openSamlObjects.buildDefaultInstanceOfType(Organization.class);
+
+ OrganizationName organizationName = openSamlObjects.buildDefaultInstanceOfType(OrganizationName.class);
+ organizationName.setXMLLang("en");
+ organizationName.setValue(organizationRepresentation.getName());
+ organization.getOrganizationNames().add(organizationName);
+
+ OrganizationDisplayName organizationDisplayName = openSamlObjects.buildDefaultInstanceOfType(OrganizationDisplayName.class);
+ organizationDisplayName.setXMLLang("en");
+ organizationDisplayName.setValue(organizationRepresentation.getDisplayName());
+ organization.getDisplayNames().add(organizationDisplayName);
+
+ OrganizationURL organizationURL = openSamlObjects.buildDefaultInstanceOfType(OrganizationURL.class);
+ organizationURL.setXMLLang("en");
+ organizationURL.setValue(organizationRepresentation.getUrl());
+ organization.getURLs().add(organizationURL);
+
+ ed.setOrganization(organization);
+ } else {
+ ed.setOrganization(null);
+ }
+ }
+
+ public static void setupSecurity(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getSecurityInfo() != null) {
+ SecurityInfoRepresentation securityInfoRepresentation = representation.getSecurityInfo();
+ if (securityInfoRepresentation.isAuthenticationRequestsSigned()) {
+ getSPSSODescriptorFromEntityDescriptor(ed).setAuthnRequestsSigned(true);
+ }
+ if (securityInfoRepresentation.isWantAssertionsSigned()) {
+ getSPSSODescriptorFromEntityDescriptor(ed).setWantAssertionsSigned(true);
+ }
+ // TODO: review if we need more than a naive implementation
+ ed.getOptionalSPSSODescriptor().ifPresent( i -> i.getKeyDescriptors().clear());
+ if (securityInfoRepresentation.isX509CertificateAvailable()) {
+ for (SecurityInfoRepresentation.X509CertificateRepresentation x509CertificateRepresentation : securityInfoRepresentation.getX509Certificates()) {
+ KeyDescriptor keyDescriptor = createKeyDescriptor(x509CertificateRepresentation.getName(), x509CertificateRepresentation.getType(), x509CertificateRepresentation.getValue());
+ getSPSSODescriptorFromEntityDescriptor(ed).addKeyDescriptor(keyDescriptor);
+ }
+ }
+ } else {
+ ed.getOptionalSPSSODescriptor().ifPresent( spssoDescriptor -> {
+ spssoDescriptor.setAuthnRequestsSigned((Boolean) null);
+ spssoDescriptor.setWantAssertionsSigned((Boolean) null);
+ spssoDescriptor.getKeyDescriptors().clear();
+ });
+ }
+ }
+
+ public static void setupSPSSODescriptor(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getServiceProviderSsoDescriptor() != null) {
+ SPSSODescriptor spssoDescriptor = getSPSSODescriptorFromEntityDescriptor(ed);
+
+ spssoDescriptor.setSupportedProtocols(Collections.EMPTY_LIST);
+ if (!Strings.isNullOrEmpty(representation.getServiceProviderSsoDescriptor().getProtocolSupportEnum())) {
+ spssoDescriptor.setSupportedProtocols(
+ Arrays.stream(representation.getServiceProviderSsoDescriptor().getProtocolSupportEnum().split(",")).map(p -> MDDCConstants.PROTOCOL_BINDINGS.get(p.trim())).collect(Collectors.toList())
+ );
+ }
+
+ spssoDescriptor.getNameIDFormats().clear();
+ if (representation.getServiceProviderSsoDescriptor() != null && representation.getServiceProviderSsoDescriptor().getNameIdFormats() != null && representation.getServiceProviderSsoDescriptor().getNameIdFormats().size() > 0) {
+ for (String nameidFormat : representation.getServiceProviderSsoDescriptor().getNameIdFormats()) {
+ NameIDFormat nameIDFormat = openSamlObjects.buildDefaultInstanceOfType(NameIDFormat.class);
+
+ nameIDFormat.setFormat(nameidFormat);
+
+ spssoDescriptor.getNameIDFormats().add(nameIDFormat);
+ }
+ }
+ } else {
+ ed.setRoleDescriptors(null);
+ }
+ }
+
+ public static void setupUIInfo(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getMdui() != null) {
+ // TODO: check if we need more than a naive implementation
+ removeUIInfo(ed);
+ MduiRepresentation mduiRepresentation = representation.getMdui();
+
+ if (!Strings.isNullOrEmpty(mduiRepresentation.getDisplayName())) {
+ DisplayName displayName = openSamlObjects.buildDefaultInstanceOfType(DisplayName.class);
+ getUIInfo(ed).addDisplayName(displayName);
+ displayName.setValue(mduiRepresentation.getDisplayName());
+ displayName.setXMLLang("en");
+ } else {
+ ed.getOptionalSPSSODescriptor()
+ .flatMap(SPSSODescriptor::getOptionalExtensions)
+ .flatMap(Extensions::getOptionalUIInfo)
+ .ifPresent(u -> u.getXMLObjects().removeAll(u.getDisplayNames()));
+ }
+
+ if (!Strings.isNullOrEmpty(mduiRepresentation.getInformationUrl())) {
+ InformationURL informationURL = openSamlObjects.buildDefaultInstanceOfType(InformationURL.class);
+ getUIInfo(ed).addInformationURL(informationURL);
+ informationURL.setValue(mduiRepresentation.getInformationUrl());
+ informationURL.setXMLLang("en");
+ } else {
+ ed.getOptionalSPSSODescriptor()
+ .flatMap(SPSSODescriptor::getOptionalExtensions)
+ .flatMap(Extensions::getOptionalUIInfo)
+ .ifPresent(u -> u.getXMLObjects().removeAll(u.getInformationURLs()));
+ }
+
+ if (!Strings.isNullOrEmpty(mduiRepresentation.getPrivacyStatementUrl())) {
+ PrivacyStatementURL privacyStatementURL = openSamlObjects.buildDefaultInstanceOfType(PrivacyStatementURL.class);
+ getUIInfo(ed).addPrivacyStatementURL(privacyStatementURL);
+ privacyStatementURL.setValue(mduiRepresentation.getPrivacyStatementUrl());
+ privacyStatementURL.setXMLLang("en");
+ } else {
+ ed.getOptionalSPSSODescriptor()
+ .flatMap(SPSSODescriptor::getOptionalExtensions)
+ .flatMap(Extensions::getOptionalUIInfo)
+ .ifPresent(u -> u.getXMLObjects().removeAll(u.getPrivacyStatementURLs()));
+ }
+
+ if (!Strings.isNullOrEmpty(mduiRepresentation.getDescription())) {
+ Description description = openSamlObjects.buildDefaultInstanceOfType(Description.class);
+ getUIInfo(ed).addDescription(description);
+ description.setValue(mduiRepresentation.getDescription());
+ description.setXMLLang("en");
+ } else {
+ ed.getOptionalSPSSODescriptor()
+ .flatMap(SPSSODescriptor::getOptionalExtensions)
+ .flatMap(Extensions::getOptionalUIInfo)
+ .ifPresent(u -> u.getXMLObjects().removeAll(u.getDescriptions()));
+ }
+
+ if (!Strings.isNullOrEmpty(mduiRepresentation.getLogoUrl())) {
+ Logo logo = openSamlObjects.buildDefaultInstanceOfType(Logo.class);
+ getUIInfo(ed).addLogo(logo);
+ logo.setURL(mduiRepresentation.getLogoUrl());
+ logo.setHeight(mduiRepresentation.getLogoHeight());
+ logo.setWidth(mduiRepresentation.getLogoWidth());
+ logo.setXMLLang("en");
+ } else {
+ ed.getOptionalSPSSODescriptor()
+ .flatMap(SPSSODescriptor::getOptionalExtensions)
+ .flatMap(Extensions::getOptionalUIInfo)
+ .ifPresent(u -> u.getXMLObjects().removeAll(u.getLogos()));
+ }
+ } else {
+ removeUIInfo(ed);
+ }
+ }
+
+ public static void setupRelyingPartyOverrides(EntityDescriptor ed, EntityDescriptorRepresentation representation) {
+ if (representation.getRelyingPartyOverrides() != null || (representation.getAttributeRelease() != null && representation.getAttributeRelease().size() > 0)) {
+ // TODO: review if we need more than a naive implementation
+ getOptionalEntityAttributes(ed).ifPresent(entityAttributes -> entityAttributes.getAttributes().clear());
+ getEntityAttributes(ed).getAttributes().addAll(entityService.getAttributeListFromEntityRepresentation(representation));
+ } else {
+ getOptionalEntityAttributes(ed).ifPresent(entityAttributes -> entityAttributes.getAttributes().clear());
+ }
+ }
+}
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerTests.groovy
index 9185a973b..35c015681 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerTests.groovy
@@ -37,6 +37,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
class EntitiesControllerTests extends Specification {
+ @Autowired
+ JPAEntityDescriptorServiceImpl serviceImpl
+
+ @Autowired
+ UserService userService
+
def openSamlObjects = new OpenSamlObjects().with {
init()
it
@@ -50,9 +56,6 @@ class EntitiesControllerTests extends Specification {
initialize()
it
}
-
- @Autowired
- UserService userService
// This stub will spit out the results from the resolver instead of actually finding them in the DB
@SpringBean
@@ -62,14 +65,18 @@ class EntitiesControllerTests extends Specification {
}
@Subject
- def controller = new EntitiesController(
- openSamlObjects: openSamlObjects,
- entityDescriptorService: new JPAEntityDescriptorServiceImpl(openSamlObjects, new JPAEntityServiceImpl(openSamlObjects), userService),
- entityDescriptorRepository: edr
- )
-
- def mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
+ def controller
+ def mockMvc
+ def setup() {
+ controller = new EntitiesController()
+ controller.openSamlObjects = openSamlObjects
+ controller.entityDescriptorService = serviceImpl
+ controller.entityDescriptorRepository = edr
+
+ mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
+ }
+
def 'GET /api/entities/test'() {
when:
def result = mockMvc.perform(get("/api/entities/test"))
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy
index 03ead4284..b7822e373 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy
@@ -12,28 +12,45 @@ import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository
import edu.internet2.tier.shibboleth.admin.ui.security.model.Group
+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.GroupsRepository
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.ui.security.service.IGroupService
import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService
+import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService
import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService
+import edu.internet2.tier.shibboleth.admin.ui.service.EntityService
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator
import edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
+import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
+import org.skyscreamer.jsonassert.Customization
+import org.skyscreamer.jsonassert.JSONAssert
+import org.skyscreamer.jsonassert.JSONCompareMode
+import org.skyscreamer.jsonassert.ValueMatcher
+import org.skyscreamer.jsonassert.comparator.CustomComparator
+import org.skyscreamer.jsonassert.comparator.JSONCompareUtil
+import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.support.RootBeanDefinition
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
+import org.springframework.context.annotation.ComponentScan
import org.springframework.context.support.StaticApplicationContext
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContext
import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.test.context.support.WithMockUser
+import org.springframework.test.annotation.DirtiesContext
+import org.springframework.test.annotation.Rollback
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.client.RestTemplate
@@ -42,11 +59,14 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupp
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
import spock.lang.Ignore
+import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Subject
import java.time.LocalDateTime
+import javax.persistence.EntityManager
+
import static org.hamcrest.CoreMatchers.containsString
import static org.springframework.http.MediaType.*
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
@@ -57,14 +77,32 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
class EntityDescriptorControllerTests extends Specification {
+ @Autowired
+ EntityDescriptorRepository entityDescriptorRepository
+
+ @Autowired
+ EntityManager entityManager
+
+ @Autowired
+ EntityService entityService
+
+ @Autowired
+ RoleRepository roleRepository
+ @Autowired
+ JPAEntityDescriptorServiceImpl service
+
+ @Autowired
+ UserRepository userRepository
+
+ @Autowired
+ UserService userService
+
RandomGenerator randomGenerator
TestObjectGenerator generator
def mapper
- def service
-
- def entityDescriptorRepository = Mock(EntityDescriptorRepository)
+
def mockRestTemplate = Mock(RestTemplate)
def openSamlObjects = new OpenSamlObjects().with {
@@ -78,49 +116,63 @@ class EntityDescriptorControllerTests extends Specification {
def controller
Authentication authentication = Mock()
- SecurityContext securityContext = Mock()
- UserRepository userRepository = Mock()
- RoleRepository roleRepository = Mock()
-
- UserService userService
+ SecurityContext securityContext = Mock()
EntityDescriptorVersionService versionService = Mock()
-
IGroupService groupService = Mock()
-
+
def setup() {
generator = new TestObjectGenerator()
randomGenerator = new RandomGenerator()
mapper = new ObjectMapper()
- userService = new UserService(roleRepository, userRepository)
- service = new JPAEntityDescriptorServiceImpl(openSamlObjects, new JPAEntityServiceImpl(openSamlObjects), userService)
- service.entityDescriptorRepository = entityDescriptorRepository
+ service.userService = userService
service.groupService = groupService
controller = new EntityDescriptorController(versionService)
controller.openSamlObjects = openSamlObjects
controller.entityDescriptorService = service
-
controller.restTemplate = mockRestTemplate
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
securityContext.getAuthentication() >> authentication
SecurityContextHolder.setContext(securityContext)
- Group defGroup = new Group();
- defGroup.setResourceId("testingGroup");
- defGroup.setName("For Tests");
- defGroup.setDefaultGroup(true);
- Group.DEFAULT_GROUP = defGroup;
+
+ 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)
+ }
+ }
+
+ Optional adminRole = roleRepository.findByName("ROLE_ADMIN")
+ User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo")
+ userService.save(adminUser)
+
+ Optional userRole = roleRepository.findByName("ROLE_USER")
+ User user = new User(username: "someUser", roles:[userRole.get()], password: "foo")
+ userService.save(user)
+ entityManager.flush()
+
+ EntityDescriptorConverstionUtils.setOpenSamlObjects(openSamlObjects)
+ EntityDescriptorConverstionUtils.setEntityService(entityService)
}
-
+
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'GET /EntityDescriptors with empty repository as admin'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def emptyRecordsFromRepository = [].stream()
+ authentication.getName() >> 'admin'
+
def expectedEmptyListResponseBody = '[]'
def expectedResponseContentType = APPLICATION_JSON
def expectedHttpResponseStatus = status().isOk()
@@ -129,124 +181,49 @@ class EntityDescriptorControllerTests extends Specification {
def result = mockMvc.perform(get('/api/EntityDescriptors'))
then:
- //One call to the repo expected
- 1 * entityDescriptorRepository.findAllStreamByCustomQuery() >> emptyRecordsFromRepository
result.andExpect(expectedHttpResponseStatus)
.andExpect(content().contentType(expectedResponseContentType))
.andExpect(content().json(expectedEmptyListResponseBody))
-
}
- //todo review
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'GET /EntityDescriptors with 1 record in repository as admin'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- groupService.find("testingGroup") >> Group.DEFAULT_GROUP
- def expectedCreationDate = '2017-10-23T11:11:11'
- def entityDescriptor = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate))
- def oneRecordFromRepository = [entityDescriptor].stream()
- def version = entityDescriptor.hashCode()
- def expectedOneRecordListResponseBody = """
- [
- {
- "id": "uuid-1",
- "serviceProviderName": "sp1",
- "entityId": "eid1",
- "serviceEnabled": true,
- "createdDate": "$expectedCreationDate",
- "modifiedDate": null,
- "organization": {},
- "contacts": null,
- "serviceProviderSsoDescriptor": null,
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": null,
- "version": $version,
- "createdBy": null,
- "current": false,
- "groupId": "testingGroup"
- }
- ]
- """
-
+ authentication.getName() >> 'admin'
+ groupService.find("admingroup") >> Group.ADMIN_GROUP
+ def entityDescriptor = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true)
+ entityDescriptorRepository.save(entityDescriptor)
+ entityManager.flush()
+
def expectedResponseContentType = APPLICATION_JSON
def expectedHttpResponseStatus = status().isOk()
- when:
+ when:
def result = mockMvc.perform(get('/api/EntityDescriptors'))
- then:
- //One call to the repo expected
- 1 * entityDescriptorRepository.findAllStreamByCustomQuery() >> oneRecordFromRepository
- result.andExpect(expectedHttpResponseStatus)
- .andExpect(content().contentType(expectedResponseContentType))
- .andExpect(content().json(expectedOneRecordListResponseBody, true))
-
+ then:
+ def mvcResult = result.andExpect(expectedHttpResponseStatus).andExpect(content().contentType(expectedResponseContentType))
+ .andExpect(jsonPath("\$.[0].id").value("uuid-1"))
+ .andExpect(jsonPath("\$.[0].entityId").value("eid1"))
+ .andExpect(jsonPath("\$.[0].serviceEnabled").value(true))
+ .andExpect(jsonPath("\$.[0].groupId").value("admingroup"))
}
- //todo review
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'GET /EntityDescriptors with 2 records in repository as admin'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- groupService.find("testingGroup") >> Group.DEFAULT_GROUP
- def expectedCreationDate = '2017-10-23T11:11:11'
- def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1',
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate))
- def versionOne = entityDescriptorOne.hashCode()
- def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2',
- serviceEnabled: false,
- createdDate: LocalDateTime.parse(expectedCreationDate))
- def versionTwo = entityDescriptorTwo.hashCode()
- def twoRecordsFromRepository = [entityDescriptorOne, entityDescriptorTwo].stream()
- def expectedTwoRecordsListResponseBody = """
- [
- {
- "id": "uuid-1",
- "serviceProviderName": "sp1",
- "entityId": "eid1",
- "serviceEnabled": true,
- "createdDate": "$expectedCreationDate",
- "modifiedDate": null,
- "organization": {},
- "contacts": null,
- "serviceProviderSsoDescriptor": null,
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": null,
- "version": $versionOne,
- "createdBy": null,
- "current": false,
- "groupId": testingGroup
- },
- {
- "id": "uuid-2",
- "serviceProviderName": "sp2",
- "entityId": "eid2",
- "serviceEnabled": false,
- "createdDate": "$expectedCreationDate",
- "modifiedDate": null,
- "organization": {},
- "contacts": null,
- "serviceProviderSsoDescriptor": null,
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": null,
- "version": $versionTwo,
- "createdBy": null,
- "current": false,
- "groupId": testingGroup
- }
- ]
- """
+ authentication.getName() >> 'admin'
+ groupService.find("admingroup") >> Group.ADMIN_GROUP
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true)
+ def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false)
+
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityDescriptorRepository.save(entityDescriptorTwo)
+ entityManager.flush()
+
def expectedResponseContentType = APPLICATION_JSON
def expectedHttpResponseStatus = status().isOk()
@@ -254,35 +231,32 @@ class EntityDescriptorControllerTests extends Specification {
def result = mockMvc.perform(get('/api/EntityDescriptors'))
then:
- //One call to the repo expected
- 1 * entityDescriptorRepository.findAllStreamByCustomQuery() >> twoRecordsFromRepository
result.andExpect(expectedHttpResponseStatus)
- .andExpect(content().contentType(expectedResponseContentType))
- .andExpect(content().json(expectedTwoRecordsListResponseBody, true))
-
+ .andExpect(content().contentType(expectedResponseContentType))
+ .andExpect(jsonPath("\$.[0].id").value("uuid-1"))
+ .andExpect(jsonPath("\$.[0].entityId").value("eid1"))
+ .andExpect(jsonPath("\$.[0].serviceEnabled").value(true))
+ .andExpect(jsonPath("\$.[0].groupId").value("admingroup"))
+ .andExpect(jsonPath("\$.[1].id").value("uuid-2"))
+ .andExpect(jsonPath("\$.[1].entityId").value("eid2"))
+ .andExpect(jsonPath("\$.[1].serviceEnabled").value(false))
+ .andExpect(jsonPath("\$.[1].groupId").value("admingroup"))
}
- //todo review
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'POST /EntityDescriptor and successfully create new record'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- groupService.find(null) >> null
- def expectedCreationDate = '2017-10-23T11:11:11'
+ authentication.getName() >> 'admin'
+ groupService.find("admingroup") >> Group.ADMIN_GROUP
+
def expectedEntityId = 'https://shib'
def expectedSpName = 'sp1'
- def expectedUUID = 'uuid-1'
def expectedResponseHeader = 'Location'
- def expectedResponseHeaderValue = "/api/EntityDescriptor/$expectedUUID"
- def entityDescriptor = new EntityDescriptor(resourceId: expectedUUID, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate))
- def version = entityDescriptor.hashCode()
+ def expectedResponseHeaderValue = "/api/EntityDescriptor/"
def postedJsonBody = """
- {
+ {
"serviceProviderName": "$expectedSpName",
"entityId": "$expectedEntityId",
"organization": {},
@@ -298,56 +272,23 @@ class EntityDescriptorControllerTests extends Specification {
}
"""
- def expectedJsonBody = """
- {
- "id": "$expectedUUID",
- "serviceProviderName": "$expectedSpName",
- "entityId": "$expectedEntityId",
- "organization": {},
- "serviceEnabled": true,
- "createdDate": "$expectedCreationDate",
- "modifiedDate": null,
- "contacts": null,
- "serviceProviderSsoDescriptor": null,
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": null,
- "version": $version,
- "createdBy": null,
- "current": false,
- "groupId": "testingGroup"
- }
- """
-
when:
- def result = mockMvc.perform(
- post('/api/EntityDescriptor')
- .contentType(APPLICATION_JSON)
- .content(postedJsonBody))
+ def result = mockMvc.perform(post('/api/EntityDescriptor').contentType(APPLICATION_JSON).content(postedJsonBody))
then:
- //Stub invocation of the repository returning null for non-existent record
- 1 * entityDescriptorRepository.findByEntityID(expectedEntityId) >> null
-
- //Expect 1 invocation of repository save() with correct EntityDescriptor
- 1 * entityDescriptorRepository.save({
- it.entityID == expectedEntityId &&
- it.serviceProviderName == expectedSpName &&
- it.serviceEnabled == true
- }) >> entityDescriptor
-
result.andExpect(status().isCreated())
- .andExpect(content().json(expectedJsonBody, true))
- .andExpect(header().string(expectedResponseHeader, containsString(expectedResponseHeaderValue)))
-
+ .andExpect(header().string(expectedResponseHeader, containsString(expectedResponseHeaderValue)))
+ .andExpect(jsonPath("\$.entityId").value("https://shib"))
+ .andExpect(jsonPath("\$.serviceEnabled").value(true))
+ .andExpect(jsonPath("\$.groupId").value("admingroup"))
}
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
def 'POST /EntityDescriptor as user disallows enabling'() {
given:
- def username = 'someUser'
- def role = 'ROLE_USER'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
+ authentication.getName() >> 'someUser'
+
def expectedEntityId = 'https://shib'
def expectedSpName = 'sp1'
@@ -381,17 +322,16 @@ class EntityDescriptorControllerTests extends Specification {
}
}
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'POST /EntityDescriptor record already exists'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def expectedEntityId = 'eid1'
+ authentication.getName() >> 'admin'
+
def postedJsonBody = """
{
"serviceProviderName": "sp1",
- "entityId": "$expectedEntityId",
+ "entityId": "eid1",
"organization": null,
"serviceEnabled": true,
"createdDate": null,
@@ -409,9 +349,13 @@ class EntityDescriptorControllerTests extends Specification {
"""
when:
- //Stub invocation of the repository returning an existing record
- 1 * entityDescriptorRepository.findByEntityID(expectedEntityId) >> new EntityDescriptor(entityID: expectedEntityId)
-
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true)
+ def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false)
+
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityDescriptorRepository.save(entityDescriptorTwo)
+ entityManager.flush()
+
then:
try {
def exceptionExpected = mockMvc.perform(post('/api/EntityDescriptor').contentType(APPLICATION_JSON).content(postedJsonBody))
@@ -420,251 +364,152 @@ class EntityDescriptorControllerTests extends Specification {
e instanceof EntityIdExistsException == true
}
}
-
+
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'GET /EntityDescriptor/{resourceId} non-existent'() {
- given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def providedResourceId = 'uuid-1'
-
when:
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> null
+ authentication.getName() >> 'admin'
then:
try {
- def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId"))
+ def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/uuid-1"))
}
catch (Exception e) {
e instanceof EntityNotFoundException == true
}
}
- //todo review
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'GET /EntityDescriptor/{resourceId} existing'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- groupService.find(null) >> null
- def expectedCreationDate = '2017-10-23T11:11:11'
- def providedResourceId = 'uuid-1'
- def expectedSpName = 'sp1'
- def expectedEntityId = 'eid1'
-
- def entityDescriptor = new EntityDescriptor(resourceId: providedResourceId, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate))
- def version = entityDescriptor.hashCode()
-
- def expectedJsonBody = """
- {
- "id": "${providedResourceId}",
- "serviceProviderName": "$expectedSpName",
- "entityId": "$expectedEntityId",
- "organization": {},
- "serviceEnabled": true,
- "createdDate": "$expectedCreationDate",
- "modifiedDate": null,
- "contacts": null,
- "serviceProviderSsoDescriptor": null,
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": null,
- "version": $version,
- "createdBy": null,
- "current": false,
- "groupId": "testingGroup"
- }
- """
-
+ authentication.getName() >> 'admin'
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true)
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
+
when:
- def result = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId"))
-
+ def result = mockMvc.perform(get("/api/EntityDescriptor/uuid-1"))
+
then:
- //EntityDescriptor found
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> entityDescriptor
-
-
result.andExpect(status().isOk())
- .andExpect(content().json(expectedJsonBody, true))
+ .andExpect(jsonPath("\$.entityId").value("eid1"))
+ .andExpect(jsonPath("\$.serviceProviderName").value("sp1"))
+ .andExpect(jsonPath("\$.serviceEnabled").value(true))
+ .andExpect(jsonPath("\$.groupId").value("admingroup"))
}
-
- //todo review
- def 'GET /EntityDescriptor/{resourceId} existing, owned by non-admin'() {
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
+ def 'GET /EntityDescriptor/{resourceId} existing, validate group access'() {
given:
- def username = 'someUser'
- def role = 'ROLE_USER'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- groupService.find(null) >> null
- def expectedCreationDate = '2017-10-23T11:11:11'
- def providedResourceId = 'uuid-1'
- def expectedSpName = 'sp1'
- def expectedEntityId = 'eid1'
-
- def entityDescriptor = new EntityDescriptor(resourceId: providedResourceId, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate),
- createdBy: 'someUser')
- def version = entityDescriptor.hashCode()
-
- def expectedJsonBody = """
- {
- "id": "${providedResourceId}",
- "serviceProviderName": "$expectedSpName",
- "entityId": "$expectedEntityId",
- "organization": {},
- "serviceEnabled": true,
- "createdDate": "$expectedCreationDate",
- "modifiedDate": null,
- "contacts": null,
- "serviceProviderSsoDescriptor": null,
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": null,
- "version": $version,
- "createdBy": "someUser",
- "current": false,
- "groupId": "testingGroup"
- }
- """
-
+ authentication.getName() >> 'someUser'
+ Group g = userService.getCurrentUserGroup()
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, group: g)
+ def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false, group: Group.ADMIN_GROUP)
+
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityDescriptorRepository.save(entityDescriptorTwo)
+ entityManager.flush()
+
when:
- def result = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId"))
+ def result = mockMvc.perform(get("/api/EntityDescriptor/uuid-1"))
then:
- //EntityDescriptor found
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> entityDescriptor
-
-
- result.andExpect(status().isOk()).andExpect(content().json(expectedJsonBody, true))
+ result.andExpect(status().isOk())
+ .andExpect(jsonPath("\$.entityId").value("eid1"))
+ .andExpect(jsonPath("\$.serviceProviderName").value("sp1"))
+ .andExpect(jsonPath("\$.serviceEnabled").value(true))
+ .andExpect(jsonPath("\$.groupId").value("someUser"))
}
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
def 'GET /EntityDescriptor/{resourceId} existing, owned by some other user'() {
- given:
- def username = 'someUser'
- def role = 'ROLE_USER'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def expectedCreationDate = '2017-10-23T11:11:11'
- def providedResourceId = 'uuid-1'
- def expectedSpName = 'sp1'
- def expectedEntityId = 'eid1'
-
- def entityDescriptor = new EntityDescriptor(resourceId: providedResourceId, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate),
- createdBy: 'someOtherUser')
-
when:
- //EntityDescriptor found
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> entityDescriptor
+ authentication.getName() >> 'someUser'
+ Group g = userService.getCurrentUserGroup()
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, group: g)
+ def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false, group: Group.ADMIN_GROUP)
+
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityDescriptorRepository.save(entityDescriptorTwo)
+ entityManager.flush()
then:
try {
- def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId"))
+ def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/uuid-2"))
}
catch (Exception e) {
e instanceof ForbiddenException == true
}
}
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def 'GET /EntityDescriptor/{resourceId} existing (xml)'() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def expectedCreationDate = '2017-10-23T11:11:11'
- def providedResourceId = 'uuid-1'
- def expectedSpName = 'sp1'
- def expectedEntityId = 'eid1'
-
- def entityDescriptor = new EntityDescriptor(resourceId: providedResourceId, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate))
- entityDescriptor.setElementLocalName("EntityDescriptor")
- entityDescriptor.setNamespacePrefix("md")
- entityDescriptor.setNamespaceURI("urn:oasis:names:tc:SAML:2.0:metadata")
+ authentication.getName() >> 'admin'
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true)
+ entityDescriptorOne.setElementLocalName("EntityDescriptor")
+ entityDescriptorOne.setNamespacePrefix("md")
+ entityDescriptorOne.setNamespaceURI("urn:oasis:names:tc:SAML:2.0:metadata")
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
def expectedXML = """
"""
+ xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="eid1"/>"""
when:
- def result = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId")
- .accept(APPLICATION_XML))
+ def result = mockMvc.perform(get("/api/EntityDescriptor/uuid-1").accept(APPLICATION_XML))
then:
- //EntityDescriptor found
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> entityDescriptor
-
-
- result.andExpect(status().isOk())
- .andExpect(content().xml(expectedXML))
+ result.andExpect(status().isOk()).andExpect(content().xml(expectedXML))
}
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
def 'GET /EntityDescriptor/{resourceId} existing (xml), user-owned'() {
given:
- def username = 'someUser'
- def role = 'ROLE_USER'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def expectedCreationDate = '2017-10-23T11:11:11'
- def providedResourceId = 'uuid-1'
- def expectedSpName = 'sp1'
- def expectedEntityId = 'eid1'
-
- def entityDescriptor = new EntityDescriptor(resourceId: providedResourceId, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate),
- createdBy: 'someUser')
- entityDescriptor.setElementLocalName("EntityDescriptor")
- entityDescriptor.setNamespacePrefix("md")
- entityDescriptor.setNamespaceURI("urn:oasis:names:tc:SAML:2.0:metadata")
- entityDescriptor.setGroup(Group.DEFAULT_GROUP)
+ authentication.getName() >> 'someUser'
+ Group g = userService.getCurrentUserGroup()
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, group: g)
+ entityDescriptorOne.setElementLocalName("EntityDescriptor")
+ entityDescriptorOne.setNamespacePrefix("md")
+ entityDescriptorOne.setNamespaceURI("urn:oasis:names:tc:SAML:2.0:metadata")
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
def expectedXML = """
"""
+ xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="eid1"/>"""
when:
- def result = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId").accept(APPLICATION_XML))
+ def result = mockMvc.perform(get("/api/EntityDescriptor/uuid-1").accept(APPLICATION_XML))
then:
- //EntityDescriptor found
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> entityDescriptor
-
result.andExpect(status().isOk()).andExpect(content().xml(expectedXML))
- }
+ }
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
def 'GET /EntityDescriptor/{resourceId} existing (xml), other user-owned'() {
- given:
- def username = 'someUser'
- def role = 'ROLE_USER'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def expectedCreationDate = '2017-10-23T11:11:11'
- def providedResourceId = 'uuid-1'
- def expectedSpName = 'sp1'
- def expectedEntityId = 'eid1'
-
- def entityDescriptor = new EntityDescriptor(resourceId: providedResourceId, entityID: expectedEntityId, serviceProviderName: expectedSpName,
- serviceEnabled: true,
- createdDate: LocalDateTime.parse(expectedCreationDate),
- createdBy: 'someOtherUser')
- entityDescriptor.setElementLocalName("EntityDescriptor")
- entityDescriptor.setNamespacePrefix("md")
- entityDescriptor.setNamespaceURI("urn:oasis:names:tc:SAML:2.0:metadata")
-
when:
- //EntityDescriptor found
- 1 * entityDescriptorRepository.findByResourceId(providedResourceId) >> entityDescriptor
-
+ authentication.getName() >> 'someUser'
+ Group g = Group.ADMIN_GROUP
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, group: g)
+ entityDescriptorOne.setElementLocalName("EntityDescriptor")
+ entityDescriptorOne.setNamespacePrefix("md")
+ entityDescriptorOne.setNamespaceURI("urn:oasis:names:tc:SAML:2.0:metadata")
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
+
then:
try {
def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId").accept(APPLICATION_XML))
@@ -674,14 +519,13 @@ class EntityDescriptorControllerTests extends Specification {
}
}
-
- //todo review
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def "POST /EntityDescriptor handles XML happily"() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
+ authentication.getName() >> 'admin'
+ groupService.find("admingroup") >> Group.ADMIN_GROUP
+
def postedBody = '''
@@ -701,62 +545,32 @@ class EntityDescriptorControllerTests extends Specification {
'''
- def spName = randomGenerator.randomString()
-
- def expectedEntityDescriptor = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(postedBody.bytes))
-
- 1 * entityDescriptorRepository.findByEntityID(_) >> null
- 1 * entityDescriptorRepository.save(_) >> expectedEntityDescriptor
-
- def expectedJson = """
-{
- "version": ${expectedEntityDescriptor.hashCode()},
- "id": "${expectedEntityDescriptor.resourceId}",
- "serviceProviderName": null,
- "entityId": "http://test.scaldingspoon.org/test1",
- "organization": {},
- "contacts": null,
- "serviceProviderSsoDescriptor": {
- "protocolSupportEnum": "SAML 2",
- "nameIdFormats": [
- "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
- ]
- },
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": [
- {
- "locationUrl": "https://test.scaldingspoon.org/test1/acs",
- "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
- "makeDefault": false
- }
- ],
- "serviceEnabled": false,
- "createdDate": null,
- "modifiedDate": null,
- "attributeRelease": [
- "givenName",
- "employeeNumber"
- ],
- "createdBy": null,
- "current": false
-}
-"""
+ def expectedResponseHeader = 'Location'
+ def expectedResponseHeaderValue = "/api/EntityDescriptor/"
when:
- def result = mockMvc.perform(post("/api/EntityDescriptor")
- .contentType(APPLICATION_XML)
- .content(postedBody)
- .param("spName", spName))
-
+ def spName = randomGenerator.randomString()
+ def result = mockMvc.perform(post("/api/EntityDescriptor").contentType(APPLICATION_XML).content(postedBody).param("spName", spName))
then:
result.andExpect(status().isCreated())
- .andExpect(content().json(expectedJson, false))
+ .andExpect(header().string(expectedResponseHeader, containsString(expectedResponseHeaderValue)))
+ .andExpect(jsonPath("\$.entityId").value("http://test.scaldingspoon.org/test1"))
+ .andExpect(jsonPath("\$.serviceEnabled").value(false))
+ .andExpect(jsonPath("\$.groupId").value("admingroup"))
+ .andExpect(jsonPath("\$.serviceProviderSsoDescriptor.protocolSupportEnum").value("SAML 2"))
+ .andExpect(jsonPath("\$.serviceProviderSsoDescriptor.nameIdFormats[0]").value("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"))
+ .andExpect(jsonPath("\$.assertionConsumerServices[0].binding").value("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"))
+ .andExpect(jsonPath("\$.assertionConsumerServices[0].makeDefault").value(false))
+ .andExpect(jsonPath("\$.assertionConsumerServices[0].locationUrl").value("https://test.scaldingspoon.org/test1/acs"))
+
}
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def "POST /EntityDescriptor returns error for duplicate entity id"() {
- given:
+ when:
+ authentication.getName() >> 'admin'
def postedBody = '''
@@ -777,13 +591,13 @@ class EntityDescriptorControllerTests extends Specification {
'''
def spName = randomGenerator.randomString()
-
- def expectedEntityDescriptor = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(postedBody.bytes))
- 0 * entityDescriptorRepository.save(_)
-
- when:
- 1 * entityDescriptorRepository.findByEntityID(expectedEntityDescriptor.entityID) >> expectedEntityDescriptor
-
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true)
+ def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'http://test.scaldingspoon.org/test1', serviceProviderName: 'sp2', serviceEnabled: false)
+
+ entityDescriptorRepository.save(entityDescriptorOne)
+ entityDescriptorRepository.save(entityDescriptorTwo)
+ entityManager.flush()
+
then:
try {
def exceptionExpected = mockMvc.perform(post("/api/EntityDescriptor").contentType(APPLICATION_XML).content(postedBody).param("spName", spName))
@@ -793,196 +607,104 @@ class EntityDescriptorControllerTests extends Specification {
}
}
- @Ignore("until we handle the workaround for SHIBUI-1237")
- def "POST /EntityDescriptor handles x-www-form-urlencoded happily"() {
- given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def postedMetadataUrl = "http://test.scaldingspoon.org/test1"
- def restXml = '''
-
-
-
-
- internal
-
-
- givenName
- employeeNumber
-
-
-
-
- urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
-
-
-
-'''
-
- def spName = randomGenerator.randomString()
-
- def expectedEntityDescriptor = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(restXml.bytes))
-
- 1 * mockRestTemplate.getForObject(_, _) >> restXml.bytes
- 1 * entityDescriptorRepository.findByEntityID(_) >> null
- 1 * entityDescriptorRepository.save(_) >> expectedEntityDescriptor
-
- def expectedJson = """
-{
- "version": ${expectedEntityDescriptor.hashCode()},
- "id": "${expectedEntityDescriptor.resourceId}",
- "serviceProviderName": null,
- "entityId": "http://test.scaldingspoon.org/test1",
- "organization": null,
- "contacts": null,
- "mdui": null,
- "serviceProviderSsoDescriptor": {
- "protocolSupportEnum": "SAML 2",
- "nameIdFormats": [
- "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
- ]
- },
- "logoutEndpoints": null,
- "securityInfo": null,
- "assertionConsumerServices": [
- {
- "locationUrl": "https://test.scaldingspoon.org/test1/acs",
- "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
- "makeDefault": false
- }
- ],
- "serviceEnabled": false,
- "createdDate": null,
- "modifiedDate": null,
- "relyingPartyOverrides": {},
- "attributeRelease": [
- "givenName",
- "employeeNumber"
- ],
- "createdBy": null
-}
-"""
-
- when:
- def result = mockMvc.perform(post("/api/EntityDescriptor")
- .contentType(APPLICATION_FORM_URLENCODED)
- .param("metadataUrl", postedMetadataUrl)
- .param("spName", spName))
-
-
- then:
- result.andExpect(status().isCreated())
- .andExpect(content().json(expectedJson, true))
- }
-
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def "PUT /EntityDescriptor updates entity descriptors properly as admin"() {
given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- groupService.find(null) >> null
- def entityDescriptor = generator.buildEntityDescriptor()
- def updatedEntityDescriptor = generator.buildEntityDescriptor()
- updatedEntityDescriptor.resourceId = entityDescriptor.resourceId
- def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(updatedEntityDescriptor)
- updatedEntityDescriptorRepresentation.version = entityDescriptor.hashCode()
- def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
-
- def resourceId = entityDescriptor.resourceId
-
- 1 * entityDescriptorRepository.findByResourceId(resourceId) >> entityDescriptor
- 1 * entityDescriptorRepository.save(_) >> updatedEntityDescriptor
+ authentication.getName() >> 'admin'
+
+ def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false, group: Group.ADMIN_GROUP)
+
+ entityDescriptorTwo = entityDescriptorRepository.save(entityDescriptorTwo)
+ entityManager.flush()
+ entityManager.clear()
+ def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorTwo)
+ updatedEntityDescriptorRepresentation.setServiceProviderName("newName")
+ def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
+
when:
- def result = mockMvc.perform(
- put("/api/EntityDescriptor/$resourceId")
- .contentType(APPLICATION_JSON)
- .content(postedJsonBody))
+ def result = mockMvc.perform(put("/api/EntityDescriptor/uuid-2").contentType(APPLICATION_JSON).content(postedJsonBody))
then:
- def expectedJson = new JsonSlurper().parseText(postedJsonBody)
- expectedJson << [version: updatedEntityDescriptor.hashCode()]
result.andExpect(status().isOk())
- .andExpect(content().json(JsonOutput.toJson(expectedJson), true))
+ .andExpect(jsonPath("\$.entityId").value("eid2"))
+ .andExpect(jsonPath("\$.serviceEnabled").value(false))
+ .andExpect(jsonPath("\$.groupId").value("admingroup"))
+ .andExpect(jsonPath("\$.serviceProviderName").value("newName"))
}
- def "PUT /EntityDescriptor disallows user from enabling"() {
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
+ def "PUT /EntityDescriptor disallows non-admin user from enabling"() {
given:
- def username = 'someUser'
- def role = 'ROLE_USER'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def entityDescriptor = generator.buildEntityDescriptor()
- entityDescriptor.serviceEnabled = false
- def updatedEntityDescriptor = generator.buildEntityDescriptor()
- updatedEntityDescriptor.serviceEnabled = true
- updatedEntityDescriptor.resourceId = entityDescriptor.resourceId
- def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(updatedEntityDescriptor)
- updatedEntityDescriptorRepresentation.version = entityDescriptor.hashCode()
- def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
-
- def resourceId = entityDescriptor.resourceId
- 0 * entityDescriptorRepository.save(_) >> updatedEntityDescriptor
+ authentication.getName() >> 'someUser'
+ Group g = userService.getCurrentUserGroup()
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: false, group: g)
+ entityDescriptorOne = entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
when:
- 1 * entityDescriptorRepository.findByResourceId(resourceId) >> entityDescriptor
+ entityDescriptorOne.serviceEnabled = true
+ entityDescriptorOne.resourceId = 'uuid-1'
+ def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorOne)
+ updatedEntityDescriptorRepresentation.version = entityDescriptorOne.hashCode()
+ def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
then:
try {
- def exceptionExpected = mockMvc.perform(put("/api/EntityDescriptor/$resourceId").contentType(APPLICATION_JSON).content(postedJsonBody))
+ def exceptionExpected = mockMvc.perform(put("/api/EntityDescriptor/uuid-1").contentType(APPLICATION_JSON).content(postedJsonBody))
}
catch (Exception e) {
e instanceof ForbiddenException == true
}
}
- def "PUT /EntityDescriptor denies the request if the PUTing user is not an ADMIN and not the createdBy user"() {
+ @Rollback
+ @WithMockUser(value = "someUser", roles = ["USER"])
+ def "PUT /EntityDescriptor denies the request if the PUTing user is not an ADMIN and not the createdBy user"() {
given:
- def username = 'someUser'
- def role = 'ROLE_USERN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def entityDescriptor = generator.buildEntityDescriptor()
- entityDescriptor.createdBy = 'someoneElse'
- def updatedEntityDescriptor = generator.buildEntityDescriptor()
- updatedEntityDescriptor.createdBy = 'someoneElse'
- updatedEntityDescriptor.resourceId = entityDescriptor.resourceId
- def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(updatedEntityDescriptor)
- def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
- def resourceId = entityDescriptor.resourceId
-
+ authentication.getName() >> 'someUser'
+ Group g = userService.getCurrentUserGroup()
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, group: g)
+ entityDescriptorOne = entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
+
when:
- 1 * entityDescriptorRepository.findByResourceId(resourceId) >> entityDescriptor
+ entityDescriptorOne.serviceProviderName = 'foo'
+ entityDescriptorOne.resourceId = 'uuid-1'
+ def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorOne)
+ updatedEntityDescriptorRepresentation.version = entityDescriptorOne.hashCode()
+ def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
then:
try {
- def exceptionExpected = mockMvc.perform(put("/api/EntityDescriptor/$resourceId").contentType(APPLICATION_JSON).content(postedJsonBody))
+ def exceptionExpected = mockMvc.perform(put("/api/EntityDescriptor/uuid-1").contentType(APPLICATION_JSON).content(postedJsonBody))
}
catch (Exception e) {
e instanceof ForbiddenException == true
}
}
+ @Rollback
+ @WithMockUser(value = "admin", roles = ["ADMIN"])
def "PUT /EntityDescriptor throws a concurrent mod exception if the version numbers don't match"() {
- given:
- def username = 'admin'
- def role = 'ROLE_ADMIN'
- authentication.getName() >> username
- userRepository.findByUsername(username) >> TestHelpers.generateOptionalUser(username, role)
- def entityDescriptor = generator.buildEntityDescriptor()
- def updatedEntityDescriptor = generator.buildEntityDescriptor()
- updatedEntityDescriptor.resourceId = entityDescriptor.resourceId
- def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(updatedEntityDescriptor)
- def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
-
- def resourceId = entityDescriptor.resourceId
+ given:
+ authentication.getName() >> 'admin'
+
+ def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, group: Group.ADMIN_GROUP)
+ entityDescriptorOne = entityDescriptorRepository.save(entityDescriptorOne)
+ entityManager.flush()
when:
- 1 * entityDescriptorRepository.findByResourceId(resourceId) >> entityDescriptor
-
+ entityDescriptorOne.serviceProviderName = 'foo'
+ entityDescriptorOne.resourceId = 'uuid-1'
+ def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorOne)
+
+ def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation)
+
then:
try {
def exception = mockMvc.perform(put("/api/EntityDescriptor/$resourceId").contentType(APPLICATION_JSON).content(postedJsonBody))
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy
index bfeacf55d..3fb7a3f21 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy
@@ -12,6 +12,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository
import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService
import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionServiceImpl
+import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl
import org.apache.lucene.analysis.Analyzer
@@ -22,6 +23,7 @@ import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.ComponentScan
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
@@ -63,7 +65,8 @@ class EntityDescriptorRepositoryTest extends Specification {
it
}
- def service = new JPAEntityDescriptorServiceImpl(openSamlObjects, new JPAEntityServiceImpl(openSamlObjects), new UserService(roleRepository, userRepository))
+ @Autowired
+ EntityDescriptorService service
def "SHIBUI-553.2"() {
when:
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy
index a0ba13aca..99ff22481 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy
@@ -10,10 +10,8 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetada
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver
-import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
-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.ui.security.service.UserService
+import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl
import org.springframework.beans.factory.annotation.Autowired
@@ -44,15 +42,7 @@ class MetadataResolverRepositoryTests extends Specification {
EntityManager entityManager
@Autowired
- OpenSamlObjects openSamlObjects
-
- @Autowired
- RoleRepository roleRepository
-
- @Autowired
- UserRepository userRepository
-
- def service = new JPAEntityDescriptorServiceImpl(openSamlObjects, new JPAEntityServiceImpl(openSamlObjects), new UserService(roleRepository, userRepository))
+ EntityDescriptorService service
def "test persisting a metadata resolver"() {
when:
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/scheduled/EntityDescriptorFilesScheduledTasksTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/scheduled/EntityDescriptorFilesScheduledTasksTests.groovy
index 7402cb098..19d0e4689 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/scheduled/EntityDescriptorFilesScheduledTasksTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/scheduled/EntityDescriptorFilesScheduledTasksTests.groovy
@@ -16,6 +16,8 @@ import edu.internet2.tier.shibboleth.admin.ui.service.FileCheckingFileWritingSer
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl
import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator
+import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils
+
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
@@ -34,38 +36,36 @@ import spock.lang.Specification
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
class EntityDescriptorFilesScheduledTasksTests extends Specification {
+ @Autowired
+ OpenSamlObjects openSamlObjects
+
+ @Autowired
+ IGroupService groupService
+
def tempPath = "/tmp/shibui"
def directory
- @Autowired
- OpenSamlObjects openSamlObjects
-
def entityDescriptorRepository = Mock(EntityDescriptorRepository)
def entityDescriptorFilesScheduledTasks
- def service
-
def randomGenerator
-
- @Autowired
- RoleRepository roleRepository
-
- @Autowired
- UserRepository userRepository
-
- @Autowired
- IGroupService groupService
+
+
+ def service
def setup() {
randomGenerator = new RandomGenerator()
tempPath = tempPath + randomGenerator.randomRangeInt(10000, 20000)
- service = new JPAEntityDescriptorServiceImpl(openSamlObjects, new JPAEntityServiceImpl(openSamlObjects), new UserService(roleRepository, userRepository))
- service.groupService = groupService
+ EntityDescriptorConverstionUtils.setOpenSamlObjects(openSamlObjects)
entityDescriptorFilesScheduledTasks = new EntityDescriptorFilesScheduledTasks(tempPath, entityDescriptorRepository, openSamlObjects, new FileCheckingFileWritingService())
directory = new File(tempPath)
directory.mkdir()
+
+ service = new JPAEntityDescriptorServiceImpl()
+ service.openSamlObjects = openSamlObjects
+ service.groupService = groupService
}
def "generateEntityDescriptorFiles properly generates a file from an Entity Descriptor"() {
@@ -127,7 +127,7 @@ class EntityDescriptorFilesScheduledTasksTests extends Specification {
http://test.example.org
- '''
+ '''
def entityDescriptor = service.createDescriptorFromRepresentation(new EntityDescriptorRepresentation().with {
it.entityId = 'http://test.example.org/test1'
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryIntegrationTests.groovy
index 02fde7269..eeae13328 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryIntegrationTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryIntegrationTests.groovy
@@ -5,6 +5,8 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.JsonSchemaComponents
import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor
import edu.internet2.tier.shibboleth.admin.ui.jsonschema.LowLevelJsonSchemaValidator
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
+import edu.internet2.tier.shibboleth.admin.ui.security.model.Group
+
import org.springframework.core.io.DefaultResourceLoader
import org.springframework.core.io.ResourceLoader
import org.springframework.mock.http.MockHttpInputMessage
@@ -14,31 +16,33 @@ import spock.lang.Specification
import java.time.LocalDateTime
class AuxiliaryIntegrationTests extends Specification {
- @Shared
OpenSamlObjects openSamlObjects = new OpenSamlObjects().with {
it.init()
it
}
- @Shared
- EntityDescriptorService entityDescriptorService
-
- @Shared
+ JPAEntityDescriptorServiceImpl entityDescriptorService
ObjectMapper objectMapper
-
- @Shared
ResourceLoader resourceLoader
void setup() {
- this.entityDescriptorService = new JPAEntityDescriptorServiceImpl(openSamlObjects, null, null)
- this.objectMapper = new ObjectMapper()
- this.resourceLoader = new DefaultResourceLoader()
+ entityDescriptorService = new JPAEntityDescriptorServiceImpl()
+ entityDescriptorService.openSamlObjects = openSamlObjects
+ objectMapper = new ObjectMapper()
+ resourceLoader = new DefaultResourceLoader()
}
def "SHIBUI-1723: after enabling saved entity descriptor, it should still have valid xml"() {
given:
+ def group = new Group().with {
+ it.name = "foo"
+ it.resourceId = "foo"
+ it
+ }
def entityDescriptor = openSamlObjects.unmarshalFromXml(this.class.getResource('/metadata/SHIBUI-1723-1.xml').bytes) as EntityDescriptor
- def entityDescriptorRepresentation = this.entityDescriptorService.createRepresentationFromDescriptor(entityDescriptor).with {
+ entityDescriptor.group = group
+
+ def entityDescriptorRepresentation = entityDescriptorService.createRepresentationFromDescriptor(entityDescriptor).with {
it.serviceProviderName = 'testme'
it.contacts = []
it.securityInfo.x509Certificates[0].name = 'testcert'
@@ -47,7 +51,7 @@ class AuxiliaryIntegrationTests extends Specification {
it.setModifiedDate(LocalDateTime.now())
it
}
- def json = this.objectMapper.writeValueAsString(entityDescriptorRepresentation)
+ def json = objectMapper.writeValueAsString(entityDescriptorRepresentation)
def schemaUri = edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.metadataSourcesSchema(new JsonSchemaComponentsConfiguration().jsonSchemaResourceLocationRegistry(this.resourceLoader, this.objectMapper)).uri
when:
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy
index 11da9c2ef..4ec0b37b8 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy
@@ -27,12 +27,15 @@ import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService
import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
import edu.internet2.tier.shibboleth.admin.util.AttributeUtility
+import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils
+
import org.opensaml.saml.ext.saml2mdattr.EntityAttributes
import org.skyscreamer.jsonassert.JSONAssert
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.json.JacksonTester
import org.springframework.context.annotation.PropertySource
+import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import org.xmlunit.builder.DiffBuilder
import org.xmlunit.builder.Input
@@ -43,47 +46,34 @@ import spock.lang.Specification
@ContextConfiguration(classes=[CoreShibUiConfiguration, CustomPropertiesConfiguration])
@SpringBootTest(classes = ShibbolethUiApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@PropertySource("classpath:application.yml")
-class JPAEntityDescriptorServiceImplTests extends Specification {
-
+@DirtiesContext
+class JPAEntityDescriptorServiceImplTests extends Specification {
+ @Autowired
+ EntityService entityService;
+
@Autowired
- CustomPropertiesConfiguration customPropertiesConfiguration
+ JPAEntityDescriptorServiceImpl service
def testObjectGenerator
-
+
OpenSamlObjects openSamlObjects = new OpenSamlObjects().with {
init()
it
}
-
- JPAEntityDescriptorServiceImpl service
-
+
JacksonTester jacksonTester
-
ObjectMapper mapper
-
RandomGenerator generator
-
- @Autowired
- RoleRepository roleRepository
-
- @Autowired
- UserRepository userRepository
-
- @Autowired
- IGroupService groupService
- def setup() {
- service = new JPAEntityDescriptorServiceImpl(openSamlObjects,
- new JPAEntityServiceImpl(openSamlObjects, new AttributeUtility(openSamlObjects), customPropertiesConfiguration), new UserService(roleRepository, userRepository))
- service.groupService = groupService
+ def setup() {
mapper = new ObjectMapper()
JacksonTester.initFields(this, mapper)
generator = new RandomGenerator()
testObjectGenerator = new TestObjectGenerator()
+ EntityDescriptorConverstionUtils.openSamlObjects = openSamlObjects
+ EntityDescriptorConverstionUtils.entityService = entityService
}
-
-
def "simple Entity Descriptor"() {
when:
def expected = ''' adminRole = roleRepository.findByName("ROLE_ADMIN")
+ User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo")
+ userService.save(adminUser)
- User u = new User()
- u.setUsername("foo")
- u.setGroup(gb)
- u.setPassword("pass")
- userRepository.save(u)
+ Optional userRole = roleRepository.findByName("ROLE_USER")
+ User user = new User(username: "someUser", roles:[userRole.get()], password: "foo", group: gb)
+ userService.save(user)
}
- @WithMockUser(value = "foo", roles = ["USER"])
+ @WithMockUser(value = "someUser", roles = ["USER"])
+ @Rollback
def "When creating Entity Descriptor, ED is assigned to the user's group"() {
given:
User current = userService.getCurrentUser()
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy
index 0a5db2bcf..8360bf8d5 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy
@@ -34,6 +34,10 @@ class UserBootstrapTests extends Specification {
@Autowired
RoleRepository roleRepository
+ def setup() {
+ roleRepository.deleteAll();
+ }
+
def "simple test"() {
setup:
shibUIConfiguration.roles = []
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/EntityDescriptorConversionUtilsTests.groovy
similarity index 94%
rename from backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy
rename to backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/EntityDescriptorConversionUtilsTests.groovy
index f78f8d354..03bbefd77 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/EntityDescriptorConversionUtilsTests.groovy
@@ -1,4 +1,7 @@
-package edu.internet2.tier.shibboleth.admin.ui.service
+package edu.internet2.tier.shibboleth.admin.ui.util
+
+import org.opensaml.saml.common.xml.SAMLConstants
+import org.opensaml.saml.saml2.metadata.ContactPersonTypeEnumeration
import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPerson
import edu.internet2.tier.shibboleth.admin.ui.domain.Description
@@ -22,63 +25,31 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.MduiRepresentation
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ServiceProviderSsoDescriptorRepresentation
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
-import org.opensaml.saml.common.xml.SAMLConstants
-import org.opensaml.saml.saml2.metadata.ContactPersonTypeEnumeration
+import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConverstionUtils
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll
-class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
- @Shared
- OpenSamlObjects openSAMLObjects = new OpenSamlObjects().with {
- it.init()
- it
- }
+class EntityDescriptorConversionUtilsTests extends Specification {
@Shared
- JPAEntityDescriptorServiceImpl entityDescriptorService
-
- void setup() {
- entityDescriptorService = new JPAEntityDescriptorServiceImpl(openSAMLObjects, null, null)
- }
-
- def "simple test"() {
- assert true
- }
-
- // this is a stub to build out the DataFields
- def "pretest"() {
- given:
- def dataField = new Data.DataField(
- method: 'setupLogout',
- description: 'no change',
- representation: new EntityDescriptorRepresentation(),
- starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class),
- expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class)
- )
-
- when:
- def (expected, starter) = [dataField.expected, dataField.starter]
- expected.setResourceId(starter.getResourceId())
- entityDescriptorService."${dataField.method}"(starter, dataField.representation)
-
- then:
- assert expected == starter
- }
-
- @Unroll
- def "test #method(#description)"() {
- setup:
- expected.setResourceId(starter.getResourceId())
- entityDescriptorService."$method"(starter, representation)
+ def OpenSamlObjects openSAMLObjects
+
+ @Shared
+ def EntityDescriptorConverstionUtils utilsUnderTest
- expect:
- assert starter == expected
+ def setup() {
+ openSAMLObjects = new OpenSamlObjects().with {
+ it.init()
+ it
+ }
- where:
- [method, description, representation, starter, expected] << Data.getData(openSAMLObjects)
+ utilsUnderTest = new EntityDescriptorConverstionUtils().with {
+ it.openSamlObjects = openSAMLObjects
+ it
+ }
}
-
+
def "test createKeyDescriptor, single type"() {
given:
def expectedXml = '''
@@ -92,12 +63,12 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
expected.name = 'testName'
when:
- def keyDescriptor = entityDescriptorService.createKeyDescriptor('testName', 'signing', 'testValue')
+ def keyDescriptor = EntityDescriptorConverstionUtils.createKeyDescriptor('testName', 'signing', 'testValue')
then:
assert keyDescriptor == expected
}
-
+
def "test createKeyDescriptor, both type"() {
given:
def expectedXml = '''
@@ -111,7 +82,7 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
expected.name = 'testName'
when:
- def keyDescriptor = entityDescriptorService.createKeyDescriptor('testName', 'both', 'testValue')
+ def keyDescriptor = EntityDescriptorConverstionUtils.createKeyDescriptor('testName', 'both', 'testValue')
def x = openSAMLObjects.marshalToXmlString(keyDescriptor)
then:
assert keyDescriptor == expected
@@ -119,16 +90,28 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
def 'test createKeyDescriptor equality'() {
when:
- def key1 = entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')
- def key2 = entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')
+ def key1 = EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test')
+ def key2 = EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test')
then:
assert key1.equals(key2)
}
+
+ @Unroll
+ def "test #method(#description)"() {
+ setup:
+ expected.setResourceId(starter.getResourceId())
+ EntityDescriptorConverstionUtils."$method"(starter, representation)
+
+ expect:
+ assert starter == expected
+
+ where:
+ [method, description, representation, starter, expected] << Data.getData(openSAMLObjects)
+ }
static class Data {
static def getData(OpenSamlObjects openSAMLObjects) {
- JPAEntityDescriptorServiceImpl entityDescriptorService = new JPAEntityDescriptorServiceImpl(openSAMLObjects, null, null)
def data = []
data << new DataField(
@@ -621,7 +604,7 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test'))
it
}
)
@@ -645,7 +628,7 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test'))
it
}
)
@@ -654,8 +637,8 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test'))
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test2', 'encryption', 'test2'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test2', 'encryption', 'test2'))
it
}
)
@@ -678,8 +661,8 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test'))
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test2', 'encryption', 'test2'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test2', 'encryption', 'test2'))
it
}
)
@@ -688,7 +671,7 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test2', 'encryption', 'test2'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test2', 'encryption', 'test2'))
it
}
)
@@ -708,8 +691,8 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test'))
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'encryption', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'encryption', 'test'))
it
}
)
@@ -729,8 +712,8 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with {
it.getRoleDescriptors().add(
openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with {
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test'))
- it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'encryption', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'signing', 'test'))
+ it.addKeyDescriptor(EntityDescriptorConverstionUtils.createKeyDescriptor('test', 'encryption', 'test'))
it
}
)
@@ -1108,11 +1091,9 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
it
}
)
-
return data
}
-
static class DataField implements Iterable {
String method
String description
@@ -1126,4 +1107,4 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification {
}
}
}
-}
+}
\ No newline at end of file