[java-plugin-shibd] branch main updated: Rework sealer operation/flow design.

Codeberg noreply at shibboleth.net
Tue Sep 29 18:05:23 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/687ac0a32f167def74bba6788e1091036a44d6d8

The following commit(s) were added to refs/heads/main by this push:
     new 687ac0a  Rework sealer operation/flow design.
687ac0a is described below

commit 687ac0a32f167def74bba6788e1091036a44d6d8
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Tue Sep 29 14:04:51 2026 -0400

    Rework sealer operation/flow design.
---
 .../net/shibboleth/sp/flows/SealerFlowTest.java    | 110 +++++-------------
 .../sp/profile/impl/DoSealerOperation.java         | 123 ++++++++++++---------
 .../sp/profile/impl/DoSealerOperationTest.java     | 113 +++++++++----------
 3 files changed, 152 insertions(+), 194 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 141b437..c1b0a0f 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
@@ -16,6 +16,7 @@ package net.shibboleth.sp.flows;
 
 import java.io.IOException;
 import java.time.Instant;
+import java.util.List;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -27,7 +28,7 @@ import org.springframework.webflow.executor.FlowExecutionResult;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import net.shibboleth.shared.security.DataExpiredException;
+import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.DataSealer;
 import net.shibboleth.shared.security.DataSealerException;
 import net.shibboleth.sp.ddf.DDF;
@@ -71,30 +72,15 @@ public class SealerFlowTest extends AbstractSPFlowTest {
         assertFlowExecutionOutcome(result.getOutcome());
         assertOutputMessageEvent(result, EventIds.ACCESS_DENIED);
     }
