[java-plugin-shibd] 01/02: Updates to sealer operation contract.
Codeberg
noreply at shibboleth.net
Mon Sep 21 19:49:54 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd/commit/49f774fb0773c102db824fd1abbf98af918aa6d6
commit 49f774fb0773c102db824fd1abbf98af918aa6d6
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Mon Sep 21 15:49:26 2026 -0400
Updates to sealer operation contract.
---
.../net/shibboleth/sp/flows/SealerFlowTest.java | 58 +++++++++----
.../sp/profile/impl/DoSealerOperation.java | 77 +++++++++---------
.../sp/profile/impl/DoSealerOperationTest.java | 94 +++++++++-------------
3 files changed, 119 insertions(+), 110 deletions(-)
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java
index c8add88..141b437 100644
--- a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java
@@ -73,10 +73,10 @@ public class SealerFlowTest extends AbstractSPFlowTest {
}
/**
- * Test wrap operation with no input.
+ * Test missing operation.
*/
@Test
- public void testWrapNoInput() {
+ public void testMissingOperation() {
setDefaultAuth();
request.setMethod("POST");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -86,16 +86,35 @@ public class SealerFlowTest extends AbstractSPFlowTest {
}
/**
- * Test wrap operation with pre-expired data.
+ * Test encrypt operation with no input.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testEncryptNoInput() throws IOException {
+ setDefaultAuth();
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoSealerOperation.OP).string("E");
+ setRequest("POST", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+ assertOutputMessageEvent(result, EventIds.INVALID_MESSAGE);
+ }
+
+ /**
+ * Test encrypt operation with pre-expired data.
*
* @throws IOException
* @throws DataSealerException
*/
@Test
- public void testWrapExpired() throws IOException, DataSealerException {
+ public void testEncryptExpired() throws IOException, DataSealerException {
setDefaultAuth();
final DDF input = new DDF("sealer").structure();
+ input.addmember(DoSealerOperation.OP).string("E");
input.addmember(DoSealerOperation.VALUE).string(TEST_VALUE);
input.addmember(DoSealerOperation.EXP).longinteger(Instant.now().minusSeconds(3600).toEpochMilli() / 1000);
setRequest("POST", input);
@@ -117,16 +136,17 @@ public class SealerFlowTest extends AbstractSPFlowTest {
}
/**
- * Test wrap operation success.
+ * Test encrypt operation success.
*
* @throws IOException
* @throws DataSealerException
*/
@Test
- public void testWrapSuccess() throws IOException, DataSealerException {
+ public void testEncryptSuccess() throws IOException, DataSealerException {
setDefaultAuth();
final DDF input = new DDF("sealer").structure();
+ input.addmember(DoSealerOperation.OP).string("E");
input.addmember(DoSealerOperation.VALUE).string(TEST_VALUE);
setRequest("POST", input);
@@ -142,12 +162,18 @@ public class SealerFlowTest extends AbstractSPFlowTest {
}
/**
- * Test unwrap operation with no input.
+ * Test decrypt operation with no input.
+ *
+ * @throws IOException
*/
@Test
- public void testUnwrapNoInput() {
+ public void testDecryptNoInput() throws IOException {
setDefaultAuth();
- request.setMethod("GET");
+
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoSealerOperation.OP).string("D");
+ setRequest("POST", input);
+
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
@@ -155,20 +181,21 @@ public class SealerFlowTest extends AbstractSPFlowTest {
}
/**
- * Test unwrap operation with pre-expired data.
+ * Test decrypt operation with pre-expired data.
*
* @throws IOException
* @throws DataSealerException
*/
@Test
- public void testUnrrapExpired() throws IOException, DataSealerException {
+ public void testDecryptExpired() throws IOException, DataSealerException {
setDefaultAuth();
final String wrapped = getDataSealer().wrap(AGENT_ID + '!' + TEST_VALUE, Instant.now().minusSeconds(3600));
final DDF input = new DDF("sealer").structure();
+ input.addmember(DoSealerOperation.OP).string("D");
input.addmember(DoSealerOperation.VALUE).string(wrapped);
- setRequest("GET", input);
+ setRequest("POST", input);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
@@ -177,20 +204,21 @@ public class SealerFlowTest extends AbstractSPFlowTest {
}
/**
- * Test unwrap operation success.
+ * Test decrypt operation success.
*
* @throws IOException
* @throws DataSealerException
*/
@Test
- public void testUnwrapSuccess() throws IOException, DataSealerException {
+ public void testDecryptSuccess() throws IOException, DataSealerException {
setDefaultAuth();
final String wrapped = getDataSealer().wrap(AGENT_ID + '!' + TEST_VALUE, Instant.now().plusSeconds(3600));
final DDF input = new DDF("sealer").structure();
+ input.addmember(DoSealerOperation.OP).string("D");
input.addmember(DoSealerOperation.VALUE).string(wrapped);
- setRequest("GET", input);
+ setRequest("POST", input);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSealerOperation.java b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSealerOperation.java
index 0eb4b97..ff48ad4 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSealerOperation.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSealerOperation.java
@@ -35,7 +35,6 @@ import net.shibboleth.shared.security.DataSealerException;
import net.shibboleth.sp.Agent;
import net.shibboleth.sp.ddf.DDF;
import net.shibboleth.sp.profile.AbstractAgentAction;
-import jakarta.servlet.http.HttpServletRequest;
/**
* Action that implements a remote API for SP agents to leverage a {@link DataSealer}.
@@ -43,7 +42,7 @@ import jakarta.servlet.http.HttpServletRequest;
* <p>All contexts are prefixed with {@link Agent#getId} to prevent conflicts across agents.</p>
*
* @event {@link EventIds#PROCEED_EVENT_ID}
- * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link EventIds#INVALID_MSG_CTX}
* @event {@link EventIds#ACCESS_DENIED}
* @event {@link EventIds#INVALID_MESSAGE}
* @event {@link EventIds#MESSAGE_PROC_ERROR}
@@ -52,6 +51,9 @@ import jakarta.servlet.http.HttpServletRequest;
*/
public class DoSealerOperation extends AbstractAgentAction {
+ /** Member for operation code. */
+ @Nonnull @NotEmpty public static final String OP = "op";
+
/** Member for storage value. */
@Nonnull @NotEmpty public static final String VALUE = "value";
@@ -97,10 +99,6 @@ public class DoSealerOperation extends AbstractAgentAction {
if (!super.doPreExecute(profileRequestContext)) {
return false;
- } else if (getHttpServletRequest() == null) {
- log.warn("{} No HttpServletRequest available", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
- return false;
}
input = ensureAgentRequestContext().getInput();
@@ -113,7 +111,7 @@ public class DoSealerOperation extends AbstractAgentAction {
output = ensureAgentRequestContext().getOutput();
if (output == null || !output.isstruct()) {
log.warn("{} Invalid or missing output message", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
return false;
}
@@ -124,14 +122,14 @@ public class DoSealerOperation extends AbstractAgentAction {
@Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
try {
- final HttpServletRequest request = ensureHttpServletRequest();
+ final String op = input.getmember(OP).string();
- if ("GET".equals(request.getMethod())) {
- doUnwrap(profileRequestContext);
- } else if ("POST".equals(request.getMethod())) {
+ if ("E".equals(op)) {
doWrap(profileRequestContext);
+ } else if ("D".equals(op)) {
+ doUnwrap(profileRequestContext);
} else {
- log.warn("{} Invalid method: {}", getLogPrefix(), request.getMethod());
+ log.warn("{} Invalid {} value: {}", getLogPrefix(), OP, op);
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
}
} catch (final DataSealerException e) {
@@ -140,6 +138,30 @@ public class DoSealerOperation extends AbstractAgentAction {
}
}
+ /**
+ * Perform wrap operation.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @throws DataSealerException if an error is raised
+ */
+ private void doWrap(@Nonnull final ProfileRequestContext profileRequestContext) throws DataSealerException {
+
+ String unwrapped = input.getmember(VALUE).string();
+ if (unwrapped == null) {
+ log.warn("{} No {} parameter supplied for encryption operation", getLogPrefix(), VALUE);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+ return;
+ }
+
+ final Long exp = input.getmember(EXP).longinteger();
+
+ final String wrapped = dataSealer.wrap(ensureAgent().getId() + '!' + unwrapped,
+ exp != null ? Instant.ofEpochSecond(exp) : null);
+
+ output.addmember(VALUE).string(wrapped);
+ }
+
/**
* Perform unwrap operation.
*
@@ -151,7 +173,7 @@ public class DoSealerOperation extends AbstractAgentAction {
final String wrapped = input.getmember(VALUE).string();
if (wrapped == null) {
- log.warn("{} No value parameter supplied for unwrap operation", getLogPrefix());
+ log.warn("{} No {} parameter supplied for decryption operation", getLogPrefix(), VALUE);
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
return;
}
@@ -160,7 +182,7 @@ public class DoSealerOperation extends AbstractAgentAction {
try {
unwrapped = dataSealer.unwrap(wrapped);
} catch (final DataExpiredException e) {
- log.info("{} Decrypted data was expired", getLogPrefix());
+ log.info("{} Decrypted data has expired", getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_EXPIRED);
return;
}
@@ -169,34 +191,9 @@ public class DoSealerOperation extends AbstractAgentAction {
if (unwrapped.startsWith(prefix)) {
output.addmember(VALUE).string(unwrapped.substring(prefix.length()));
} else {
- log.warn("{} Encrypted data was not created by this agent", getLogPrefix());
+ log.warn("{} Encrypted data was not created by this Agent", getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
}
}
-
- /**
- * Perform wrap operation.
- *
- * @param profileRequestContext profile request context
- *
- * @throws DataSealerException if an error is raised
- */
- private void doWrap(@Nonnull final ProfileRequestContext profileRequestContext) throws DataSealerException {
-
- String unwrapped = input.getmember(VALUE).string();
- if (unwrapped == null) {
- log.warn("{} No value parameter supplied for wrap operation", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
- return;
- }
-
- final Long exp = input.getmember(EXP).longinteger();
-
- final String wrapped = dataSealer.wrap(ensureAgent().getId() + '!' + unwrapped,
- exp != null ? Instant.ofEpochSecond(exp) : null);
-
- output.addmember(VALUE).string(wrapped);
- }
-
}
\ No newline at end of file
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/DoSealerOperationTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/DoSealerOperationTest.java
index b5914f1..57b7f13 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/DoSealerOperationTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/DoSealerOperationTest.java
@@ -105,6 +105,7 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
super.beforeMethod();
request = (MockHttpServletRequest) src.getExternalContext().getNativeRequest();
+ request.setMethod("POST");
dataSealer = createDataSealer("one");
dataSealer.initialize();
@@ -130,118 +131,104 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
}
/**
- * Test invalidMethod
+ * Test request with no operation
*/
@Test
- public void invalidMethod() {
-
- arc.setInput(new DDF().structure());
-
- request.setMethod("FOO");
+ public void noOperation() {
+ arc.setInput(new DDF("sealer").structure());
+
final Event event = action.execute(src);
-
ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
}
-
/**
- * Test unwrap with no inputs.
+ * Test encrypt with no inputs.
*/
@Test
- public void noParamsUnwrap() {
- arc.setInput(new DDF().structure());
+ public void noParamsEncrypt() {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("E");
+ arc.setInput(input);
+
- request.setMethod("GET");
final Event event = action.execute(src);
-
ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
}
-
+
/**
- * Test wrap with no inputs.
+ * Test decrypt with no inputs.
*/
@Test
- public void noParamsWrap() {
- arc.setInput(new DDF().structure());
+ public void noParamsDecrypt() {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("D");
+ arc.setInput(input);
+
- request.setMethod("POST");
final Event event = action.execute(src);
-
ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
}
/**
- * Test unwrap with bogus data.
+ * Test decrypt with bogus data.
*/
@Test
- public void invalidDataUnwrap() {
-
- request.setMethod("GET");
-
- final DDF input = new DDF().structure();
+ public void invalidDataDecrypt() {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("D");
input.addmember(DoSealerOperation.VALUE).string("foo");
arc.setInput(input);
final Event event = action.execute(src);
-
ActionTestingSupport.assertEvent(event, EventIds.MESSAGE_PROC_ERROR);
}
/**
- * Test unwrap with expired data.
+ * Test decrypt with expired data.
*
* @throws DataSealerException
*/
@Test
- public void expiredDataUnwrap() throws DataSealerException {
-
- request.setMethod("GET");
-
- final DDF input = new DDF().structure();
+ public void expiredDataDecrypt() throws DataSealerException {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("D");
input.addmember(DoSealerOperation.VALUE).string(dataSealer.wrap(VALUE, Instant.now().minusSeconds(3600)));
arc.setInput(input);
final Event event = action.execute(src);
-
ActionTestingSupport.assertEvent(event, EventIds.MESSAGE_EXPIRED);
}
/**
- * Test unwrap with wrong agent's data.
+ * Test decrypt with wrong agent's data.
*
* @throws DataSealerException
*/
@Test
- public void wrongDataUnwrap() throws DataSealerException {
-
- request.setMethod("GET");
-
- final DDF input = new DDF().structure();
- input.addmember(DoSealerOperation.VALUE).string(dataSealer.wrap(VALUE, Instant.now().plusSeconds(3600)));
+ public void wrongDataDecrypt() throws DataSealerException {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("D");
+ input.addmember(DoSealerOperation.VALUE).string(dataSealer.wrap(agent.getId() + '2' + '!' + VALUE, Instant.now().plusSeconds(3600)));
arc.setInput(input);
final Event event = action.execute(src);
-
ActionTestingSupport.assertEvent(event, EventIds.ACCESS_DENIED);
}
/**
- * Test successful unwrap.
+ * Test successful decrypt.
*
* @throws IOException
* @throws DataSealerException
*/
@Test
- public void unwrap() throws IOException, DataSealerException {
-
- request.setMethod("GET");
-
- final DDF input = new DDF().structure();
+ public void decrypt() throws IOException, DataSealerException {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("D");
input.addmember(DoSealerOperation.VALUE).string(dataSealer.wrap(agent.getId() + '!' + VALUE, Instant.now().plusSeconds(3600)));
arc.setInput(input);
final Event event = action.execute(src);
-
ActionTestingSupport.assertProceedEvent(event);
final DDF output = arc.getOutput();
@@ -251,22 +238,19 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
}
/**
- * Test successful wrap.
+ * Test successful encrypt.
*
* @throws IOException
* @throws DataSealerException
*/
@Test
- public void wrap() throws IOException, DataSealerException {
-
- request.setMethod("POST");
-
- final DDF input = new DDF().structure();
+ public void encrypt() throws IOException, DataSealerException {
+ final DDF input = new DDF("sealer").structure();
+ input.addmember(DoStorageOperation.OP).string("E");
input.addmember(DoSealerOperation.VALUE).string(VALUE);
arc.setInput(input);
final Event event = action.execute(src);
-
ActionTestingSupport.assertProceedEvent(event);
final DDF output = arc.getOutput();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list