// Path: mujina-sp/src/main/java/nl/surfnet/mujina/model/SpConfiguration.java
// public interface SpConfiguration extends CommonConfiguration {
//     public void setSingleSignOnServiceURL(String singleSignOnServiceURL);
//     public String getSingleSignOnServiceURL();
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/saml/AuthnRequestGenerator.java
// public class AuthnRequestGenerator {
// 
//     private XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
// 
//     private final String issuingEntityName;
//     private final TimeService timeService;
//     private final IDService idService;
//     private IssuerGenerator issuerGenerator;
// 
//     public AuthnRequestGenerator(String issuingEntityName, TimeService timeService, IDService idService) {
//         super();
//         this.issuingEntityName = issuingEntityName;
//         this.timeService = timeService;
//         this.idService = idService;
// 
//         issuerGenerator = new IssuerGenerator(issuingEntityName);
//     }
// 
//     public AuthnRequest generateAuthnRequest(String destination, String responseLocation) {
// 
//         AuthnRequestBuilder authnRequestBuilder = (AuthnRequestBuilder) builderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
// 
//         AuthnRequest authnRequest = authnRequestBuilder.buildObject();
// 
//         authnRequest.setAssertionConsumerServiceURL(responseLocation);
//         authnRequest.setID(idService.generateID());
//         authnRequest.setIssueInstant(timeService.getCurrentDateTime());
//         authnRequest.setDestination(destination);
// 
//         authnRequest.setIssuer(issuerGenerator.generateIssuer());
// 
//         return authnRequest;
//     }
// 
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/saml/BindingAdapter.java
// public interface BindingAdapter {
// 
//     public void sendSAMLMessage(SignableSAMLObject samlMessage, Endpoint endpoint, Credential signingCredential, HttpServletResponse response) throws MessageEncodingException;
// 
//     public SAMLMessageContext extractSAMLMessageContext(HttpServletRequest request) throws MessageDecodingException, SecurityException;
// 
//     public String extractSAMLMessage(HttpServletRequest request);
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/saml/xml/EndpointGenerator.java
// public class EndpointGenerator {
// 
//     private final static Logger logger = LoggerFactory.getLogger(EndpointGenerator.class);
// 
//     private XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
// 
//     public Endpoint generateEndpoint(QName service, String location, String responseLocation) {
// 
//         logger.debug("end point service: {}", service);
//         logger.debug("end point location: {}", location);
//         logger.debug("end point responseLocation: {}", responseLocation);
// 
//         SAMLObjectBuilder<Endpoint> endpointBuilder = (SAMLObjectBuilder<Endpoint>) builderFactory.getBuilder(service);
//         Endpoint samlEndpoint = endpointBuilder.buildObject();
// 
//         samlEndpoint.setLocation(location);
// 
//         // this does not have to be set
//         if (StringUtils.isNotEmpty(responseLocation))
//             samlEndpoint.setResponseLocation(responseLocation);
// 
//         return samlEndpoint;
//     }
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/util/IDService.java
// public class IDService {
// 
//     public String generateID() {
//         return UUID.randomUUID().toString();
//     }
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/util/TimeService.java
// public class TimeService {
// 
//     public DateTime getCurrentDateTime() {
//         return new DateTime();
//     }
// 
// }