-    
     /**
-     * Test missing operation.
-     */
-    @Test
-    public void testMissingOperation() {
-        setDefaultAuth();
-        request.setMethod("POST");
-        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 no input.
+     * Test with no input.
      * 
      * @throws IOException 
      */
     @Test
-    public void testEncryptNoInput() throws IOException {
+    public void testNoInput() 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);
@@ -102,38 +88,6 @@ public class SealerFlowTest extends AbstractSPFlowTest {
         assertFlowExecutionOutcome(result.getOutcome());
         assertOutputMessageEvent(result, EventIds.INVALID_MESSAGE);
     }
-    
-    /**
-     * Test encrypt operation with pre-expired data.
-     * 
-     * @throws IOException 
-     * @throws DataSealerException 
-     */
-    @Test
-    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);
-        
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertFlowExecutionResult(result, FLOW_ID);
-        assertFlowExecutionOutcome(result.getOutcome());
-        final DDF obj = assertOutputMessageSuccess(result);
-        assert obj != null;
-        
-        final String wrapped = obj.getmember("value").string();
-        assert wrapped != null;
-        try {
-            getDataSealer().unwrap(wrapped);
-            Assert.fail("Exception should have been raised");
-        } catch (DataExpiredException e) {
-            // expected
-        }
-    }
 
     /**
      * Test encrypt operation success.
@@ -146,8 +100,8 @@ public class SealerFlowTest extends AbstractSPFlowTest {
         setDefaultAuth();
 
         final DDF input = new DDF("sealer").structure();
-        input.addmember(DoSealerOperation.OP).string("E");
-        input.addmember(DoSealerOperation.VALUE).string(TEST_VALUE);
+        final DDF encrypt = input.addmember(DoSealerOperation.ENCRYPT).list();
+        encrypt.add(new DDF().string(TEST_VALUE));
         setRequest("POST", input);
         
         final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -156,30 +110,10 @@ public class SealerFlowTest extends AbstractSPFlowTest {
         final DDF obj = assertOutputMessageSuccess(result);
         assert obj != null;
         
-        final String wrapped = obj.getmember("value").string();
-        assert wrapped != null;
-        Assert.assertEquals(getDataSealer().unwrap(wrapped), AGENT_ID + '!' + TEST_VALUE);
+        final List<DDF> encrypted = obj.getmember(DoSealerOperation.ENCRYPTED).asList();
+        Assert.assertEquals(getDataSealer().unwrap(ensure(encrypted.get(0).string())), AGENT_ID + '!' + TEST_VALUE);
     }
 
-    /**
-     * Test decrypt operation with no input.
-     * 
-     * @throws IOException 
-     */
-    @Test
-    public void testDecryptNoInput() throws IOException {
-        setDefaultAuth();
-
-        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());
-        assertOutputMessageEvent(result, EventIds.INVALID_MESSAGE);
-    }
-    
     /**
      * Test decrypt operation with pre-expired data.
      * 
@@ -193,14 +127,14 @@ public class SealerFlowTest extends AbstractSPFlowTest {
         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);
+        final DDF decrypt = input.addmember(DoSealerOperation.DECRYPT).list();
+        decrypt.add(new DDF().string(wrapped));
         setRequest("POST", input);
         
         final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
         assertFlowExecutionResult(result, FLOW_ID);
         assertFlowExecutionOutcome(result.getOutcome());
-        assertOutputMessageEvent(result, EventIds.MESSAGE_EXPIRED);
+        assertOutputMessageEvent(result, EventIds.MESSAGE_PROC_ERROR);
     }
 
     /**
@@ -213,11 +147,11 @@ public class SealerFlowTest extends AbstractSPFlowTest {
     public void testDecryptSuccess() throws IOException, DataSealerException {
         setDefaultAuth();
 
-        final String wrapped = getDataSealer().wrap(AGENT_ID + '!' + TEST_VALUE, Instant.now().plusSeconds(3600));
+        final String wrapped = getDataSealer().wrap(AGENT_ID + '!' + TEST_VALUE, null);
         
         final DDF input = new DDF("sealer").structure();
-        input.addmember(DoSealerOperation.OP).string("D");
-        input.addmember(DoSealerOperation.VALUE).string(wrapped);
+        final DDF decrypt = input.addmember(DoSealerOperation.DECRYPT).list();
+        decrypt.add(new DDF().string(wrapped));
         setRequest("POST", input);
         
         final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -226,8 +160,20 @@ public class SealerFlowTest extends AbstractSPFlowTest {
         final DDF obj = assertOutputMessageSuccess(result);
         assert obj != null;
         
-        final String unwrapped = obj.getmember("value").string();
-        Assert.assertEquals(unwrapped, TEST_VALUE);
+        final List<DDF> decrypted = obj.getmember(DoSealerOperation.DECRYPTED).asList();
+        Assert.assertEquals(decrypted.get(0).string(), TEST_VALUE);
     }
     
+    /**
+     * Non-nullify an input.
+     * 
+     * @param <T> input type
+     * @param input input value
+     * 
+     * @return non-null input
+     */
+    @Nonnull private <T> T ensure(@Nullable final T input) {
+        return Constraint.isNotNull(input, "Input was null");
+    }
+
 }
\ No newline at end of file
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 ff48ad4..76cbb70 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
@@ -20,6 +20,7 @@ import javax.annotation.Nonnull;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.EventContext;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 
@@ -29,7 +30,6 @@ import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.security.DataExpiredException;
 import net.shibboleth.shared.security.DataSealer;
 import net.shibboleth.shared.security.DataSealerException;
 import net.shibboleth.sp.Agent;
