Skip to content

Commit 11bb45d

Browse files
committed
Improve LogoutResponse API to match LogoutRequest/AuthnRequest ones
This introduces LogoutResponseParams and allows to make the whole API coherent when building outgoing SAML messages. The Auth factories benefit from this as well, because they now share a common construction and usage pattern.
1 parent abd6326 commit 11bb45d

File tree

5 files changed

+425
-84
lines changed

5 files changed

+425
-84
lines changed

core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java

+100-36
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,6 @@ public class LogoutResponse {
6969
*/
7070
private String currentUrl;
7171

72-
/**
73-
* The inResponseTo attribute of the Logout Request
74-
*/
75-
private String inResponseTo;
76-
7772
/**
7873
* Time when the Logout Request was created
7974
*/
@@ -85,12 +80,8 @@ public class LogoutResponse {
8580
private Exception validationException;
8681

8782
/**
88-
* The respone status code and messages
89-
*/
90-
private SamlResponseStatus responseStatus;
91-
92-
/**
93-
* Constructs the LogoutResponse object.
83+
* Constructs the LogoutResponse object when a received response should be
84+
* extracted from the HTTP request and parsed.
9485
*
9586
* @param settings
9687
* OneLogin_Saml2_Settings
@@ -115,6 +106,25 @@ public LogoutResponse(Saml2Settings settings, HttpRequest request) {
115106
logoutResponseDocument = Util.loadXML(logoutResponseString);
116107
}
117108
}
109+
110+
/**
111+
* Constructs the LogoutResponse object when a new response should be generated
112+
* and sent.
113+
*
114+
* @param settings
115+
* OneLogin_Saml2_Settings
116+
* @param params
117+
* a set of logout response input parameters that shape the
118+
* request to create
119+
*/
120+
public LogoutResponse(Saml2Settings settings, LogoutResponseParams params) {
121+
this.settings = settings;
122+
this.request = null;
123+
id = Util.generateUniqueID(settings.getUniqueIDPrefix());
124+
issueInstant = Calendar.getInstance();
125+
StrSubstitutor substitutor = generateSubstitutor(params, settings);
126+
this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), params, settings);
127+
}
118128

119129
/**
120130
* @return the base64 encoded unsigned Logout Response (deflated or not)
@@ -355,21 +365,33 @@ protected NodeList query (String query) throws XPathExpressionException {
355365
return Util.query(this.logoutResponseDocument, query, null);
356366
}
357367

358-
/**
359-
* Generates a Logout Response XML string.
360-
*
361-
* @param inResponseTo
362-
* InResponseTo attribute value to bet set at the Logout Response.
368+
/**
369+
* Generates a Logout Response XML string.
370+
*
371+
* @param inResponseTo
372+
* InResponseTo attribute value to bet set at the Logout Response.
363373
* @param responseStatus
364-
* SamlResponseStatus response status to be set on the LogoutResponse
365-
*/
374+
* SamlResponseStatus response status to be set on the
375+
* LogoutResponse
376+
* @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)}
377+
* instead, in which case this method becomes completely useless;
378+
* indeed, invoking this method in an outgoing logout response
379+
* scenario will cause the response parameters specified at
380+
* construction time (<code>inResponseTo</code> and
381+
* <code>responseStatus</code>) to be overwritten, as well as its
382+
* generated id and issue instant; on the other hand invoking this
383+
* method in a received logout response scenario does not make sense
384+
* at all (and in that case
385+
* {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be
386+
* used instead)
387+
*/
388+
@Deprecated
366389
public void build(String inResponseTo, SamlResponseStatus responseStatus) {
367390
id = Util.generateUniqueID(settings.getUniqueIDPrefix());
368391
issueInstant = Calendar.getInstance();
369-
this.inResponseTo = inResponseTo;
370-
371-
StrSubstitutor substitutor = generateSubstitutor(settings, responseStatus);
372-
this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), settings);
392+
final LogoutResponseParams params = new LogoutResponseParams(inResponseTo, responseStatus);
393+
StrSubstitutor substitutor = generateSubstitutor(params, settings);
394+
this.logoutResponseString = postProcessXml(substitutor.replace(getLogoutResponseTemplate()), params, settings);
373395
}
374396

