Skip to main content

Version: 22.04

Form Security Filter

The Form Security Filter service is used to perform additional security and access control checks when someone renders a form or reopens a saved transaction, and is called before running Journey Manager access checks.

This service is configured via the Form Version Services tab.

Service Invoke Parameters

Parameters are not nullable except where otherwise indicated.

ParameterDescription
svcDefSvcDef
A service definition value object.
formForm
A form value object.
txnTxn
Nullable. A transaction record value object.
requestHttpServletRequest
A HTTP servlet request.
userUser
Nullable. An authenticated user.

Script Result

If all checks performed by the script pass, the script should do nothing. Journey Manager will continue with in-built access checks before allowing the user to access the form or transaction.

If any checks fail and access shall be denied to the user, the script must throw a RedirectException with a valid target attribute. Journey Manager will redirect the user to the target.

info

You cannot use this design pattern in TransactField App because the form security filter service is executed on the server and not in the client.

Templates

Service

import com.avoka.core.groovy.GroovyLogger as logger
import com.avoka.tm.util.*
import com.avoka.tm.vo.*
import javax.servlet.http.*

class FluentFormSecurityFilter {

/*
* Perform form security filter service
*
* throws: if access checks fail, throw a RedirectException to redirect to another page
*/
Object invoke(SvcDef svcDef, Form form, Txn txn, HttpServletRequest request, User user) throws RedirectException {

// Opening a new form
if (txn == null) {
return
}

// TODO: replace this with realistic access control checks
def authorization = request.getHeader("Authorization")

if (authorization == null) {
// access control checks failed, redirect to an appropriate URL
throw new RedirectException("../not-authorized.htm")
}

// Store the security tokens in session
Security.addSessionTxnSecurityTokens(request, txn)
}
}

Unit Test

import com.avoka.core.groovy.GroovyLogger as logger
import com.avoka.tm.svc.*
import com.avoka.tm.test.*
import com.avoka.tm.util.*
import com.avoka.tm.vo.*
import org.junit.*

class UnitTest extends AbstractJUnitTest {

Map params
MockRequest request

@Before
void prepareTest() {

request = new MockRequest()

params = [
"svcDef": svcDef,
"form": null,
"txn": null,
"request": request,
"user": null
]
}

@After
void cleanTest() {
request = null
params = null
}

@Test
void test1() throws Exception {

// Test 1: open form flow
try {
new ServiceInvoker(svcDef).invoke(params)

} catch (Exception re) {
assert false : 'Test 1 failed'
}
}

@Test
void test2() throws Exception {

// Test 2: we ensure that the security filter does not grant access for unauthorized requests
Txn txn = new MockVoBuilder().createTxnCompletedWithXml("<avokasmartform></avokasmartform>")
params.txn = txn

try {
new ServiceInvoker(svcDef).invoke(params)

// the above call should fail due to access attribute not having been set up
assert false : 'Test 2 failed'

} catch (RedirectException re) {
assert "../not-authorized.htm" == re.getTarget()
}

}

@Test
void test3() throws Exception {

// Test 3: we set up the appropriate header attribute that will cause access control checks to pass
request.setHeader("Authorization", "3888c972a167ca55e967cd764ab691bf")

try {
new ServiceInvoker(svcDef).invoke(params)

} catch (Exception re) {
logger.info re
assert false : 'Test 3 failed'
}
}
}