import java.util.zip.Inflater
import java.util.zip.InflaterInputStream

def extractPost(String value) {
    if (value == null) {
        return
    }
    String text
    if (value.startsWith("<")) {
        text = value
    }
    else {
        text = new String(value.decodeBase64())
    }
    def xml = new groovy.xml.XmlSlurper().parseText(text)
    // according to the SAML spec Issuer is optional but we need it for dispatching
    def issuer = xml.depthFirst().find { it -> it.name().equalsIgnoreCase("Issuer") }?.text()
    session.put("saml.inbound.issuer", issuer)
}

def extractQuery(String value) {
    byte[] d2 = Base64.getDecoder().decode(value)
    def d3 = new ByteArrayInputStream(d2)
    def d4 = new InflaterInputStream(d3, new Inflater(true))
    def xml = new groovy.xml.XmlSlurper().parse(d4)
    // according to the SAML spec Issuer is optional but we need it for dispatching
    def issuer = xml.depthFirst().find { it -> it.name().equalsIgnoreCase("Issuer") }?.text()
    session.put("saml.inbound.issuer", issuer)
}

def handleMessage(String name) {
    def value = inargs.get(name)
    def resource = request.getCurrentResource()
    def url = new URL(resource)
    def query = url.getQuery()
    if (query != null && query.contains(name)) {
        notes.put("saml.inbound.binding", "redirect")
        extractQuery(value)
    }
    else {
        notes.put("saml.inbound.binding", "post")
        extractPost(value)
    }
}

if (inargs.containsKey("SAMLResponse")) {
    handleMessage("SAMLResponse")
}
else if (inargs.containsKey("SAMLRequest")) {
    handleMessage("SAMLRequest")
}
else if (inargs.containsKey("soapheader")) {
    handleMessage("soapheader")
}
else { // no incoming message.
    if (request.getCurrentResource().matches('^http[s]?\u003A//[^/]+/SAML2/ACS/.*$')) {
        LOG.debug("denying request without incoming message on ACS path")
        return // giving up
    }
}

response.setResult('ok')
