// Path: mujina-sp/src/main/java/mujina/api/SpConfiguration.java
// @Component
// @Getter
// @Setter
// public class SpConfiguration extends SharedConfiguration {
// 
//   private String defaultEntityId;
// 
//   private String defaultIdpSSOServiceURL;
//   private String idpSSOServiceURL;
//   private String defaultProtocolBinding;
//   private String protocolBinding;
//   private String defaultAssertionConsumerServiceURL;
//   private boolean defaultNeedsSigning;
//   private String assertionConsumerServiceURL;
//   private String spPrivateKey;
//   private String spCertificate;
// 
//   @Autowired
//   public SpConfiguration(JKSKeyManager keyManager,
//                          @Value("${sp.base_url}") String spBaseUrl,
//                          @Value("${sp.entity_id}") String defaultEntityId,
//                          @Value("${sp.single_sign_on_service_location}") String defaultIdpSSOServiceURL,
//                          @Value("${sp.acs_location_path}") String defaultAssertionConsumerServiceURLPath,
//                          @Value("${sp.protocol_binding}") String defaultProtocolBinding,
//                          @Value("${sp.private_key}") String spPrivateKey,
//                          @Value("${sp.certificate}") String spCertificate,
//                          @Value("${sp.needs_signing}") boolean needsSigning) {
//     super(keyManager);
//     this.setDefaultEntityId(defaultEntityId);
//     this.setDefaultIdpSSOServiceURL(defaultIdpSSOServiceURL);
//     this.setDefaultAssertionConsumerServiceURL(spBaseUrl + defaultAssertionConsumerServiceURLPath);
//     this.setDefaultProtocolBinding(defaultProtocolBinding);
//     this.setSpPrivateKey(spPrivateKey);
//     this.setSpCertificate(spCertificate);
//     this.setDefaultNeedsSigning(needsSigning);
//     reset();
//   }
// 
//   @Override
//   public void reset() {
//     setEntityId(defaultEntityId, false);
//     setNeedsSigning(defaultNeedsSigning);
//     resetKeyStore(defaultEntityId, spPrivateKey, spCertificate);
//     setIdpSSOServiceURL(defaultIdpSSOServiceURL);
//     setProtocolBinding(defaultProtocolBinding);
//     setAssertionConsumerServiceURL(defaultAssertionConsumerServiceURL);
//     setSignatureAlgorithm(getDefaultSignatureAlgorithm());
//   }
// 
// }
// 
// Path: mujina-common/src/main/java/mujina/saml/UpgradedSAMLBootstrap.java
// public class UpgradedSAMLBootstrap extends SAMLBootstrap {
// 
//   @Override
//   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//     super.postProcessBeanFactory(beanFactory);
//     BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
//     config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
//     config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
//   }
// }