375397
/**
@@ -379,24 +401,61 @@ public void build(String inResponseTo, SamlResponseStatus responseStatus) {
379401
* InResponseTo attribute value to bet set at the Logout Response.
380402
* @param statusCode
381403
* String StatusCode to be set on the LogoutResponse
404+
* @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)}
405+
* instead, in which case this method becomes completely useless;
406+
* indeed, invoking this method in an outgoing logout response
407+
* scenario will cause the response parameters specified at
408+
* construction time (<code>inResponseTo</code> and
409+
* <code>responseStatus</code>) to be overwritten, as well as its
410+
* generated id and issue instant; on the other hand invoking this
411+
* method in a received logout response scenario does not make sense
412+
* at all (and in that case
413+
* {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be
414+
* used instead)
382415
*/
416+
@Deprecated
383417
public void build(String inResponseTo, String statusCode) {
384418
build(inResponseTo, new SamlResponseStatus(statusCode));
385419
}
386420

387-
/**
388-
* Generates a Logout Response XML string.
389-
*
390-
* @param inResponseTo
391-
* InResponseTo attribute value to bet set at the Logout Response.
392-
*/
421+
/**
422+
* Generates a Logout Response XML string.
423+
*
424+
* @param inResponseTo
425+
* InResponseTo attribute value to bet set at the Logout Response.
426+
* @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)}
427+
* instead, in which case this method becomes completely useless;
428+
* indeed, invoking this method in an outgoing logout response
429+
* scenario will cause the response parameters specified at
430+
* construction time (<code>inResponseTo</code> and
431+
* <code>responseStatus</code>) to be overwritten, as well as its
432+
* generated id and issue instant; on the other hand invoking this
433+
* method in a received logout response scenario does not make sense
434+
* at all (and in that case
435+
* {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be
436+
* used instead)
437+
*/
438+
@Deprecated
393439
public void build(String inResponseTo) {
394440
build(inResponseTo, Constants.STATUS_SUCCESS);
395441
}
396442