import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.Validate;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.metadata.Endpoint;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.xml.security.*;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.credential.CredentialResolver;
import org.opensaml.xml.security.credential.UsageType;
import org.opensaml.xml.security.criteria.EntityIDCriteria;
import org.opensaml.xml.security.criteria.UsageCriteria;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import nl.surfnet.mujina.model.SpConfiguration;
import nl.surfnet.mujina.saml.AuthnRequestGenerator;
import nl.surfnet.mujina.saml.BindingAdapter;
import nl.surfnet.mujina.saml.xml.EndpointGenerator;
import nl.surfnet.mujina.util.IDService;
import nl.surfnet.mujina.util.TimeService;
        super();
        this.timeService = timeService;
        this.idService = idService;
    }

    @Required
    public void setAssertionConsumerServiceURL(String assertionConsumerServiceURL) {
        this.assertionConsumerServiceURL = assertionConsumerServiceURL;
    }

    @Required
    public void setBindingAdapter(BindingAdapter bindingAdapter) {
        this.bindingAdapter = bindingAdapter;
    }


    @Required
    public void setCredentialResolver(CredentialResolver credentialResolver) {
        this.credentialResolver = credentialResolver;
    }

    public void setConfiguration(final SpConfiguration spConfiguration) {
        this.spConfiguration = spConfiguration;
    }

    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException authException) throws IOException, ServletException {

// Path: mujina-sp/src/main/java/nl/surfnet/mujina/model/SpConfiguration.java
// public interface SpConfiguration extends CommonConfiguration {
//     public void setSingleSignOnServiceURL(String singleSignOnServiceURL);
//     public String getSingleSignOnServiceURL();
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/saml/AuthnRequestGenerator.java
// public class AuthnRequestGenerator {
// 
//     private XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
// 
//     private final String issuingEntityName;
//     private final TimeService timeService;
//     private final IDService idService;
//     private IssuerGenerator issuerGenerator;
// 
//     public AuthnRequestGenerator(String issuingEntityName, TimeService timeService, IDService idService) {
//         super();
//         this.issuingEntityName = issuingEntityName;
//         this.timeService = timeService;
//         this.idService = idService;
// 
//         issuerGenerator = new IssuerGenerator(issuingEntityName);
//     }
// 
//     public AuthnRequest generateAuthnRequest(String destination, String responseLocation) {
// 
//         AuthnRequestBuilder authnRequestBuilder = (AuthnRequestBuilder) builderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
// 
//         AuthnRequest authnRequest = authnRequestBuilder.buildObject();
// 
//         authnRequest.setAssertionConsumerServiceURL(responseLocation);
//         authnRequest.setID(idService.generateID());
//         authnRequest.setIssueInstant(timeService.getCurrentDateTime());
//         authnRequest.setDestination(destination);
// 
//         authnRequest.setIssuer(issuerGenerator.generateIssuer());
// 
//         return authnRequest;
//     }
// 
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/saml/BindingAdapter.java
// public interface BindingAdapter {
// 
//     public void sendSAMLMessage(SignableSAMLObject samlMessage, Endpoint endpoint, Credential signingCredential, HttpServletResponse response) throws MessageEncodingException;
// 
//     public SAMLMessageContext extractSAMLMessageContext(HttpServletRequest request) throws MessageDecodingException, SecurityException;
// 
//     public String extractSAMLMessage(HttpServletRequest request);
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/saml/xml/EndpointGenerator.java
// public class EndpointGenerator {
// 
//     private final static Logger logger = LoggerFactory.getLogger(EndpointGenerator.class);
// 
//     private XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
// 
//     public Endpoint generateEndpoint(QName service, String location, String responseLocation) {
// 
//         logger.debug("end point service: {}", service);
//         logger.debug("end point location: {}", location);
//         logger.debug("end point responseLocation: {}", responseLocation);
// 
//         SAMLObjectBuilder<Endpoint> endpointBuilder = (SAMLObjectBuilder<Endpoint>) builderFactory.getBuilder(service);
//         Endpoint samlEndpoint = endpointBuilder.buildObject();
// 
//         samlEndpoint.setLocation(location);
// 
//         // this does not have to be set
//         if (StringUtils.isNotEmpty(responseLocation))
//             samlEndpoint.setResponseLocation(responseLocation);
// 
//         return samlEndpoint;
//     }
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/util/IDService.java
// public class IDService {
// 
//     public String generateID() {
//         return UUID.randomUUID().toString();
//     }
// 
// }
// 
// Path: mujina-common/src/main/java/nl/surfnet/mujina/util/TimeService.java
// public class TimeService {
// 
//     public DateTime getCurrentDateTime() {
//         return new DateTime();
//     }
// 
// }


// Path: mujina-sp/src/main/java/nl/surfnet/mujina/spring/SAMLAuthenticationEntryPoint.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.Validate;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.metadata.Endpoint;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.xml.security.*;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.credential.CredentialResolver;
import org.opensaml.xml.security.credential.UsageType;
import org.opensaml.xml.security.criteria.EntityIDCriteria;
import org.opensaml.xml.security.criteria.UsageCriteria;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import nl.surfnet.mujina.model.SpConfiguration;
import nl.surfnet.mujina.saml.AuthnRequestGenerator;
import nl.surfnet.mujina.saml.BindingAdapter;
import nl.surfnet.mujina.saml.xml.EndpointGenerator;
import nl.surfnet.mujina.util.IDService;
import nl.surfnet.mujina.util.TimeService;

        super();
        this.timeService = timeService;
        this.idService = idService;
    }

    @Required
    public void setAssertionConsumerServiceURL(String assertionConsumerServiceURL) {
        this.assertionConsumerServiceURL = assertionConsumerServiceURL;
    }

    @Required
    public void setBindingAdapter(BindingAdapter bindingAdapter) {
        this.bindingAdapter = bindingAdapter;
    }


    @Required
    public void setCredentialResolver(CredentialResolver credentialResolver) {
        this.credentialResolver = credentialResolver;
    }

    public void setConfiguration(final SpConfiguration spConfiguration) {
        this.spConfiguration = spConfiguration;
    }

    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException authException) throws IOException, ServletException {

        AuthnRequestGenerator authnRequestGenerator = new AuthnRequestGenerator(spConfiguration.getEntityID(), timeService, idService);