@@ -46,20 +46,25 @@ import net.shibboleth.sp.profile.AbstractAgentAction;
  * @event {@link EventIds#ACCESS_DENIED}
  * @event {@link EventIds#INVALID_MESSAGE}
  * @event {@link EventIds#MESSAGE_PROC_ERROR}
- * @event {@link EventIds#MESSAGE_EXPIRED}
  * @pre <pre>AgentRequestContext.getOutput().isstruct()</pre>
  */
 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";
+    /** Member for data to encrypt. */
+    @Nonnull @NotEmpty public static final String ENCRYPT = "encrypt";
 
+    /** Member for data to decrypt. */
+    @Nonnull @NotEmpty public static final String DECRYPT = "decrypt";
+    
     /** Member for storage expiration. */
     @Nonnull @NotEmpty public static final String EXP = "exp";
 
+    /** Member for encrypted data. */
+    @Nonnull @NotEmpty public static final String ENCRYPTED = "encrypted";
+
+    /** Member for decrypted data. */
+    @Nonnull @NotEmpty public static final String DECRYPTED = "decrypted";
+    
     /** Class logger. */
     @Nonnull private Logger log = LoggerFactory.getLogger(DoSealerOperation.class);
     
@@ -119,22 +124,31 @@ public class DoSealerOperation extends AbstractAgentAction {
     }
 
     /** {@inheritDoc} */
-    @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+    @Override
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+        final DDF encrypt = input.getmember(ENCRYPT);
+        final DDF decrypt = input.getmember(DECRYPT);
+        if (!encrypt.islist() && !decrypt.islist()) {
+            log.warn("{} No inputs to encrypt or decrypt", getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+            return;
+        }
         
         try {
-            final String op = input.getmember(OP).string();
-            
-            if ("E".equals(op)) {
-                doWrap(profileRequestContext);
-            } else if ("D".equals(op)) {
-                doUnwrap(profileRequestContext);
-            } else {
-                log.warn("{} Invalid {} value: {}", getLogPrefix(), OP, op);
-                ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+            if (encrypt.islist()) {
+                output.add(doWrap(profileRequestContext, encrypt));
+            }
+
+            if (decrypt.islist()) {
+                output.add(doUnwrap(profileRequestContext, decrypt));
             }
+            
         } catch (final DataSealerException e) {
             log.error("{} Exception raised by DataSealer", getLogPrefix(), e);
-            ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_PROC_ERROR);
+            if (!profileRequestContext.containsSubcontext(EventContext.class)) {
+                ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_PROC_ERROR);
+            }
         }
     }
     
@@ -142,58 +156,67 @@ public class DoSealerOperation extends AbstractAgentAction {
      * Perform wrap operation.
      * 
      * @param profileRequestContext profile request context
+     * @param toWrap list of nodes containing data to wrap
+     * 
+     * @return a list node containing the encrypted data strings
      * 
      * @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;
-        }
+    @Nonnull private DDF doWrap(@Nonnull final ProfileRequestContext profileRequestContext,
+            @Nonnull final DDF toWrap) throws DataSealerException {
         
         final Long exp = input.getmember(EXP).longinteger();
 
-        final String wrapped = dataSealer.wrap(ensureAgent().getId() + '!' + unwrapped,
-                exp != null ? Instant.ofEpochSecond(exp) : null);
+        final DDF encrypted = new DDF(ENCRYPTED).list();
         
-        output.addmember(VALUE).string(wrapped);
+        for (final DDF unwrapped : toWrap) {
+            if (!unwrapped.isstring()) {
+                ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+                throw new DataSealerException("Non-string input from Agent.");
+            }
+            
+            encrypted.add(new DDF().string(
+                    dataSealer.wrap(ensureAgent().getId() + '!' + unwrapped.string(),
+                            exp != null ? Instant.ofEpochSecond(exp) : null)));
+        }
+        
+        return encrypted;
     }
     
     /**
      * Perform unwrap operation.
      * 
      * @param profileRequestContext profile request context
+     * @param toUnwrap list of nodes containing data to unwrap
+     * 
+     * @return a list node containing the decrypted data strings
      * 
      * @throws DataSealerException if an error is raised
      */
-    private void doUnwrap(@Nonnull final ProfileRequestContext profileRequestContext) throws DataSealerException {
+    @Nonnull private DDF doUnwrap(@Nonnull final ProfileRequestContext profileRequestContext,
+            @Nonnull final DDF toUnwrap) throws DataSealerException {
+
+        final String prefix = ensureAgent().getId() + '!';
         
-        final String wrapped = input.getmember(VALUE).string();
-        if (wrapped == null) {
-            log.warn("{} No {} parameter supplied for decryption operation", getLogPrefix(), VALUE);
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
-            return;
-        }
+        final DDF decrypted = new DDF(DECRYPTED).list();
         
-        final String unwrapped;
-        try {
-            unwrapped = dataSealer.unwrap(wrapped);
-        } catch (final DataExpiredException e) {
-            log.info("{} Decrypted data has expired", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_EXPIRED);
-            return;
+        for (final DDF wrapped : toUnwrap) {
+            final String ciphertext = wrapped.isstring() ? wrapped.string() : null;
+            if (ciphertext == null || ciphertext.isEmpty()) {
+                ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+                throw new DataSealerException("Non-string input from Agent.");
+            }
+
+            final String value = dataSealer.unwrap(ciphertext);
+            if (value.startsWith(prefix)) {
+                decrypted.add(new DDF().string(value.substring(prefix.length())));
+            } else {
+                ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
+                throw new DataSealerException("Encrypted data was not created by this Agent");
+            }
         }
         
-        final String prefix = ensureAgent().getId() + '!';
-        if (unwrapped.startsWith(prefix)) {
-            output.addmember(VALUE).string(unwrapped.substring(prefix.length()));
-        } else {
-            log.warn("{} Encrypted data was not created by this Agent", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
-        }
+        return decrypted;
     }
     
 }
\ 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 57b7f13..f5a925b 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
@@ -16,6 +16,7 @@ package net.shibboleth.sp.profile.impl;
 
 import java.io.IOException;
 import java.time.Instant;
+import java.util.List;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -33,6 +34,7 @@ import org.testng.annotations.Test;
 import net.shibboleth.idp.profile.testing.ActionTestingSupport;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.resource.Resource;
 import net.shibboleth.shared.security.DataSealer;
 import net.shibboleth.shared.security.DataSealerException;
@@ -47,8 +49,11 @@ import net.shibboleth.sp.testing.TestResourceConverter;
 public class DoSealerOperationTest extends BaseAgentRequestTest {
 
     /** Test value. */
-    @Nonnull @NotEmpty private final static String VALUE = "testValue";
+    @Nonnull @NotEmpty private final static String VALUE_1 = "testValue1";
 
+    /** Test value. */
+    @Nonnull @NotEmpty private final static String VALUE_2 = "testValue2";
+    
     private Resource keystoreResource;
     private Resource versionResource;
 
@@ -73,7 +78,7 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
         versionResource = TestResourceConverter.of(resource);
     }
     
-    private DataSealer createDataSealer(@Nullable @NotEmpty final String nodePrefix)
+    private DataSealer createDataSealer()
             throws DataSealerException, ComponentInitializationException {
         final BasicKeystoreKeyStrategy strategy = new BasicKeystoreKeyStrategy();
         
@@ -89,7 +94,6 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
         
         final DataSealer sealer = new DataSealer();
         sealer.setKeyStrategy(strategy);
-        sealer.setNodePrefix(nodePrefix);
         sealer.initialize();
         return sealer;
     }
@@ -107,7 +111,7 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
         request = (MockHttpServletRequest) src.getExternalContext().getNativeRequest();
         request.setMethod("POST");
 
-        dataSealer = createDataSealer("one");
+        dataSealer = createDataSealer();
         dataSealer.initialize();
              
         action = new DoSealerOperation();
@@ -131,52 +135,34 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
     }
 
     /**
-     * Test request with no operation
+     * Test request with no input.
      */
     @Test
-    public void noOperation() {
-        arc.setInput(new DDF("sealer").structure());
-
+    public void noInput() {
         final Event event = action.execute(src);
         ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
     }
 
     /**
-     * Test encrypt with no inputs.
+     * Test with no inputs.
      */
     @Test
-    public void noParamsEncrypt() {
+    public void noParams() {
         final DDF input = new DDF("sealer").structure();
-        input.addmember(DoStorageOperation.OP).string("E");
         arc.setInput(input);
 
-
         final Event event = action.execute(src);
         ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
     }
     
-    /**
-     * Test decrypt with no inputs.
-     */
-    @Test
-    public void noParamsDecrypt() {
-        final DDF input = new DDF("sealer").structure();
-        input.addmember(DoStorageOperation.OP).string("D");
-        arc.setInput(input);
-
-
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
-    }
-
     /**
      * Test decrypt with bogus data.
      */
     @Test
     public void invalidDataDecrypt() {
         final DDF input = new DDF("sealer").structure();
-        input.addmember(DoStorageOperation.OP).string("D");
-        input.addmember(DoSealerOperation.VALUE).string("foo");
+        final DDF decrypt = input.addmember(DoSealerOperation.DECRYPT).list();
+        decrypt.add(new DDF().string("foo"));
         arc.setInput(input);
         
         final Event event = action.execute(src);
@@ -191,12 +177,12 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
     @Test
     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)));
+        final DDF decrypt = input.addmember(DoSealerOperation.DECRYPT).list();
+        decrypt.add(new DDF().string(dataSealer.wrap(VALUE_1, Instant.now().minusSeconds(3600))));
         arc.setInput(input);
         
         final Event event = action.execute(src);
-        ActionTestingSupport.assertEvent(event, EventIds.MESSAGE_EXPIRED);
+        ActionTestingSupport.assertEvent(event, EventIds.MESSAGE_PROC_ERROR);
     }
 
     /**
@@ -205,10 +191,10 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
      * @throws DataSealerException 
      */
     @Test
-    public void wrongDataDecrypt() throws DataSealerException {
+    public void wrongAgentDecrypt() 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)));
+        final DDF decrypt = input.addmember(DoSealerOperation.DECRYPT).list();
+        decrypt.add(new DDF().string(dataSealer.wrap(agent.getId() + '2' + '!' + VALUE_1, null)));
         arc.setInput(input);
         
         final Event event = action.execute(src);
@@ -222,32 +208,17 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
      * @throws DataSealerException 
      */
     @Test
-    public void decrypt() throws IOException, DataSealerException {
+    public void test() 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();
-        assert output != null;
+        final DDF decrypt = input.addmember(DoSealerOperation.DECRYPT).list();
+        decrypt.add(new DDF().string(dataSealer.wrap(agent.getId() + '!' + VALUE_1, null)));
+        decrypt.add(new DDF().string(dataSealer.wrap(agent.getId() + '!' + VALUE_2, null)));
+        
+        final DDF encrypt = input.addmember(DoSealerOperation.ENCRYPT).list();
+        encrypt.add(new DDF().string(VALUE_1));
+        encrypt.add(new DDF().string(VALUE_2));
         
-        Assert.assertEquals(output.getmember(DoStorageOperation.VALUE).string(), VALUE);
-    }    
-
-    /**
-     * Test successful encrypt.
-     * 
-     * @throws IOException 
-     * @throws DataSealerException 
-     */
-    @Test
-    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);
@@ -256,11 +227,29 @@ public class DoSealerOperationTest extends BaseAgentRequestTest {
         final DDF output = arc.getOutput();
         assert output != null;
         
-        final String wrapped = output.getmember(DoStorageOperation.VALUE).string();
-        assert wrapped != null;
+        final DDF decrypted = output.getmember(DoSealerOperation.DECRYPTED);
+        Assert.assertTrue(decrypted.islist());
+        final List<DDF> dlist = decrypted.asList();
+        Assert.assertEquals(dlist.get(0).string(), VALUE_1);
+        Assert.assertEquals(dlist.get(1).string(), VALUE_2);
         
-        final String unwrapped = dataSealer.unwrap(wrapped);
-        Assert.assertEquals(unwrapped, agent.getId() + '!'  + VALUE);
-    }    
+        final DDF encrypted = output.getmember(DoSealerOperation.ENCRYPTED);
+        Assert.assertTrue(encrypted.islist());
+        final List<DDF> elist = encrypted.asList();
+        Assert.assertEquals(dataSealer.unwrap(ensure(elist.get(0).string())), agent.getId() + '!'  + VALUE_1);
+        Assert.assertEquals(dataSealer.unwrap(ensure(elist.get(1).string())), agent.getId() + '!'  + VALUE_2);
+    }
+    
+    /**
+     * Non-nullify an input.
+     * 
+     * @param <T> input type
+     * @param input input value
+     * 
+     * @return non-null input
+     */
+    @Nonnull private <T> T ensure(@Nullable final T input) {
+        return Constraint.isNotNull(input, "Input was null");
+    }
 
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list