Skip to content

Commit

Permalink
Merge pull request #60 from swedenconnect/feature/IS-59-response-acce…
Browse files Browse the repository at this point in the history
…ssible

IS-59 Added getResponse to ResponseProcessingResult
  • Loading branch information
martin-lindstrom committed Apr 22, 2024
2 parents 4bb8467 + 00eecee commit 72e7483
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 42 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ See <https://github.com/swedenconnect/opensaml-security-ext>.

---

Copyright &copy; 2016-2023, [Sweden Connect](https://swedenconnect.se). Licensed under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).
Copyright &copy; 2016-2024, [Sweden Connect](https://swedenconnect.se). Licensed under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).
20 changes: 13 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>se.swedenconnect.opensaml</groupId>
<artifactId>opensaml-addons</artifactId>
<packaging>jar</packaging>
<version>2.0.2</version>
<version>2.0.3-SNAPSHOT</version>

<name>Sweden Connect :: OpenSAML 5.X utility extensions</name>
<description>OpenSAML 5.X utility extension library</description>
Expand Down Expand Up @@ -46,8 +46,8 @@

<opensaml.version>5.0.0</opensaml.version>
<shib.support.version>9.0.0</shib.support.version>
<slf4j.version>2.0.9</slf4j.version>
<jackson.version>2.15.2</jackson.version>
<slf4j.version>2.0.12</slf4j.version>
<jackson.version>2.17.0</jackson.version>
</properties>

<repositories>
Expand Down Expand Up @@ -106,6 +106,12 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>

</dependencies>
Expand Down Expand Up @@ -142,28 +148,28 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
<version>3.14.0</version>
</dependency>

<!-- For testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<version>5.10.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.10.0</version>
<version>5.10.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.5.0</version>
<version>5.11.0</version>
<scope>test</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public final class LibraryVersion {

private static final int MAJOR = 2;
private static final int MINOR = 0;
private static final int PATCH = 2;
private static final int PATCH = 3;

/**
* Global serialization value for library classes.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2023 Sweden Connect
* Copyright 2016-2024 Sweden Connect
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,10 +21,12 @@
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Attribute;
import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.Response;

/**
* Interface that describes the result of a response processing operation. It contains the actual {@code Assertion} that
* really holds all information, but also "easy to access" methods of the elements that are of most interest.
* Interface that describes the result of a response processing operation. It contains the actual {@link Response} and
* {@link Assertion} objects that really holds all information, but also "easy to access" methods of the elements that
* are of most interest.
* <p>
* Note that only successful responses are represented. Error responses are represented using the
* {@link ResponseStatusErrorException}.
Expand Down Expand Up @@ -55,6 +57,13 @@ public interface ResponseProcessingResult {
*/
Instant getIssueInstant();

/**
* Gets the actual {@link Response} object.
*
* @return the {@link Response}
*/
Response getResponse();

/**
* Gets the {@code Assertion} from the response.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Attribute;
import org.opensaml.saml.saml2.core.AttributeStatement;
import org.opensaml.saml.saml2.core.AuthnContext;
import org.opensaml.saml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml.saml2.core.AuthnStatement;
import org.opensaml.saml.saml2.core.Issuer;
import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.Response;
Expand All @@ -35,14 +39,8 @@
*/
public class ResponseProcessingResultImpl implements ResponseProcessingResult {

/** The response ID. */
private final String responseId;

/** The InResponseTo attribute of the response. */
private final String inResponseTo;

/** The issue instant. */
private final Instant issueInstant;
/** The response. */
private final Response response;

/** The assertion. */
private final Assertion assertion;
Expand All @@ -54,31 +52,33 @@ public class ResponseProcessingResultImpl implements ResponseProcessingResult {
* @param assertion the Assertion
*/
public ResponseProcessingResultImpl(final Response response, final Assertion assertion) {
this.responseId = Optional.ofNullable(response).map(Response::getID)
.orElseThrow(() -> new NullPointerException("response is required"));
this.inResponseTo = Optional.ofNullable(response).map(Response::getInResponseTo)
.orElseThrow(() -> new NullPointerException("response is required"));
this.issueInstant = Optional.ofNullable(response).map(Response::getIssueInstant)
.orElseThrow(() -> new NullPointerException("response is required"));
this.response = Objects.requireNonNull(response, "response is required");
this.assertion = Objects.requireNonNull(assertion, "assertion is required");
}

/** {@inheritDoc} */
@Override
public Response getResponse() {
return this.response;
}


/** {@inheritDoc} */
@Override
public String getResponseId() {
return this.responseId;
return this.response.getID();
}

/** {@inheritDoc} */
@Override
public String getInResponseTo() {
return this.inResponseTo;
return this.response.getInResponseTo();
}

/** {@inheritDoc} */
@Override
public Instant getIssueInstant() {
return this.issueInstant;
return this.response.getIssueInstant();
}

/** {@inheritDoc} */
Expand All @@ -90,30 +90,31 @@ public Assertion getAssertion() {
/** {@inheritDoc} */
@Override
public List<Attribute> getAttributes() {
try {
return Collections.unmodifiableList(this.assertion.getAttributeStatements().get(0).getAttributes());
}
catch (NullPointerException | IndexOutOfBoundsException e) {
return Collections.emptyList();
}
return Collections.unmodifiableList(this.assertion.getAttributeStatements().stream()
.map(AttributeStatement::getAttributes)
.findFirst()
.orElseGet(() -> Collections.emptyList()));
}

/** {@inheritDoc} */
@Override
public String getAuthnContextClassUri() {
try {
return this.assertion.getAuthnStatements().get(0).getAuthnContext().getAuthnContextClassRef().getURI();
}
catch (NullPointerException e) {
return null;
}
return this.assertion.getAuthnStatements().stream()
.map(AuthnStatement::getAuthnContext)
.map(AuthnContext::getAuthnContextClassRef)
.map(AuthnContextClassRef::getURI)
.findFirst()
.orElse(null);
}

/** {@inheritDoc} */
@Override
public Instant getAuthnInstant() {

Instant authnInstant = this.assertion.getAuthnStatements().get(0).getAuthnInstant();
final Instant authnInstant = this.assertion.getAuthnStatements().stream()
.map(AuthnStatement::getAuthnInstant)
.findFirst()
.orElseGet(() -> Instant.now());

// We have already checked the validity of the authentication instant, but if it is
// after the current time it means that it is within the allowed clock skew. If so,
Expand Down

0 comments on commit 72e7483

Please sign in to comment.