397-
/**
398-
* Generates a Logout Response XML string.
399-
*/
443+
/**
444+
* Generates a Logout Response XML string.
445+
*
446+
* @deprecated use {@link #LogoutResponse(Saml2Settings, LogoutResponseParams)}
447+
* instead, in which case this method becomes completely useless;
448+
* indeed, invoking this method in an outgoing logout response
449+
* scenario will cause the response parameters specified at
450+
* construction time (<code>inResponseTo</code> and
451+
* <code>responseStatus</code>) to be overwritten, as well as its
452+
* generated id and issue instant; on the other hand invoking this
453+
* method in a received logout response scenario does not make sense
454+
* at all (and in that case
455+
* {@link #LogoutResponse(Saml2Settings, HttpRequest)} should be
456+
* used instead)
457+
*/
458+
@Deprecated
400459
public void build() {
401460
build(null);
402461
}
@@ -412,26 +471,29 @@ public void build() {
412471
* @param logoutResponseXml
413472
* the XML produced for this LogoutResponse by the standard
414473
* implementation provided by {@link LogoutResponse}
474+
* @param params
475+
* the logout request input parameters
415476
* @param settings
416477
* the settings
417478
* @return the post-processed XML for this LogoutResponse, which will then be
418479
* returned by any call to {@link #getLogoutResponseXml()}
419480
*/
420-
protected String postProcessXml(final String logoutResponseXml, final Saml2Settings settings) {
481+
protected String postProcessXml(final String logoutResponseXml, final LogoutResponseParams params,
482+
final Saml2Settings settings) {
421483
return logoutResponseXml;
422484
}
423485

424486
/**
425487
* Substitutes LogoutResponse variables within a string by values.
426488
*
489+
* @param params
490+
* the logout response input parameters
427491
* @param settings
428-
* Saml2Settings object. Setting data
429-
* @param responseStatus
430-
* SamlResponseStatus response status to be set on the LogoutResponse
492+
* Saml2Settings object. Setting data
431493
*
432494
* @return the StrSubstitutor object of the LogoutResponse
433495
*/
434-
private StrSubstitutor generateSubstitutor(Saml2Settings settings, SamlResponseStatus responseStatus) {
496+
private StrSubstitutor generateSubstitutor(LogoutResponseParams params, Saml2Settings settings) {
435497
Map<String, String> valueMap = new HashMap<String, String>();
436498

437499
valueMap.put("id", Util.toXml(id));
@@ -447,12 +509,14 @@ private StrSubstitutor generateSubstitutor(Saml2Settings settings, SamlResponseS
447509
valueMap.put("destinationStr", destinationStr);
448510

449511
String inResponseStr = "";
512+
final String inResponseTo = params.getInResponseTo();
450513
if (inResponseTo != null) {
451514
inResponseStr = " InResponseTo=\"" + Util.toXml(inResponseTo) + "\"";
452515
}
453516
valueMap.put("inResponseStr", inResponseStr);
454517

455518
StringBuilder statusStr = new StringBuilder("<samlp:StatusCode ");
519+
final SamlResponseStatus responseStatus = params.getResponseStatus();
456520
if (responseStatus != null) {
457521
String statusCode = responseStatus.getStatusCode();
458522
if (statusCode != null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.onelogin.saml2.logout;
2+
3+
import com.onelogin.saml2.model.SamlResponseStatus;
4+
import com.onelogin.saml2.util.Constants;
5+
6+
/**
7+
* Input parameters for a SAML 2 logout response.
8+
*/
9+
public class LogoutResponseParams {
10+
11+
/**
12+
* Id of the logout request the response refers to.
13+
*/
14+
private final String inResponseTo;
15+
16+
/**
17+
* Response status.
18+
*/
19+
private final SamlResponseStatus responseStatus;
20+
21+
/**
22+
* Creates a logout response with no <code>inResponseTo</code> attribute and a
23+
* response status with a top-level {@link Constants#STATUS_SUCCESS} status
24+
* code.
25+
*/
26+
public LogoutResponseParams() {
27+
this((String) null);
28+
}
29+
30+
/**
31+
* Creates a logout response with a response status with a top-level
32+
* {@link Constants#STATUS_SUCCESS} status code.
33+
*
34+
* @param inResponseTo
35+
* the id of the logout request the response refers to; may be
36+
* <code>null</code> if such id cannot be determined (possibly
37+
* because the request is malformed)
38+
*/
39+
public LogoutResponseParams(String inResponseTo) {
40+
this(inResponseTo, Constants.STATUS_SUCCESS);
41+
}
42+
43+
/**
44+
* Creates a logout response.
45+
*
46+
* @param inResponseTo
47+
* the id of the logout request the response refers to; may be
48+
* <code>null</code> if such id cannot be determined (possibly
49+
* because the request is malformed)
50+
* @param statusCode
51+
* the top-level status code code to set on the response
52+
*/
53+
public LogoutResponseParams(String inResponseTo, String statusCode) {
54+
this(inResponseTo, new SamlResponseStatus(statusCode));
55+
}
56+
57+
/**
58+
* Creates a logout response.
59+
*
60+
* @param inResponseTo
61+
* the id of the logout request the response refers to; may be
62+
* <code>null</code> if such id cannot be determined (possibly
63+
* because the request is malformed)
64+
* @param responseStatus
65+
* the response status; should not be <code>null</code>
66+
* @throws NullPointerException
67+
* if the specified response status is <code>null</code>
68+
*/
69+
public LogoutResponseParams(String inResponseTo, SamlResponseStatus responseStatus) throws NullPointerException {
70+
this.inResponseTo = inResponseTo;
71+
this.responseStatus = responseStatus;
72+
if (responseStatus == null)
73+
throw new NullPointerException("response status must not be null");
74+
}
75+
76+
/**
77+
* Create a set of logout request input parameters, by copying them from another
78+
* set.
79+
*
80+
* @param source
81+
* the source set of logout request input parameters
82+
*/
83+
protected LogoutResponseParams(LogoutResponseParams source) {
84+
this.inResponseTo = source.getInResponseTo();
85+
this.responseStatus = source.getResponseStatus();
86+
}
87+
88+
/**
89+
* Returns the response status.
90+
*
91+
* @return the response status
92+
*/
93+
public SamlResponseStatus getResponseStatus() {
94+
return responseStatus;
95+
}
96+
97+
/**
98+
* Returns the id of the logout request this response refers to.
99+
*
100+
* @return the <code>inResponseTo</code>
101+
*/
102+
public String getInResponseTo() {
103+
return inResponseTo;
104+
}
105+
}

0 commit comments

Comments
 (0)