import mujina.api.SpConfiguration;
import mujina.saml.UpgradedSAMLBootstrap;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.velocity.app.VelocityEngine;
import org.opensaml.common.SAMLException;
import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.xml.encryption.DecryptionException;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.validation.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.saml.SAMLBootstrap;
import org.springframework.security.saml.context.SAMLMessageContext;
import org.springframework.security.saml.log.SAMLDefaultLogger;
import org.springframework.security.saml.processor.HTTPArtifactBinding;
import org.springframework.security.saml.processor.HTTPPAOS11Binding;
import org.springframework.security.saml.processor.HTTPPostBinding;
import org.springframework.security.saml.processor.HTTPRedirectDeflateBinding;
import org.springframework.security.saml.processor.HTTPSOAP11Binding;
import org.springframework.security.saml.processor.SAMLBinding;
import org.springframework.security.saml.processor.SAMLProcessor;
import org.springframework.security.saml.websso.ArtifactResolutionProfile;
import org.springframework.security.saml.websso.ArtifactResolutionProfileImpl;
import org.springframework.security.saml.websso.WebSSOProfile;
import org.springframework.security.saml.websso.WebSSOProfileConsumer;
import org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl;
import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl;
import org.springframework.security.saml.websso.WebSSOProfileECPImpl;
import org.springframework.security.saml.websso.WebSSOProfileImpl;
import java.util.ArrayList;
import java.util.Collection;
  @Bean
  @Autowired
  public HTTPSOAP11Binding httpSOAP11Binding(ParserPool parserPool) {
    return new HTTPSOAP11Binding(parserPool);
  }

  @Bean
  @Autowired
  public HTTPPAOS11Binding httpPAOS11Binding(ParserPool parserPool) {
    return new HTTPPAOS11Binding(parserPool);
  }

  @Autowired
  @Bean
  public SAMLProcessor processor(VelocityEngine velocityEngine,
                                 ParserPool parserPool,
                                 SpConfiguration spConfiguration,
                                 @Value("${sp.compare_endpoints}") boolean compareEndpoints) {
    ArtifactResolutionProfile artifactResolutionProfile = new ArtifactResolutionProfileImpl(httpClient());
    Collection<SAMLBinding> bindings = new ArrayList<>();
    bindings.add(httpRedirectDeflateBinding(parserPool));
    bindings.add(httpPostBinding(parserPool, velocityEngine, compareEndpoints));
    bindings.add(artifactBinding(parserPool, velocityEngine, artifactResolutionProfile));
    bindings.add(httpSOAP11Binding(parserPool));
    bindings.add(httpPAOS11Binding(parserPool));
    return new ConfigurableSAMLProcessor(bindings, spConfiguration);
  }

  @Bean
  public static SAMLBootstrap sAMLBootstrap() {
// Path: mujina-sp/src/main/java/mujina/api/SpConfiguration.java
// @Component
// @Getter
// @Setter
// public class SpConfiguration extends SharedConfiguration {
// 
//   private String defaultEntityId;
// 
//   private String defaultIdpSSOServiceURL;
//   private String idpSSOServiceURL;
//   private String defaultProtocolBinding;
//   private String protocolBinding;
//   private String defaultAssertionConsumerServiceURL;
//   private boolean defaultNeedsSigning;
//   private String assertionConsumerServiceURL;
//   private String spPrivateKey;
//   private String spCertificate;
// 
//   @Autowired
//   public SpConfiguration(JKSKeyManager keyManager,
//                          @Value("${sp.base_url}") String spBaseUrl,
//                          @Value("${sp.entity_id}") String defaultEntityId,
//                          @Value("${sp.single_sign_on_service_location}") String defaultIdpSSOServiceURL,
//                          @Value("${sp.acs_location_path}") String defaultAssertionConsumerServiceURLPath,
//                          @Value("${sp.protocol_binding}") String defaultProtocolBinding,
//                          @Value("${sp.private_key}") String spPrivateKey,
//                          @Value("${sp.certificate}") String spCertificate,
//                          @Value("${sp.needs_signing}") boolean needsSigning) {
//     super(keyManager);
//     this.setDefaultEntityId(defaultEntityId);
//     this.setDefaultIdpSSOServiceURL(defaultIdpSSOServiceURL);
//     this.setDefaultAssertionConsumerServiceURL(spBaseUrl + defaultAssertionConsumerServiceURLPath);
//     this.setDefaultProtocolBinding(defaultProtocolBinding);
//     this.setSpPrivateKey(spPrivateKey);
//     this.setSpCertificate(spCertificate);
//     this.setDefaultNeedsSigning(needsSigning);
//     reset();
//   }
// 
//   @Override
//   public void reset() {
//     setEntityId(defaultEntityId, false);
//     setNeedsSigning(defaultNeedsSigning);
//     resetKeyStore(defaultEntityId, spPrivateKey, spCertificate);
//     setIdpSSOServiceURL(defaultIdpSSOServiceURL);
//     setProtocolBinding(defaultProtocolBinding);
//     setAssertionConsumerServiceURL(defaultAssertionConsumerServiceURL);
//     setSignatureAlgorithm(getDefaultSignatureAlgorithm());
//   }
// 
// }
// 
// Path: mujina-common/src/main/java/mujina/saml/UpgradedSAMLBootstrap.java
// public class UpgradedSAMLBootstrap extends SAMLBootstrap {
// 
//   @Override
//   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//     super.postProcessBeanFactory(beanFactory);
//     BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
//     config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
//     config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
//   }
// }


// Path: mujina-sp/src/main/java/mujina/sp/SAMLConfig.java
import mujina.api.SpConfiguration;
import mujina.saml.UpgradedSAMLBootstrap;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.velocity.app.VelocityEngine;
import org.opensaml.common.SAMLException;
import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.xml.encryption.DecryptionException;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.validation.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.saml.SAMLBootstrap;
import org.springframework.security.saml.context.SAMLMessageContext;
import org.springframework.security.saml.log.SAMLDefaultLogger;
import org.springframework.security.saml.processor.HTTPArtifactBinding;
import org.springframework.security.saml.processor.HTTPPAOS11Binding;
import org.springframework.security.saml.processor.HTTPPostBinding;
import org.springframework.security.saml.processor.HTTPRedirectDeflateBinding;
import org.springframework.security.saml.processor.HTTPSOAP11Binding;
import org.springframework.security.saml.processor.SAMLBinding;
import org.springframework.security.saml.processor.SAMLProcessor;
import org.springframework.security.saml.websso.ArtifactResolutionProfile;
import org.springframework.security.saml.websso.ArtifactResolutionProfileImpl;
import org.springframework.security.saml.websso.WebSSOProfile;
import org.springframework.security.saml.websso.WebSSOProfileConsumer;
import org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl;
import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl;
import org.springframework.security.saml.websso.WebSSOProfileECPImpl;
import org.springframework.security.saml.websso.WebSSOProfileImpl;
import java.util.ArrayList;
import java.util.Collection;

  @Bean
  @Autowired
  public HTTPSOAP11Binding httpSOAP11Binding(ParserPool parserPool) {
    return new HTTPSOAP11Binding(parserPool);
  }

  @Bean
  @Autowired
  public HTTPPAOS11Binding httpPAOS11Binding(ParserPool parserPool) {
    return new HTTPPAOS11Binding(parserPool);
  }

  @Autowired
  @Bean
  public SAMLProcessor processor(VelocityEngine velocityEngine,
                                 ParserPool parserPool,
                                 SpConfiguration spConfiguration,
                                 @Value("${sp.compare_endpoints}") boolean compareEndpoints) {
    ArtifactResolutionProfile artifactResolutionProfile = new ArtifactResolutionProfileImpl(httpClient());
    Collection<SAMLBinding> bindings = new ArrayList<>();
    bindings.add(httpRedirectDeflateBinding(parserPool));
    bindings.add(httpPostBinding(parserPool, velocityEngine, compareEndpoints));
    bindings.add(artifactBinding(parserPool, velocityEngine, artifactResolutionProfile));
    bindings.add(httpSOAP11Binding(parserPool));
    bindings.add(httpPAOS11Binding(parserPool));
    return new ConfigurableSAMLProcessor(bindings, spConfiguration);
  }

  @Bean
  public static SAMLBootstrap sAMLBootstrap() {
    return new UpgradedSAMLBootstrap();