Skip to content

Commit

Permalink
NOJIRA
Browse files Browse the repository at this point in the history
re-merge current feature/shibu-2270 in to correct issues
  • Loading branch information
chasegawa committed Aug 29, 2022
2 parents b26d925 + 6db7d32 commit 573c769
Show file tree
Hide file tree
Showing 8 changed files with 386 additions and 739 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package edu.internet2.tier.shibboleth.admin.ui.service

import com.opencsv.CSVReader
import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibConfigurationProperty
import groovy.util.logging.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.event.ApplicationStartedEvent
import org.springframework.context.event.EventListener
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.Resource
import org.springframework.stereotype.Component

import javax.transaction.Transactional

@Component
@Slf4j
class ShibPropertiesBootstrap {
@Autowired
private ShibConfigurationService service

ShibPropertiesBootstrap(ShibConfigurationService service) {
this.service = service
}

@Transactional
@EventListener
void bootstrapUsersAndRoles(ApplicationStartedEvent e) {
log.info("Ensuring base Shibboleth properties configuration has loaded")

Resource resource = new ClassPathResource('shib_configuration_prop.csv')
final HashMap<String, ShibConfigurationProperty> propertiesMap = new HashMap<>()

// Read in the defaults in the configuration file
new CSVReader(new InputStreamReader(resource.inputStream)).each { fields ->
def (resource_id,category,config_file,description,idp_version,module,module_version,note,default_value,property_name,property_type,selection_items,property_value) = fields
ShibConfigurationProperty prop = new ShibConfigurationProperty().with {
it.resourceId = resource_id
it.category = category
it.configFile = config_file
it.description = description
it.idpVersion = idp_version
it.module = module
it.moduleVersion = module_version
it.note = note
it.defaultValue = default_value
it.description = description
it.propertyName = property_name
def pt = property_type
it.setPropertyType(pt)
it.selectionItems = selection_items
// we shouldn't have property values coming in from the config...
it
}
propertiesMap.put(prop.getPropertyName(), prop)
}

// If we already have the property in the db, ignore the configuration setup for that property
service.getExistingPropertyNames().each {
propertiesMap.remove(it)
}

// Save anything that's left
if (propertiesMap.size() > 0) {
log.info("Saving/loading [" + propertiesMap.size() + "] properties to the database")
service.addAllConfigurationProperties(propertiesMap.values())
}

log.info("COMPLETED: ensuring base Shibboleth properties configuration has loaded")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import edu.internet2.tier.shibboleth.admin.ui.domain.IRelyingPartyOverrideProperty;
import edu.internet2.tier.shibboleth.admin.ui.domain.RelyingPartyOverrideProperty;
import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibConfigurationProperty;
import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService;
import edu.internet2.tier.shibboleth.admin.ui.service.ShibConfigurationService;
import edu.internet2.tier.shibboleth.admin.ui.service.events.CustomEntityAttributeDefinitionChangeEvent;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package edu.internet2.tier.shibboleth.admin.ui.controller;

import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySet;
import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySetting;
import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException;
import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException;
import edu.internet2.tier.shibboleth.admin.ui.service.ShibConfigurationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.tags.Tags;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping(value = "/api/shib")
@Tags(value = {@Tag(name = "Shibboleth Properties")})
public class ShibPropertiesController {
@Autowired
private ShibConfigurationService service;

@GetMapping("/properties")
@Transactional(readOnly = true)
@Operation(description = "Return all the configuration properties - used to populate the UI with the know configuration properties",
summary = "Return all the configuration properties - used to populate the UI with the know configuration properties", method = "GET")
public ResponseEntity<?> getAllConfigurationProperties() {
return ResponseEntity.ok(service.getAllConfigurationProperties());
}

/**
* @return a List of the set names and their ids
*/
@GetMapping("/property/set")
@Transactional(readOnly = true)
@Operation(description = "Return a list of all the set names and their resourceId",
summary = "Return a list of all the set names and their resourceId", method = "GET")
public ResponseEntity<?> getAllPropertySets() {
return ResponseEntity.ok(service.getAllPropertySets());
}

@GetMapping(value="/property/set/{resourceId}", produces="applcation/json")
@Transactional(readOnly = true)
@Operation(description = "Return the property set with the given resourceId",
summary = "Return the property set with the given resourceId", method = "GET")
public ResponseEntity<?> getPropertySet(@PathVariable Integer resourceId) throws EntityNotFoundException {
return ResponseEntity.ok(service.getSet(resourceId));
}

@GetMapping(value="/property/set/{resourceId}", produces="application/zip")
@Transactional(readOnly = true)
@Operation(description = "Return the property set with the given resourceId as a zip file of the properties files",
summary = "Return the property set with the given resourceId as a zip file of the properties files", method = "GET")
public ResponseEntity<?> getPropertySetAsZip(@PathVariable Integer resourceId) throws EntityNotFoundException, IOException {
ShibPropertySet set = service.getSet(resourceId);
StringBuilder sb = new StringBuilder("attachment; filename=\"").append(set.getName()).append(".zip\"");
return ResponseEntity.ok().header("Content-Disposition", sb.toString()).body(prepDownloadAsZip(convertPropertiesToMaps(set.getProperties())));
}

private Map<String, Map<String,String>> convertPropertiesToMaps(List<ShibPropertySetting> properties) {
HashMap<String, Map<String,String>> result = new HashMap<>();
for (ShibPropertySetting setting:properties){
String confFile = setting.getConfigFile();
if (!result.containsKey(confFile)) {
Map<String,String> props = new HashMap<>();
result.put(confFile,props);
}
Map<String,String> props = result.get(confFile);
props.put(setting.getPropertyName(), setting.getPropertyValue());
}
return result;
}

private byte[] prepDownloadAsZip(Map<String, Map<String,String>> propertiesFiles) throws IOException {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteOutputStream);

for (String filename : propertiesFiles.keySet()) {
zipOutputStream.putNextEntry(new ZipEntry(filename));
Map<String, String> properties = propertiesFiles.get(filename);
StringBuilder props = new StringBuilder();
for (String key : properties.keySet()) {
props.append(key).append("=").append(properties.get(key)).append("\n");
}
ByteArrayInputStream inputStream = new ByteArrayInputStream(props.toString().getBytes());
IOUtils.copy(inputStream, zipOutputStream);
zipOutputStream.closeEntry();
}
zipOutputStream.close();
return byteOutputStream.toByteArray();
}

@DeleteMapping("/property/set/{resourceId}")
@Secured("ROLE_ADMIN")
@Transactional
public ResponseEntity<?> deletePropertySet(@PathVariable Integer resourceId) throws EntityNotFoundException {
service.delete(resourceId);
return ResponseEntity.noContent().build();
}

@PostMapping("/property/set")
@Secured("ROLE_ADMIN")
@Transactional
@Operation(description = "Create a property set with all new information - must not be an existing set",
summary = "Create a property set with all new information - must not be an existing set", method = "POST")
public ResponseEntity<?> createPropertySet(@RequestBody ShibPropertySet newSet) throws ObjectIdExistsException {
ShibPropertySet result = service.create(newSet);
return ResponseEntity.status(HttpStatus.CREATED).body(result);
}

@PutMapping("/property/set/{resourceId}")
@Secured("ROLE_ADMIN")
@Transactional
@Operation(description = "Update a property set with with the matching resourceId - must exist",
summary = "Update an existing property set with the matching resourceId - must exist", method = "PUT")
public ResponseEntity<?> updatePropertySet(@RequestBody ShibPropertySet setToUpdate, @PathVariable int resourceId) throws EntityNotFoundException {
ShibPropertySet result = service.update(setToUpdate);
return ResponseEntity.status(HttpStatus.OK).body(result);
}
}

This file was deleted.

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

import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibConfigurationProperty;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

/**
* Repository to manage {@link ShibConfigurationProperty} instances.
*/
public interface ShibConfigurationRepository extends JpaRepository<ShibConfigurationProperty, String> {
@Query(value = "select property_name from shib_configuration_prop", nativeQuery = true)
List<String> getPropertyNames();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibConfigurationProperty;
import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySet;
import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException;
import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException;
import edu.internet2.tier.shibboleth.admin.ui.repository.ProjectionIdAndName;

import java.util.Collection;
import java.util.List;

public interface ShibConfigurationService {
void addAllConfigurationProperties(Collection<ShibConfigurationProperty> newProperties);

ShibPropertySet create(ShibPropertySet set) throws ObjectIdExistsException;

void delete(int resourceId) throws EntityNotFoundException;

List<ShibConfigurationProperty> getAllConfigurationProperties();

List<ProjectionIdAndName> getAllPropertySets();

List<String> getExistingPropertyNames();

ShibPropertySet getSet(int resourceId) throws EntityNotFoundException;

ShibConfigurationProperty save(ShibConfigurationProperty prop);

ShibPropertySet update(ShibPropertySet setToUpdate) throws EntityNotFoundException;
}
Loading

0 comments on commit 573c769

Please sign in to comment.