Java tutorial
/* * oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. * * Copyright (c) 2014, Gluu */ package org.gluu.oxtrust.action; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.io.StringWriter; import java.math.BigInteger; import java.security.KeyPair; import java.security.SecureRandom; import java.security.Security; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.zip.Deflater; import java.util.zip.ZipOutputStream; import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.velocity.VelocityContext; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JDKKeyPairGenerator; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.encoders.Base64; import org.gluu.oxtrust.ldap.service.AttributeService; import org.gluu.oxtrust.ldap.service.ClientService; import org.gluu.oxtrust.ldap.service.MetadataValidationTimer; import org.gluu.oxtrust.ldap.service.OrganizationService; import org.gluu.oxtrust.ldap.service.SSLService; import org.gluu.oxtrust.ldap.service.Shibboleth2ConfService; import org.gluu.oxtrust.ldap.service.SvnSyncTimer; import org.gluu.oxtrust.ldap.service.TemplateService; import org.gluu.oxtrust.ldap.service.TrustService; import org.gluu.oxtrust.model.GluuCustomAttribute; import org.gluu.oxtrust.model.GluuMetadataSourceType; import org.gluu.oxtrust.model.GluuSAMLTrustRelationship; import org.gluu.oxtrust.model.OxAuthClient; import org.gluu.oxtrust.util.OxTrustConstants; import org.gluu.site.ldap.persistence.exception.LdapMappingException; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.security.Restrict; import org.jboss.seam.core.ResourceLoader; import org.jboss.seam.faces.FacesMessages; import org.jboss.seam.international.StatusMessage.Severity; import org.jboss.seam.log.Log; import org.jboss.seam.security.Identity; import org.xdi.config.oxtrust.ApplicationConfiguration; import org.xdi.ldap.model.GluuStatus; import org.xdi.model.GluuAttribute; import org.xdi.model.GluuUserRole; import org.xdi.model.SchemaEntry; import org.xdi.service.SchemaService; import org.xdi.util.StringHelper; import org.xdi.util.io.FileUploadWrapper; import org.xdi.util.io.ResponseHelper; import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition; /** * Action class for updating and adding the trust relationships * * @author Pankaj Narang * @author Yuriy Movchan Date: 11.04.2010 */ @Scope(ScopeType.CONVERSATION) @Name("updateTrustRelationshipAction") @Restrict("#{identity.loggedIn}") public class UpdateTrustRelationshipAction implements Serializable { private static final long serialVersionUID = -1032167044333943680L; @Logger private Log log; @In(value = "#{oxTrustConfiguration.applicationConfiguration}") private ApplicationConfiguration applicationConfiguration; static final Class<?>[] NO_PARAM_SIGNATURE = new Class[0]; private String inum; private boolean update; private GluuSAMLTrustRelationship trustRelationship; @In protected AttributeService attributeService; @In private TrustService trustService; @In private ClientService clientService; @In private Identity identity; @In private TemplateService templateService; @In private SvnSyncTimer svnSyncTimer; @In private Shibboleth2ConfService shibboleth2ConfService; @In private FacesMessages facesMessages; @In(value = "#{facesContext}") private FacesContext facesContext; @In(create = true) @Out(scope = ScopeType.CONVERSATION) private TrustContactsAction trustContactsAction; @In(create = true) @Out(scope = ScopeType.CONVERSATION) private MetadataFiltersAction metadataFiltersAction; @In(create = true) @Out(scope = ScopeType.CONVERSATION) private RelyingPartyAction relyingPartyAction; @In(create = true) @Out(scope = ScopeType.CONVERSATION) private CustomAttributeAction customAttributeAction; @In(create = true) @Out(scope = ScopeType.CONVERSATION) private FederationDeconstructionAction federationDeconstructionAction; private FileUploadWrapper fileWrapper = new FileUploadWrapper(); private FileUploadWrapper certWrapper = new FileUploadWrapper(); private String selectedTR; private List<GluuSAMLTrustRelationship> federatedSites; private List<String> availableEntities; private List<String> filteredEntities; private String filterString; private List<String> availableEntitiesFiltered; @In private ResourceLoader resourceLoader; @Restrict("#{s:hasPermission('trust', 'access')}") public String add() { if (this.trustRelationship != null) { return OxTrustConstants.RESULT_SUCCESS; } this.update = false; this.trustRelationship = new GluuSAMLTrustRelationship(); this.trustRelationship.setMaxRefreshDelay("PT8H"); this.fileWrapper = new FileUploadWrapper(); this.trustRelationship.setOwner(OrganizationService.instance().getOrganization().getDn()); boolean initActionsResult = initActions(); if (!initActionsResult) { return OxTrustConstants.RESULT_FAILURE; } return OxTrustConstants.RESULT_SUCCESS; } @Restrict("#{s:hasPermission('trust', 'access')}") public String update() { if (this.trustRelationship != null) { return OxTrustConstants.RESULT_SUCCESS; } this.update = true; try { this.trustRelationship = trustService.getRelationshipByInum(inum); } catch (LdapMappingException ex) { log.error("Failed to find trust relationship {0}", ex, inum); } if (this.trustRelationship == null) { return OxTrustConstants.RESULT_FAILURE; } this.fileWrapper = new FileUploadWrapper(); this.fileWrapper.setFileName(this.trustRelationship.getSpMetaDataFN()); boolean initActionsResult = initActions(); if (!initActionsResult) { return OxTrustConstants.RESULT_FAILURE; } return OxTrustConstants.RESULT_SUCCESS; } @Restrict("#{s:hasPermission('trust', 'access')}") public void cancel() { } @Restrict("#{s:hasPermission('trust', 'access')}") public String save() { synchronized (svnSyncTimer) { if (StringHelper.isEmpty(this.trustRelationship.getInum())) { this.inum = trustService.generateInumForNewTrustRelationship(); this.trustRelationship.setInum(this.inum); } else { this.inum = this.trustRelationship.getInum(); } boolean updateShib2Configuration = applicationConfiguration.isConfigGeneration(); switch (trustRelationship.getSpMetaDataSourceType()) { case GENERATE: String certificate = getCertForGeneratedSP(); GluuStatus status = StringHelper.isNotEmpty(certificate) ? GluuStatus.ACTIVE : GluuStatus.INACTIVE; this.trustRelationship.setStatus(status); if (generateSpMetaDataFile(certificate)) { setEntityId(); } else { log.error("Failed to generate SP meta-data file"); return OxTrustConstants.RESULT_FAILURE; } break; case FILE: if (saveSpMetaDataFileSourceTypeFile()) { update = true; updateSpMetaDataCert(certWrapper); // setEntityId(); this.trustRelationship.setStatus(GluuStatus.ACTIVE); } else { log.error("Failed to save SP meta-data file {0}", fileWrapper); return OxTrustConstants.RESULT_FAILURE; } break; case URI: try { if (saveSpMetaDataFileSourceTypeURI()) { // setEntityId(); this.trustRelationship.setStatus(GluuStatus.ACTIVE); } else { log.error("Failed to save SP meta-data file {0}", fileWrapper); return OxTrustConstants.RESULT_FAILURE; } } catch (Exception e) { return "unable_download_metadata"; } break; case FEDERATION: this.trustRelationship.setStatus(GluuStatus.ACTIVE); if (this.trustRelationship.getEntityId() == null) { return "invalid_entity_id"; } break; default: break; } trustService.updateReleasedAttributes(this.trustRelationship); boolean federation = trustService.isFederation(this.trustRelationship); this.trustRelationship.setFederation(federation); trustContactsAction.saveContacts(); if (update) { try { saveTR(update); } catch (LdapMappingException ex) { log.error("Failed to update trust relationship {0}", ex, inum); return OxTrustConstants.RESULT_FAILURE; } } else { String dn = trustService.getDnForTrustRelationShip(this.inum); // Save trustRelationship this.trustRelationship.setDn(dn); try { saveTR(update); } catch (LdapMappingException ex) { log.error("Failed to add new trust relationship {0}", ex, this.trustRelationship.getInum()); return OxTrustConstants.RESULT_FAILURE; } this.update = true; } if (updateShib2Configuration) { List<GluuSAMLTrustRelationship> trustRelationships = trustService.getAllActiveTrustRelationships(); updateShibboleth2Configuration(trustRelationships); } } return OxTrustConstants.RESULT_SUCCESS; } private boolean initActions() { initAttributes(this.trustRelationship); String resultInitContacts = trustContactsAction.initContacts(this.trustRelationship); if (!StringHelper.equalsIgnoreCase(OxTrustConstants.RESULT_SUCCESS, resultInitContacts)) { return false; } String resultInitMetadataFilters = metadataFiltersAction.initMetadataFilters(this.trustRelationship); if (!StringHelper.equalsIgnoreCase(OxTrustConstants.RESULT_SUCCESS, resultInitMetadataFilters)) { return false; } String resultInitProfileConfigurations = relyingPartyAction.initProfileConfigurations(); if (!StringHelper.equalsIgnoreCase(OxTrustConstants.RESULT_SUCCESS, resultInitProfileConfigurations)) { return false; } String resultInitFederationDeconstructions = federationDeconstructionAction .initFederationDeconstructions(this.trustRelationship); if (!StringHelper.equalsIgnoreCase(OxTrustConstants.RESULT_SUCCESS, resultInitFederationDeconstructions)) { return false; } initFederatedSites(this.trustRelationship); return true; } private List<GluuAttribute> getAllAttributes() { List<GluuAttribute> attributes = attributeService.getAllPersonAttributes(GluuUserRole.ADMIN); return attributes; } private List<GluuAttribute> getAllActiveAttributes() { List<GluuAttribute> attributes = attributeService.getAllActivePersonAttributes(GluuUserRole.ADMIN); return attributes; } private void initFederatedSites(GluuSAMLTrustRelationship trustRelationship) { List<GluuAttribute> attributes = getAllAttributes(); this.federatedSites = new ArrayList<GluuSAMLTrustRelationship>(); for (GluuSAMLTrustRelationship deconstructedTrustRelationship : trustService .getDeconstructedTrustRelationships(trustRelationship)) { initTrustRelationship(deconstructedTrustRelationship, attributes); this.federatedSites.add(deconstructedTrustRelationship); } } private void initAttributes(GluuSAMLTrustRelationship trust) { List<GluuAttribute> attributes = getAllActiveAttributes(); List<String> origins = attributeService.getAllAttributeOrigins(attributes); initTrustRelationship(trust, attributes); customAttributeAction.initCustomAttributes(attributes, trust.getReleasedCustomAttributes(), origins, applicationConfiguration.getPersonObjectClassTypes(), applicationConfiguration.getPersonObjectClassDisplayNames()); } public void initTrustRelationship(GluuSAMLTrustRelationship trust, List<GluuAttribute> attributes) { HashMap<String, GluuAttribute> attributesByDNs = attributeService.getAttributeMapByDNs(attributes); List<GluuCustomAttribute> customAttributes = attributeService .getCustomAttributesByAttributeDNs(trust.getReleasedAttributes(), attributesByDNs); boolean empty = (customAttributes == null) || customAttributes.isEmpty(); if (empty) { customAttributes = new ArrayList<GluuCustomAttribute>(); } trust.setReleasedCustomAttributes(customAttributes); } /** * Sets entityId according to metadatafile. Works for all TR which have own * metadata file. * * @author Oleksiy Tataryn */ private void setEntityId() { String idpMetadataFolder = applicationConfiguration.getShibboleth2IdpRootDir() + File.separator + Shibboleth2ConfService.SHIB2_IDP_METADATA_FOLDER + File.separator; File metadataFile = new File(idpMetadataFolder + trustRelationship.getSpMetaDataFN()); List<String> entityIdList = Shibboleth2ConfService.instance().getEntityIdFromMetadataFile(metadataFile); Set<String> entityIdSet = new TreeSet<String>(); if (entityIdList != null && !entityIdList.isEmpty()) { Set<String> duplicatesSet = new TreeSet<String>(); for (String entityId : entityIdList) { if (!entityIdSet.add(entityId)) { duplicatesSet.add(entityId); } } } this.trustRelationship.setGluuEntityId(entityIdSet); } /** * If there is no certificate selected, or certificate is invalid - * generates one. * * @author Oleksiy Tataryn * @return certificate for generated SP * @throws CertificateEncodingException */ private String getCertForGeneratedSP() { X509Certificate cert = SSLService.instance().getCertificate(certWrapper.getStream()); if (cert == null) { facesMessages.add(Severity.INFO, "Certificate were not provided, or was incorrect. Appliance will create a self-signed certificate."); if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { Security.addProvider(new BouncyCastleProvider()); } try { JDKKeyPairGenerator.RSA keyPairGen = new JDKKeyPairGenerator.RSA(); keyPairGen.initialize(2048); KeyPair pair = keyPairGen.generateKeyPair(); StringWriter keyWriter = new StringWriter(); PEMWriter pemFormatWriter = new PEMWriter(keyWriter); pemFormatWriter.writeObject(pair.getPrivate()); pemFormatWriter.close(); String url = trustRelationship.getUrl().replaceFirst(".*//", ""); X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder( new X500Name("CN=" + url + ", OU=None, O=None L=None, C=None"), BigInteger.valueOf(new SecureRandom().nextInt()), new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10)), new X500Name("CN=" + url + ", OU=None, O=None L=None, C=None"), pair.getPublic()); cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build( new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(pair.getPrivate()))); org.apache.commons.codec.binary.Base64 encoder = new org.apache.commons.codec.binary.Base64(64); byte[] derCert = cert.getEncoded(); String pemCertPre = new String(encoder.encode(derCert)); log.debug(Shibboleth2ConfService.PUBLIC_CERTIFICATE_START_LINE); log.debug(pemCertPre); log.debug(Shibboleth2ConfService.PUBLIC_CERTIFICATE_END_LINE); saveCert(trustRelationship, pemCertPre); saveKey(trustRelationship, keyWriter.toString()); } catch (Exception e) { e.printStackTrace(); } // String certName = applicationConfiguration.getCertDir() + File.separator + StringHelper.removePunctuation(applicationConfiguration.getOrgInum()) // + "-shib.crt"; // File certFile = new File(certName); // if (certFile.exists()) { // cert = SSLService.instance().getCertificate(certName); // } } String certificate = null; if (cert != null) { try { certificate = new String(Base64.encode(cert.getEncoded())); } catch (CertificateEncodingException e) { certificate = null; facesMessages.add(Severity.ERROR, "Failed to encode provided certificate. Please notify Gluu support about this."); log.error("Failed to encode certificate to DER", e); } } else { facesMessages.add(Severity.INFO, "Certificate were not provided, or was incorrect. Appliance will create a self-signed certificate."); } return certificate; } private void saveTR(boolean isUpdate) { log.trace("Saving Trust Relationship"); if (isUpdate) { String oldLogoutRedirectUri = trustService.getRelationshipByDn(trustRelationship.getDn()) .getSpLogoutURL(); String newLogoutRedirectUri = trustRelationship.getSpLogoutURL(); boolean oxClientUpdateNeeded = !newLogoutRedirectUri.equals(oldLogoutRedirectUri); boolean parentInactive = trustRelationship.getStatus().equals(GluuStatus.INACTIVE); if (!federatedSites.isEmpty()) { for (GluuSAMLTrustRelationship trust : federatedSites) { if (parentInactive) { trust.setStatus(GluuStatus.INACTIVE); } trustService.updateReleasedAttributes(trust); trustService.updateTrustRelationship(trust); svnSyncTimer.updateTrustRelationship(trust, identity.getCredentials().getUsername()); } } trustService.updateTrustRelationship(this.trustRelationship); if (oxClientUpdateNeeded) { OxAuthClient client = clientService.getClientByInum(applicationConfiguration.getOxAuthClientId()); Set<String> updatedLogoutRedirectUris = new HashSet<String>(); List<GluuSAMLTrustRelationship> trs = trustService.getAllTrustRelationships(); if (trs != null && !trs.isEmpty()) { for (GluuSAMLTrustRelationship tr : trs) { String logoutRedirectUri = tr.getSpLogoutURL(); if (logoutRedirectUri != null && !logoutRedirectUri.isEmpty()) { updatedLogoutRedirectUris.add(logoutRedirectUri); } } } if (updatedLogoutRedirectUris.size() == 0) { client.setPostLogoutRedirectUris(null); } else { client.setPostLogoutRedirectUris(updatedLogoutRedirectUris.toArray(new String[0])); } clientService.updateClient(client); } svnSyncTimer.updateTrustRelationship(this.trustRelationship, identity.getCredentials().getUsername()); } else { trustService.addTrustRelationship(this.trustRelationship); svnSyncTimer.addTrustRelationship(this.trustRelationship, identity.getCredentials().getUsername()); } } private void updateSpMetaDataCert(FileUploadWrapper certWrapper) { String certificate = shibboleth2ConfService.getPublicCertificate(certWrapper); if (certificate == null) { return; } // This regex defines certificate enclosed in X509Certificate tags // regardless of namespace(as long as it is not more then 9 characters) String certRegEx = "(?ms)(?<=<[^</>]{0,10}X509Certificate>).*(?=</[^</>]{0,10}?X509Certificate>)"; try { saveCert(trustRelationship, certificate); saveKey(trustRelationship, null); String metadataFileName = this.trustRelationship.getSpMetaDataFN(); File metadataFile = new File(shibboleth2ConfService.getSpMetadataFilePath(metadataFileName)); String metadata = FileUtils.readFileToString(metadataFile); String updatedMetadata = metadata.replaceFirst(certRegEx, certificate); FileUtils.writeStringToFile(metadataFile, updatedMetadata); this.trustRelationship.setStatus(GluuStatus.ACTIVE); } catch (Exception e) { log.error("Failed to update certificate", e); } } /** * @param trustRelationship2 * @param certificate */ private void saveCert(GluuSAMLTrustRelationship trustRelationship, String certificate) { String sslDirFN = applicationConfiguration.getShibboleth2IdpRootDir() + File.separator + TrustService.GENERATED_SSL_ARTIFACTS_DIR + File.separator; File sslDir = new File(sslDirFN); if (!sslDir.exists()) { log.debug("creating directory: " + sslDirFN); boolean result = sslDir.mkdir(); if (result) { log.debug("DIR created"); } } BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(sslDirFN + shibboleth2ConfService .getSpNewMetadataFileName(trustRelationship).replaceFirst("\\.xml$", ".crt"))); writer.write(Shibboleth2ConfService.PUBLIC_CERTIFICATE_START_LINE + "\n" + certificate + Shibboleth2ConfService.PUBLIC_CERTIFICATE_END_LINE); } catch (IOException e) { } finally { try { if (writer != null) { writer.close(); } } catch (IOException e) { } } } /** * @param trustRelationship2 * @param printBase64Binary */ private void saveKey(GluuSAMLTrustRelationship trustRelationship, String key) { String sslDirFN = applicationConfiguration.getShibboleth2IdpRootDir() + File.separator + TrustService.GENERATED_SSL_ARTIFACTS_DIR + File.separator; File sslDir = new File(sslDirFN); if (!sslDir.exists()) { log.debug("creating directory: " + sslDirFN); boolean result = sslDir.mkdir(); if (result) { log.debug("DIR created"); } } if (key != null) { BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(sslDirFN + shibboleth2ConfService .getSpNewMetadataFileName(trustRelationship).replaceFirst("\\.xml$", ".key"))); writer.write(key); } catch (IOException e) { } finally { try { if (writer != null) { writer.close(); } } catch (IOException e) { } } } else { File keyFile = new File(sslDirFN + shibboleth2ConfService.getSpNewMetadataFileName(trustRelationship) .replaceFirst("\\.xml$", ".key")); if (keyFile.exists()) { keyFile.delete(); } } } private void markAsInactive() { // Mark this configuration as not active because we don't have correct // files in meta-data folder if (update) { try { GluuSAMLTrustRelationship tmpTrustRelationship = trustService .getRelationshipByInum(this.trustRelationship.getInum()); tmpTrustRelationship.setStatus(GluuStatus.INACTIVE); saveTR(update); } catch (LdapMappingException ex) { log.error("Failed to update trust relationship {0}", ex, inum); } } else { // Remove file name to generate new one during new save attempt. // Cover case when somebody else added new one simultaneously this.trustRelationship.setSpMetaDataFN(null); this.trustRelationship.setInum(null); } } private void updateShibboleth2Configuration(List<GluuSAMLTrustRelationship> trustRelationships) { if (!shibboleth2ConfService.generateConfigurationFiles(trustRelationships)) { log.error("Failed to update Shibboleth2 configuration"); facesMessages.add(Severity.ERROR, "Failed to update Shibboleth2 configuration"); } else { log.info("Shibboleth2 configuration updated successfully"); facesMessages.add(Severity.INFO, "Shibboleth2 configuration updated successfully"); } } private boolean generateSpMetaDataFile(String certificate) { boolean result = generateSpMetaDataFileImpl(certificate); if (result) { this.trustRelationship.setSpMetaDataSourceType(GluuMetadataSourceType.FILE); facesMessages.add(Severity.WARN, "SP meta-data file generated."); } else { facesMessages.add(Severity.ERROR, "Failed to generate SP meta-data file"); markAsInactive(); } return result; } private boolean generateSpMetaDataFileImpl(String certificate) { String spMetadataFileName = trustRelationship.getSpMetaDataFN(); if (StringHelper.isEmpty(spMetadataFileName)) { // Generate new file name spMetadataFileName = shibboleth2ConfService.getSpNewMetadataFileName(this.trustRelationship); trustRelationship.setSpMetaDataFN(spMetadataFileName); } return shibboleth2ConfService.generateSpMetadataFile(trustRelationship, certificate); } private boolean saveSpMetaDataFileSourceTypeFile() { log.trace("Saving metadata file source type: File"); String spMetadataFileName = trustRelationship.getSpMetaDataFN(); boolean emptySpMetadataFileName = StringHelper.isEmpty(spMetadataFileName); if (fileWrapper.getStream() == null) { if (emptySpMetadataFileName) { return false; } // Admin doesn't provide new file. Check if we already has this file String filePath = shibboleth2ConfService.getSpMetadataFilePath(spMetadataFileName); if (filePath == null) { return false; } File file = new File(filePath); if (!file.exists()) { return false; } // File already exist return true; } if (emptySpMetadataFileName) { // Generate new file name spMetadataFileName = shibboleth2ConfService.getSpNewMetadataFileName(this.trustRelationship); this.trustRelationship.setSpMetaDataFN(spMetadataFileName); if (trustRelationship.getDn() == null) { String dn = trustService.getDnForTrustRelationShip(this.inum); this.trustRelationship.setDn(dn); trustService.addTrustRelationship(this.trustRelationship); } else { trustService.updateTrustRelationship(this.trustRelationship); } } String result = shibboleth2ConfService.saveSpMetadataFile(spMetadataFileName, fileWrapper.getStream()); if (StringHelper.isNotEmpty(result)) { MetadataValidationTimer.queue(result); } else { facesMessages.add(Severity.ERROR, "Failed to save SP meta-data file. Please check if you provide correct file"); } return StringHelper.isNotEmpty(result); } private boolean saveSpMetaDataFileSourceTypeURI() throws IOException { String spMetadataFileName = trustRelationship.getSpMetaDataFN(); boolean emptySpMetadataFileName = StringHelper.isEmpty(spMetadataFileName); if (emptySpMetadataFileName) { // Generate new file name spMetadataFileName = shibboleth2ConfService.getSpNewMetadataFileName(this.trustRelationship); } String result = shibboleth2ConfService.saveSpMetadataFile(trustRelationship.getSpMetaDataURL(), spMetadataFileName); if (StringHelper.isNotEmpty(result)) { MetadataValidationTimer.queue(result); } else { facesMessages.add(Severity.ERROR, "Failed to download metadata"); } return StringHelper.isNotEmpty(result); } @Restrict("#{s:hasPermission('person', 'access')}") public String delete() { String result = OxTrustConstants.RESULT_FAILURE; if (update) { // Remove trust relationship try { synchronized (svnSyncTimer) { for (GluuSAMLTrustRelationship trust : trustService .getDeconstructedTrustRelationships(this.trustRelationship)) { if (GluuStatus.ACTIVE.equals(trust.getStatus())) { log.error( "Failed to remove federation trust relationship {0}, there are still active federated Trust Relationships left.", this.trustRelationship.getInum()); return result; } } for (GluuSAMLTrustRelationship trust : trustService .getDeconstructedTrustRelationships(this.trustRelationship)) { trustService.removeTrustRelationship(trust); svnSyncTimer.removeTrustRelationship(trust, identity.getCredentials().getUsername()); } shibboleth2ConfService.removeSpMetadataFile(this.trustRelationship.getSpMetaDataFN()); trustService.removeTrustRelationship(this.trustRelationship); svnSyncTimer.removeTrustRelationship(this.trustRelationship, identity.getCredentials().getUsername()); } result = OxTrustConstants.RESULT_SUCCESS; } catch (LdapMappingException ex) { result = OxTrustConstants.RESULT_FAILURE; log.error("Failed to remove trust relationship {0}", ex, this.trustRelationship.getInum()); } catch (InterruptedException e) { log.error( "Failed to add trust relationship to remove queue. It will be removed during next application restart", e); } finally { List<GluuSAMLTrustRelationship> trustRelationships = trustService.getAllActiveTrustRelationships(); updateShibboleth2Configuration(trustRelationships); } } return result; } @Restrict("#{s:hasPermission('trust', 'access')}") public String downloadConfiguration() { Shibboleth2ConfService shibboleth2ConfService = Shibboleth2ConfService.instance(); ByteArrayOutputStream bos = new ByteArrayOutputStream(16384); ZipOutputStream zos = ResponseHelper.createZipStream(bos, "Shibboleth2 configuration files"); try { zos.setMethod(ZipOutputStream.DEFLATED); zos.setLevel(Deflater.DEFAULT_COMPRESSION); // Add files String idpMetadataFilePath = shibboleth2ConfService.getIdpMetadataFilePath(); if (!ResponseHelper.addFileToZip(idpMetadataFilePath, zos, Shibboleth2ConfService.SHIB2_IDP_IDP_METADATA_FILE)) { log.error("Failed to add " + idpMetadataFilePath + " to zip"); return OxTrustConstants.RESULT_FAILURE; } if (this.trustRelationship.getSpMetaDataFN() == null) { log.error("SpMetaDataFN is not set."); return OxTrustConstants.RESULT_FAILURE; } String spMetadataFilePath = shibboleth2ConfService .getSpMetadataFilePath(this.trustRelationship.getSpMetaDataFN()); if (!ResponseHelper.addFileToZip(spMetadataFilePath, zos, Shibboleth2ConfService.SHIB2_IDP_SP_METADATA_FILE)) { log.error("Failed to add " + spMetadataFilePath + " to zip"); return OxTrustConstants.RESULT_FAILURE; } String sslDirFN = applicationConfiguration.getShibboleth2IdpRootDir() + File.separator + TrustService.GENERATED_SSL_ARTIFACTS_DIR + File.separator; String spKeyFilePath = sslDirFN + shibboleth2ConfService .getSpNewMetadataFileName(this.trustRelationship).replaceFirst("\\.xml$", ".key"); if (!ResponseHelper.addFileToZip(spKeyFilePath, zos, Shibboleth2ConfService.SHIB2_IDP_SP_KEY_FILE)) { log.error("Failed to add " + spKeyFilePath + " to zip"); // return OxTrustConstants.RESULT_FAILURE; } String spCertFilePath = sslDirFN + shibboleth2ConfService .getSpNewMetadataFileName(this.trustRelationship).replaceFirst("\\.xml$", ".crt"); if (!ResponseHelper.addFileToZip(spCertFilePath, zos, Shibboleth2ConfService.SHIB2_IDP_SP_CERT_FILE)) { log.error("Failed to add " + spCertFilePath + " to zip"); // return OxTrustConstants.RESULT_FAILURE; } String spAttributeMap = shibboleth2ConfService.generateSpAttributeMapFile(this.trustRelationship); if (spAttributeMap == null) { log.error("spAttributeMap is not set."); return OxTrustConstants.RESULT_FAILURE; } if (!ResponseHelper.addFileContentToZip(spAttributeMap, zos, Shibboleth2ConfService.SHIB2_SP_ATTRIBUTE_MAP)) { log.error("Failed to add " + spAttributeMap + " to zip"); return OxTrustConstants.RESULT_FAILURE; } String spShibboleth2FilePath = shibboleth2ConfService.getSpShibboleth2FilePath(); VelocityContext context = new VelocityContext(); context.put("spUrl", trustRelationship.getUrl()); String gluuSPEntityId = trustRelationship.getEntityId(); context.put("gluuSPEntityId", gluuSPEntityId); String spHost = trustRelationship.getUrl().replaceAll(":[0-9]*$", "").replaceAll("^.*?//", ""); context.put("spHost", spHost); String idpUrl = applicationConfiguration.getIdpUrl(); context.put("idpUrl", idpUrl); String idpHost = idpUrl.replaceAll(":[0-9]*$", "").replaceAll("^.*?//", ""); context.put("idpHost", idpHost); context.put("orgInum", StringHelper.removePunctuation(OrganizationService.instance().getOrganizationInum())); context.put("orgSupportEmail", applicationConfiguration.getOrgSupportEmail()); String shibConfig = templateService.generateConfFile(Shibboleth2ConfService.SHIB2_SP_SHIBBOLETH2, context); if (!ResponseHelper.addFileContentToZip(shibConfig, zos, Shibboleth2ConfService.SHIB2_SP_SHIBBOLETH2)) { log.error("Failed to add " + spShibboleth2FilePath + " to zip"); return OxTrustConstants.RESULT_FAILURE; } String spReadMeResourceName = shibboleth2ConfService.getSpReadMeResourceName(); String fileName = (new File(spReadMeResourceName)).getName(); InputStream is = resourceLoader.getResourceAsStream(spReadMeResourceName); //InputStream is = this.getClass().getClassLoader().getResourceAsStream(spReadMeResourceName); if (!ResponseHelper.addResourceToZip(is, fileName, zos)) { log.error("Failed to add " + spReadMeResourceName + " to zip"); return OxTrustConstants.RESULT_FAILURE; } String spReadMeWindowsResourceName = shibboleth2ConfService.getSpReadMeWindowsResourceName(); fileName = (new File(spReadMeWindowsResourceName)).getName(); is = resourceLoader.getResourceAsStream(spReadMeWindowsResourceName); if (!ResponseHelper.addResourceToZip(is, fileName, zos)) { log.error("Failed to add " + spReadMeWindowsResourceName + " to zip"); return OxTrustConstants.RESULT_FAILURE; } } finally { IOUtils.closeQuietly(zos); IOUtils.closeQuietly(bos); } boolean result = ResponseHelper.downloadFile("shibboleth2-configuration.zip", OxTrustConstants.CONTENT_TYPE_APPLICATION_ZIP, bos.toByteArray(), facesContext); return result ? OxTrustConstants.RESULT_SUCCESS : OxTrustConstants.RESULT_FAILURE; } public FileUploadWrapper getFileWrapper() { return fileWrapper; } public FileUploadWrapper getCertWrapper() { return certWrapper; } private List<GluuCustomAttribute> getCurrentCustomAttributes() { List<GluuCustomAttribute> result = new ArrayList<GluuCustomAttribute>(); if (selectedTR == null || selectedTR.equals(trustRelationship.getInum())) { result = this.trustRelationship.getReleasedCustomAttributes(); } else { for (GluuSAMLTrustRelationship trust : federatedSites) { if (selectedTR.equals(trust.getInum())) { result = trust.getReleasedCustomAttributes(); break; } } } return result; } public String getInum() { return inum; } public void setInum(String inum) { this.inum = inum; } public GluuSAMLTrustRelationship getTrustRelationship() { return trustRelationship; } public String getMetadata() throws IOException { if (trustRelationship == null) { return null; } String filename = trustRelationship.getSpMetaDataFN(); File metadataFile = null; if (!StringUtils.isEmpty(filename)) { metadataFile = new File(shibboleth2ConfService.getSpMetadataFilePath(filename)); if (metadataFile.exists()) { return FileUtils.readFileToString(metadataFile); } } return null; } public boolean isUpdate() { return update; } protected String getEventQueue() { return "trustQueue"; } protected String getActionName() { return "updateTrustRelationshipAction"; } protected boolean allowAccessAttribute(GluuAttribute attribute) { return attribute.isAdminCanAccess(); } protected boolean allowEditAttribute(GluuAttribute attribute) { // Allow select any attribute return true; } /* * public void initReleasedAttributePanelBar(){ UIAccordion * attributePanelBar = (UIAccordion) * FacesComponentUtility.findComponentById("ReleasedAttributePanelBar"); if * (attributePanelBar == null) { return; } * * if (attributePanelBar.getChildCount() == 0) { * initAttributePanelBar(attributePanelBar); } else { * updateAttributePanelBar(attributePanelBar); } } * * private void updateAttributePanelBar(UIAccordion attributePanelBar) { * UIAccordionItem uiAccordionItem = null; Map<String, UIComponent> entities * = new HashMap<String, UIComponent>(); * * for (UIComponent htmlComponent : attributePanelBar.getChildren()) { * uiAccordionItem = (UIAccordionItem) htmlComponent; * entities.put(uiAccordionItem.getId(), uiAccordionItem); } * * // this.federatedSites.clear(); for(GluuSAMLTrustRelationship trust : * trustService.getDeconstructedTrustRelationships(trustRelationship)){ * if(!this.federatedSites.contains(trust)){ this.federatedSites.add(trust); * * if(! * entities.keySet().contains(StringHelper.removePunctuation(trust.getInum * ()))){ addNewPanelBarItem(attributePanelBar,trust); }else{ if(! * entities.get * (StringHelper.removePunctuation(trust.getInum())).isRendered()){ * entities. * get(StringHelper.removePunctuation(trust.getInum())).setRendered(true); } * } } entities.remove(StringHelper.removePunctuation(trust.getInum())); } * * for(String entity : entities.keySet()){ * if(!entity.equals(StringHelper.removePunctuation * (trustRelationship.getInum())) && !entity.equals("NewTrustRelationship") * ){ if(entities.get(entity).isRendered()){ * entities.get(entity).setRendered(false); for(GluuSAMLTrustRelationship * trust : this.federatedSites){ * if(entity.equals(StringHelper.removePunctuation(trust.getInum()))){ * this.federatedSites.remove(trust); break; } } } } } } * * private void initAttributePanelBar(UIAccordion attributePanelBar) { * UIAccordionItem federation = createTrustPanel(null); String * federationName = trustRelationship.getDisplayName() == null ? * "New Trust Relationship" : trustRelationship.getDisplayName(); * federation.setHeader(federationName); String federationId = * trustRelationship.getInum() == null ? "NewTrustRelationship" : * StringHelper.removePunctuation(trustRelationship.getInum()); * federation.setId("pb" + federationId); * * attributePanelBar.getChildren().add(federation); this.federatedSites = * new ArrayList<GluuSAMLTrustRelationship>(); for(GluuSAMLTrustRelationship * trust : * trustService.getDeconstructedTrustRelationships(trustRelationship)){ * addNewPanelBarItem(attributePanelBar,trust); * * } } * * private void addNewPanelBarItem(UIAccordion attributePanelBar, * GluuSAMLTrustRelationship trust) { initAttributes(trust); * federatedSites.add(trust); UIAccordionItem trustPanel = * createTrustPanel(trust); attributePanelBar.getChildren().add(trustPanel); * } * * private UIAccordionItem createTrustPanel(GluuSAMLTrustRelationship trust) * { Application application = * FacesContext.getCurrentInstance().getApplication(); ExpressionFactory * expressionFactory = application.getExpressionFactory(); ELContext * elContext = FacesContext.getCurrentInstance().getELContext(); * * UIAccordionItem trustPanel = (UIAccordionItem) * application.createComponent(UIAccordionItem.COMPONENT_TYPE); UIRepeat * selectedCustomAttributes = (UIRepeat) * application.createComponent(UIRepeat.COMPONENT_TYPE); if(trust == null){ * trustPanel.setHeader(trustRelationship.getDisplayName()); * trustPanel.setId * ("pb"+StringHelper.removePunctuation(trustRelationship.getInum())); * AjaxBehavior onEnter = (AjaxBehavior) * application.createBehavior(AjaxBehavior.BEHAVIOR_ID); MethodExpression * methodExpression = expressionFactory.createMethodExpression(elContext, * "#{" + getActionName() + ".setSelectedTR('" + trustRelationship.getInum() * + "')}", Void.TYPE, new Class[]{String.class}); * onEnter.setOnbeforesubmit( * "changeButtonsAvailability('updateButtons',false);"); * onEnter.setOncomplete * ("changeButtonsAvailability('updateButtons',true);"); * onEnter.setLimitRender(true); * onEnter.setRender(Arrays.asList("attributeTabPanelGroupId")); * * onEnter.addAjaxBehaviorListener(new * MethodExpressionAjaxBehaviorListener(methodExpression)); * trustPanel.addClientBehavior("onenter", onEnter); * * selectedCustomAttributes.setValue(trustRelationship. * getReleasedCustomAttributes()); }else{ * trustPanel.setHeader(trust.getDisplayName()); * trustPanel.setId(StringHelper.removePunctuation(trust.getInum())); * * AjaxBehavior onEnter = (AjaxBehavior) * application.createBehavior(AjaxBehavior.BEHAVIOR_ID); MethodExpression * methodExpression = expressionFactory.createMethodExpression(elContext, * "#{" + getActionName() + ".setSelectedTR('" + trust.getEntityId() + * "')}", Void.TYPE, new Class[]{String.class}); * onEnter.setOnbeforesubmit("changeButtonsAvailability('updateButtons',false);" * ); * onEnter.setOncomplete("changeButtonsAvailability('updateButtons',true);" * ); onEnter.setLimitRender(true); * onEnter.setRender(Arrays.asList("attributeTabPanelGroupId")); * onEnter.addAjaxBehaviorListener(new * MethodExpressionAjaxBehaviorListener(methodExpression)); * trustPanel.addClientBehavior("onenter", onEnter); * * initAttributes(trust); * selectedCustomAttributes.setValue(trust.getReleasedCustomAttributes()); * * } //direction="bottom-left" mode="ajax" id="contactToolTip" * horizontalOffset="200" eventsQueue="profileQueue" * selectedCustomAttributes.setVar("_attribute"); HtmlCommandLink * atributeName = (HtmlCommandLink) * application.createComponent(HtmlCommandLink.COMPONENT_TYPE); * ValueExpression bind = expressionFactory.createValueExpression(elContext, * "#{_attribute.metadata.displayName}", String.class); * atributeName.setValueExpression("value", bind); // Commented out during * migration to Richfaces 4 // * atributeName.setSimilarityGroupingId("_attribute"); * atributeName.setStyleClass("attributeTooltip"); ValueExpression * samlUriBind = expressionFactory.createValueExpression(elContext, * "SAML URI for this attribute: |#{" + getActionName() + * ".getSAML1URI(_attribute.metadata)" + "}|#{" + getActionName() + * ".getSAML2URI(_attribute.metadata)}", String.class); * atributeName.setValueExpression("title", samlUriBind); * * * selectedCustomAttributes.getChildren().add(atributeName); HtmlOutputText * spacer = (HtmlOutputText) * application.createComponent(HtmlOutputText.COMPONENT_TYPE); * spacer.setValue(" "); selectedCustomAttributes.getChildren().add(spacer); * UICommandLink commandLink = (UICommandLink) * application.createComponent(UICommandLink.COMPONENT_TYPE); * MethodExpression removeMethodExpression = * expressionFactory.createMethodExpression(elContext, "#{" + * getActionName() + ".removeCustomAttribute(_attribute.metadata.inum)}", * null, NO_PARAM_SIGNATURE); * commandLink.setActionExpression(removeMethodExpression); * * commandLink.setRender("ReleasedAttributePanelBar, attributeTabPanelGroupId" * ); commandLink.setOncomplete("addTooltip();"); * commandLink.setLimitRender(true); * * HtmlGraphicImage image = (HtmlGraphicImage) * application.createComponent(HtmlGraphicImage.COMPONENT_TYPE); * image.setValue("/img/remove.gif"); commandLink.getChildren().add(image); * * * * selectedCustomAttributes.getChildren().add(commandLink); HtmlOutputText * lineBreak = (HtmlOutputText) * application.createComponent(HtmlOutputText.COMPONENT_TYPE); * lineBreak.setValue("<br/>"); lineBreak.setEscape(false); * selectedCustomAttributes.getChildren().add(lineBreak); * trustPanel.getChildren().add(selectedCustomAttributes); * * return trustPanel; } */ public String getSAML1URI(GluuAttribute attribute) { if (StringHelper.isNotEmpty(attribute.getSaml1Uri())) { return "SAML1 URI: " + attribute.getSaml1Uri(); } String namespace = ""; if (attribute.isCustom() || StringHelper.isEmpty(attribute.getUrn()) || (!StringHelper.isEmpty(attribute.getUrn()) && attribute.getUrn().startsWith("urn:gluu:dir:attribute-def:"))) { namespace = "gluu"; } else { namespace = "mace"; } return "SAML1 URI: urn:" + namespace + ":dir:attribute-def:" + attribute.getName(); } public String getSAML2URI(GluuAttribute attribute) { if (StringHelper.isNotEmpty(attribute.getSaml2Uri())) { return "SAML1 URI: " + attribute.getSaml2Uri(); } List<String> attributeNames = new ArrayList<String>(); attributeNames.add(attribute.getName()); SchemaService shemaService = SchemaService.instance(); SchemaEntry schemaEntry = shemaService.getSchema(); List<AttributeTypeDefinition> attributeTypes = shemaService.getAttributeTypeDefinitions(schemaEntry, attributeNames); String attributeName = attribute.getName(); AttributeTypeDefinition attributeTypeDefinition = shemaService.getAttributeTypeDefinition(attributeTypes, attributeName); if (attributeTypeDefinition == null) { log.error("Failed to get OID for attribute name {0}", attributeName); return null; } return "SAML2 URI: urn:oid:" + attributeTypeDefinition.getOID(); } public void setSelectedTR(String trust) { this.selectedTR = trust; customAttributeAction.refreshCustomAttributes(getCurrentCustomAttributes()); } public void setContainerFederation(SelectItem federation) { this.trustRelationship.setContainerFederation((GluuSAMLTrustRelationship) federation.getValue()); } public SelectItem getContainerFederation() { return new SelectItem(trustRelationship.getContainerFederation(), trustRelationship.getContainerFederation() == null ? "Select Federation" : trustRelationship.getContainerFederation().getDisplayName()); } public ArrayList<SelectItem> getAllFederations() { ArrayList<SelectItem> result = new ArrayList<SelectItem>(); for (GluuSAMLTrustRelationship federation : trustService.getAllFederations()) { result.add(new SelectItem(federation, federation.getDisplayName())); } return result; } public boolean isActive() { return GluuStatus.ACTIVE.equals(trustRelationship.getStatus()); } public String activationToggle() { if (trustRelationship.getStatus().equals(GluuStatus.ACTIVE)) { trustRelationship.setStatus(GluuStatus.INACTIVE); } else if (trustRelationship.getStatus().equals(GluuStatus.INACTIVE)) { trustRelationship.setStatus(GluuStatus.ACTIVE); } saveTR(true); List<GluuSAMLTrustRelationship> trustRelationships = trustService.getAllActiveTrustRelationships(); updateShibboleth2Configuration(trustRelationships); return OxTrustConstants.RESULT_SUCCESS; } public void setSelectedEntities(String[] entities) { if (entities != null && entities.length > 0) { this.trustRelationship.setEntityId(entities[0]); } } public String[] getSelectedEntities() { if (isUpdate() && this.trustRelationship.getGluuEntityId() != null) { return this.trustRelationship.getGluuEntityId().toArray(new String[0]); } else { return new String[0]; } } public void filterEntities() { filteredEntities = null; if (StringHelper.isNotEmpty(getFilterString())) { filteredEntities = new ArrayList<String>(); for (String entity : trustRelationship.getContainerFederation().getGluuEntityId()) { if (entity.toLowerCase().contains(getFilterString().toLowerCase())) { filteredEntities.add(entity); } } } } public void setAvailableEntities(List<String> availableEntities) { this.availableEntities.removeAll(availableEntitiesFiltered); this.availableEntities.addAll(availableEntities); } public List<String> getAvailableEntities() { if (trustRelationship.getContainerFederation() == null) { return null; } else { if (!trustRelationship.getContainerFederation().getGluuEntityId() .contains(trustRelationship.getEntityId())) { trustRelationship.setEntityId(null); availableEntities = null; } } if (availableEntities == null) { availableEntities = new ArrayList<String>(); if (trustRelationship.getContainerFederation() != null) { availableEntities.addAll(trustRelationship.getContainerFederation().getGluuEntityId()); } } availableEntitiesFiltered = new ArrayList<String>(); availableEntitiesFiltered.addAll(availableEntities); if (filteredEntities != null) { availableEntitiesFiltered.retainAll(filteredEntities); } return availableEntitiesFiltered; } public void setFilterString(String filterString) { this.filterString = filterString; } public String getFilterString() { return this.filterString; } public List<GluuSAMLTrustRelationship> getFederatedSites() { return federatedSites; } }