Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenValidatorTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenValidatorTest.java?rev=1859352&r1=1859351&r2=1859352&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenValidatorTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenValidatorTest.java Thu May 16 07:01:13 2019 @@ -16,7 +16,7 @@ */ package org.apache.jackrabbit.oak.security.authentication.token; -import java.util.Collections; +import java.util.Calendar; import java.util.Date; import java.util.UUID; @@ -24,17 +24,30 @@ import org.apache.jackrabbit.JcrConstant import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; +import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; +import org.apache.jackrabbit.oak.plugins.tree.TreeProvider; +import org.apache.jackrabbit.oak.plugins.tree.TreeUtil; +import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.Validator; import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants; +import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConstants; import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo; import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtil; -import org.apache.jackrabbit.oak.util.NodeUtil; +import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.util.ISO8601; +import org.jetbrains.annotations.NotNull; import org.junit.Before; import org.junit.Test; +import static org.apache.jackrabbit.oak.api.Type.DATE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class TokenValidatorTest extends AbstractTokenTest { @@ -47,43 +60,53 @@ public class TokenValidatorTest extends userId = getTestUser().getID(); } + private static String getDateValue() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(new Date().getTime()); + return ISO8601.format(calendar); + } + @Test public void testCreateReservedKeyProperty() throws Exception { - NodeUtil node = new NodeUtil(root.getTree("/")).addChild("testNode", JcrConstants.NT_UNSTRUCTURED); + Tree tree = TreeUtil.addChild(root.getTree("/"), "testNode", JcrConstants.NT_UNSTRUCTURED); try { - node.setString(TOKEN_ATTRIBUTE_KEY, "anyValue"); + tree.setProperty(TOKEN_ATTRIBUTE_KEY, "anyValue"); root.commit(CommitMarker.asCommitAttributes()); fail("The reserved token key property must not used with other node types."); } catch (CommitFailedException e) { assertEquals(60, e.getCode()); } finally { - node.getTree().remove(); - root.commit(); + tree.remove(); + if (root.hasPendingChanges()) { + root.commit(); + } } } @Test public void testCreateReservedKeyProperty2() throws Exception { - NodeUtil node = new NodeUtil(root.getTree("/")).addChild("testNode", JcrConstants.NT_UNSTRUCTURED); + Tree tree = TreeUtil.addChild(root.getTree("/"), "testNode", JcrConstants.NT_UNSTRUCTURED); try { - node.setString(TOKEN_ATTRIBUTE_KEY, "anyValue"); + tree.setProperty(TOKEN_ATTRIBUTE_KEY, "anyValue"); root.commit(); fail("The reserved token key property must only be created by the TokenProvider."); } catch (CommitFailedException e) { assertEquals(63, e.getCode()); } finally { - node.getTree().remove(); - root.commit(); + tree.remove(); + if (root.hasPendingChanges()) { + root.commit(); + } } } @Test public void testChangingTokenKey() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - NodeUtil tokenTree = new NodeUtil(getTokenTree(info)); + TokenInfo info = createTokenInfo(tokenProvider, userId); + Tree tokenTree = getTokenTree(info); try { - tokenTree.setString(TOKEN_ATTRIBUTE_KEY, PasswordUtil.buildPasswordHash("anotherValue")); + tokenTree.setProperty(TOKEN_ATTRIBUTE_KEY, PasswordUtil.buildPasswordHash("anotherValue")); root.commit(CommitMarker.asCommitAttributes()); fail("The token key must never be modified."); } catch (CommitFailedException e) { @@ -92,12 +115,12 @@ public class TokenValidatorTest extends } @Test - public void testPlaintextTokenKey() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - NodeUtil tokenTree = new NodeUtil(getTokenTree(info)); + public void testPlaintextTokenKey() { + TokenInfo info = createTokenInfo(tokenProvider, userId); + Tree tokenTree = getTokenTree(info); try { - tokenTree.setString(TOKEN_ATTRIBUTE_KEY, "anotherValue"); + tokenTree.setProperty(TOKEN_ATTRIBUTE_KEY, "anotherValue"); root.commit(CommitMarker.asCommitAttributes()); fail("The token key must not be plaintext."); } catch (CommitFailedException e) { @@ -106,12 +129,12 @@ public class TokenValidatorTest extends } @Test - public void testManuallyModifyExpirationDate() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - NodeUtil tokenTree = new NodeUtil(getTokenTree(info)); + public void testManuallyModifyExpirationDate() { + TokenInfo info = createTokenInfo(tokenProvider, userId); + Tree tokenTree = getTokenTree(info); try { - tokenTree.setDate(TOKEN_ATTRIBUTE_EXPIRY, new Date().getTime()); + tokenTree.setProperty(TOKEN_ATTRIBUTE_EXPIRY, getDateValue(), DATE); root.commit(); fail("The token expiry must not manually be changed"); } catch (CommitFailedException e) { @@ -121,94 +144,82 @@ public class TokenValidatorTest extends @Test public void testModifyExpirationDate() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - NodeUtil tokenTree = new NodeUtil(getTokenTree(info)); + TokenInfo info = createTokenInfo(tokenProvider, userId); + Tree tokenTree = getTokenTree(info); - tokenTree.setDate(TOKEN_ATTRIBUTE_EXPIRY, new Date().getTime()); + tokenTree.setProperty(TOKEN_ATTRIBUTE_EXPIRY, getDateValue(), DATE); root.commit(CommitMarker.asCommitAttributes()); } @Test public void testCreateTokenAtInvalidLocationBelowTestNode() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - Tree tokenTree = getTokenTree(info); - + TokenInfo info = createTokenInfo(tokenProvider, userId); assertNotNull(tokenProvider.getTokenInfo(info.getToken())); - NodeUtil node = new NodeUtil(root.getTree("/")).addChild("testNode", JcrConstants.NT_UNSTRUCTURED); + Tree tree = TreeUtil.addChild(root.getTree("/"), "testNode", JcrConstants.NT_UNSTRUCTURED); try { - createTokenTree(info, node, TOKEN_NT_NAME); - tokenTree.remove(); + replaceTokenTree(info, tree, TOKEN_NT_NAME); root.commit(CommitMarker.asCommitAttributes()); fail("Creating a new token not at '/testNode' must fail."); } catch (CommitFailedException e) { assertEquals(64, e.getCode()); } finally { - node.getTree().remove(); + tree.remove(); root.commit(CommitMarker.asCommitAttributes()); } } @Test public void testCreateTokenAtInvalidLocationInsideUser() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - Tree tokenTree = getTokenTree(info); - + TokenInfo info = createTokenInfo(tokenProvider, userId); assertNotNull(tokenProvider.getTokenInfo(info.getToken())); Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree).addChild("testNode", JcrConstants.NT_UNSTRUCTURED); + Tree tree = TreeUtil.addChild(userTree, "testNode", JcrConstants.NT_UNSTRUCTURED); try { - createTokenTree(info, node, TOKEN_NT_NAME); - tokenTree.remove(); + replaceTokenTree(info, tree, TOKEN_NT_NAME); root.commit(CommitMarker.asCommitAttributes()); - fail("Creating a new token '" + node.getTree().getPath() + "' must fail."); + fail("Creating a new token '" + tree.getPath() + "' must fail."); } catch (CommitFailedException e) { assertEquals(65, e.getCode()); } finally { - node.getTree().remove(); + tree.remove(); root.commit(CommitMarker.asCommitAttributes()); } } @Test public void testCreateTokenAtInvalidLocationInsideUser2() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - Tree tokenTree = getTokenTree(info); - + TokenInfo info = createTokenInfo(tokenProvider, userId); assertNotNull(tokenProvider.getTokenInfo(info.getToken())); Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree).getOrAddChild(TOKENS_NODE_NAME, TOKENS_NT_NAME); + Tree tree = TreeUtil.addChild(userTree, TOKENS_NODE_NAME, TOKENS_NT_NAME); try { - node = node.addChild("invalid", JcrConstants.NT_UNSTRUCTURED); - createTokenTree(info, node, TOKEN_NT_NAME); - tokenTree.remove(); + tree = TreeUtil.addChild(tree, "invalid", JcrConstants.NT_UNSTRUCTURED); + replaceTokenTree(info, tree, TOKEN_NT_NAME); root.commit(CommitMarker.asCommitAttributes()); - fail("Creating a new token '" + node.getTree().getPath() + "' must fail."); + fail("Creating a new token '" + tree.getPath() + "' must fail."); } catch (CommitFailedException e) { assertEquals(65, e.getCode()); } finally { - node.getTree().remove(); + tree.remove(); root.commit(CommitMarker.asCommitAttributes()); } } @Test public void testManuallyCreateToken() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - Tree tokenTree = getTokenTree(info); - + TokenInfo info = createTokenInfo(tokenProvider, userId); assertNotNull(tokenProvider.getTokenInfo(info.getToken())); - NodeUtil tokensNode = new NodeUtil(tokenTree.getParent()); + Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); try { // create a valid token node using the test root - createTokenTree(info, tokensNode, TOKEN_NT_NAME); - tokenTree.remove(); + replaceTokenTree(info, userTree.getChild(TOKENS_NODE_NAME), TOKEN_NT_NAME); root.commit(); fail("Manually creating a token node must fail."); @@ -222,17 +233,13 @@ public class TokenValidatorTest extends @Test public void testCreateTokenWithInvalidNodeType() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); - Tree tokenTree = getTokenTree(info); - + TokenInfo info = createTokenInfo(tokenProvider, userId); assertNotNull(tokenProvider.getTokenInfo(info.getToken())); Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree.getChild(TOKENS_NODE_NAME)); Tree t = null; try { - t = createTokenTree(info, node, JcrConstants.NT_UNSTRUCTURED); - tokenTree.remove(); + t = replaceTokenTree(info, userTree.getChild(TOKENS_NODE_NAME), JcrConstants.NT_UNSTRUCTURED); root.commit(CommitMarker.asCommitAttributes()); fail("The token node must be of type rep:Token."); @@ -248,7 +255,7 @@ public class TokenValidatorTest extends @Test public void testRemoveTokenNode() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); + TokenInfo info = createTokenInfo(tokenProvider, userId); getTokenTree(info).remove(); root.commit(); } @@ -256,17 +263,17 @@ public class TokenValidatorTest extends @Test public void testInvalidTokenParentNode() throws Exception { Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree).addChild("testNode", JcrConstants.NT_UNSTRUCTURED); + Tree node = TreeUtil.addChild(userTree, "testNode", JcrConstants.NT_UNSTRUCTURED); try { // Invalid node type of '.tokens' node - node.addChild(TOKENS_NODE_NAME, JcrConstants.NT_UNSTRUCTURED); + TreeUtil.addChild(node, TOKENS_NODE_NAME, JcrConstants.NT_UNSTRUCTURED); root.commit(CommitMarker.asCommitAttributes()); - fail("Creating a new token '" + node.getTree().getPath() + "' must fail."); + fail("Creating a new token '" + node.getPath() + "' must fail."); } catch (CommitFailedException e) { assertEquals(68, e.getCode()); } finally { - node.getTree().remove(); + node.remove(); root.commit(CommitMarker.asCommitAttributes()); } } @@ -274,28 +281,25 @@ public class TokenValidatorTest extends @Test public void testManuallyCreateTokenParent() throws Exception { Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree); - - node.addChild(TOKENS_NODE_NAME, TOKENS_NT_NAME); + TreeUtil.addChild(userTree, TOKENS_NODE_NAME, TOKENS_NT_NAME); root.commit(); } @Test public void testManuallyCreateTokenParentWithNtUnstructured() throws Exception { Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree); - node.addChild(TOKENS_NODE_NAME, JcrConstants.NT_UNSTRUCTURED); + TreeUtil.addChild(userTree, TOKENS_NODE_NAME, JcrConstants.NT_UNSTRUCTURED); root.commit(); } @Test public void testTokensNodeBelowRoot() throws Exception { - NodeUtil rootNode = new NodeUtil(root.getTree("/")); - NodeUtil n = null; + Tree rootNode = root.getTree("/"); + Tree n = null; try { // Invalid node type of '.tokens' node - n = rootNode.addChild(TOKENS_NODE_NAME, TOKENS_NT_NAME); + n = TreeUtil.addChild(rootNode, TOKENS_NODE_NAME, TOKENS_NT_NAME); root.commit(); fail("The token parent node must be located below the configured user root."); @@ -303,7 +307,7 @@ public class TokenValidatorTest extends assertEquals(64, e.getCode()); } finally { if (n != null) { - n.getTree().remove(); + n.remove(); root.commit(CommitMarker.asCommitAttributes()); } } @@ -312,12 +316,11 @@ public class TokenValidatorTest extends @Test public void testTokensNodeAtInvalidPathBelowUser() throws Exception { Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil userNode = new NodeUtil(userTree); - NodeUtil n = null; + Tree n = null; try { // Invalid node type of '.tokens' node - n = userNode.addChild("test", JcrConstants.NT_UNSTRUCTURED); - n.addChild(TOKENS_NODE_NAME, TOKENS_NT_NAME); + n = TreeUtil.addChild(userTree, "test", JcrConstants.NT_UNSTRUCTURED); + TreeUtil.addChild(n, TOKENS_NODE_NAME, TOKENS_NT_NAME); root.commit(); fail("The token parent node must be located below the user home node."); @@ -325,7 +328,7 @@ public class TokenValidatorTest extends assertEquals(68, e.getCode()); } finally { if (n != null) { - n.getTree().remove(); + n.remove(); root.commit(CommitMarker.asCommitAttributes()); } } @@ -334,18 +337,17 @@ public class TokenValidatorTest extends @Test public void testChangeTokenParentPrimaryTypeToRepUnstructured() throws Exception { Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil node = new NodeUtil(userTree); - node = node.addChild(TOKENS_NODE_NAME, JcrConstants.NT_UNSTRUCTURED); + Tree node = TreeUtil.addChild(userTree, TOKENS_NODE_NAME, JcrConstants.NT_UNSTRUCTURED); root.commit(); - node.setName(JcrConstants.JCR_PRIMARYTYPE, TOKENS_NT_NAME); + node.setProperty(JcrConstants.JCR_PRIMARYTYPE, TOKENS_NT_NAME, Type.NAME); root.commit(); } @Test - public void testChangeTokenParentPrimaryType() throws Exception { - TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()); + public void testChangeTokenParentPrimaryType() { + TokenInfo info = createTokenInfo(tokenProvider, userId); try { Tree tokensTree = getTokenTree(info).getParent(); @@ -363,10 +365,10 @@ public class TokenValidatorTest extends @Test public void testChangeRegularRepUnstructuredPrimaryType() throws Exception { Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath()); - NodeUtil n = new NodeUtil(userTree).getOrAddChild("test", NodeTypeConstants.NT_REP_UNSTRUCTURED); + Tree n = TreeUtil.getOrAddChild(userTree,"test", NodeTypeConstants.NT_REP_UNSTRUCTURED); root.commit(); - n.setName(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED); + n.setProperty(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME); root.commit(); } @@ -380,11 +382,11 @@ public class TokenValidatorTest extends t.addChild("node").setProperty(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME); root.commit(); - NodeUtil node = new NodeUtil(root.getTree(path)); - node.setName(JcrConstants.JCR_PRIMARYTYPE, TokenConstants.TOKEN_NT_NAME); - node.setString(JcrConstants.JCR_UUID, UUID.randomUUID().toString()); - node.setString(TokenConstants.TOKEN_ATTRIBUTE_KEY, PasswordUtil.buildPasswordHash("key")); - node.setDate(TokenConstants.TOKEN_ATTRIBUTE_EXPIRY, new Date().getTime()); + Tree node = root.getTree(path); + node.setProperty(JcrConstants.JCR_PRIMARYTYPE, TokenConstants.TOKEN_NT_NAME, Type.NAME); + node.setProperty(JcrConstants.JCR_UUID, UUID.randomUUID().toString()); + node.setProperty(TokenConstants.TOKEN_ATTRIBUTE_KEY, PasswordUtil.buildPasswordHash("key")); + node.setProperty(TokenConstants.TOKEN_ATTRIBUTE_EXPIRY, getDateValue(), Type.DATE); root.commit(CommitMarker.asCommitAttributes()); } catch (CommitFailedException e) { assertEquals(62, e.getCode()); @@ -394,4 +396,146 @@ public class TokenValidatorTest extends root.commit(); } } + + @Test + public void testReservedPropertyAddedValidParent() throws Exception { + Tree tokenTree = TreeUtil.addChild(root.getTree(PathUtils.ROOT_PATH), "name", TOKEN_NT_NAME); + Validator v = createRootValidator(tokenTree, tokenTree); + v.propertyAdded(PropertyStates.createProperty(TokenConstants.TOKEN_ATTRIBUTE_EXPIRY, "anyValue")); + } + + @Test(expected = CommitFailedException.class) + public void testReservedPropertyAddedInvalidParent() throws Exception { + Tree rootTree = root.getTree(PathUtils.ROOT_PATH); + try { + Validator v = createRootValidator(rootTree, rootTree); + v.propertyAdded(PropertyStates.createProperty(TokenConstants.TOKEN_ATTRIBUTE_EXPIRY, "anyValue")); + } catch (CommitFailedException e) { + assertTrue(e.isConstraintViolation()); + assertEquals(60, e.getCode()); + throw e; + } + } + + @Test(expected = CommitFailedException.class) + public void testAddTokenTreeMissingKey() throws Exception { + Tree tokenTree = getTokenTree(createTokenInfo(tokenProvider, userId)); + tokenTree.removeProperty(TokenConstants.TOKEN_ATTRIBUTE_KEY); + + Tree rootTree = root.getTree(PathUtils.ROOT_PATH); + try { + Validator v = createValidator(rootTree, rootTree, tokenTree.getParent().getPath(), false); + v.childNodeAdded(tokenTree.getName(), getTreeProvider().asNodeState(tokenTree)); + } catch (CommitFailedException e) { + assertTrue(e.isConstraintViolation()); + assertEquals(66, e.getCode()); + throw e; + } finally { + root.refresh(); + } + } + + @Test(expected = CommitFailedException.class) + public void testAddTokenTreeMissingTokensParent() throws Exception { + Tree tokenTree = getTokenTree(createTokenInfo(tokenProvider, userId)); + root.move(tokenTree.getPath(), PathUtils.concat(getTestUser().getPath(), tokenTree.getName())); + Tree rootTree = root.getTree(PathUtils.ROOT_PATH); + + try { + Validator v = createValidator(rootTree, rootTree, getTestUser().getPath(), true); + v.childNodeAdded(tokenTree.getName(), mock(NodeState.class)); + } catch (CommitFailedException e) { + assertTrue(e.isConstraintViolation()); + assertEquals(65, e.getCode()); + throw e; + } finally { + root.refresh(); + } + } + + @Test(expected = CommitFailedException.class) + public void testAddTokenTreeMissingUserGrandParent() throws Exception { + // since adding/changing an invalid tokens-parent node will be detected, mocking is required to + // reach the desired invalid state, where the .tokens node isn't located below the user home. + Tree tokenTree = getTokenTree(createTokenInfo(tokenProvider, userId)); + Tree tokensTree = tokenTree.getParent(); + // move .tokens node one level up + String destPath = PathUtils.concat(PathUtils.getParentPath(getTestUser().getPath()), tokensTree.getName()); + root.move(tokensTree.getPath(), destPath); + try { + // create a validator that has 'tokensTree' as parentBefore and parentAfter + NodeState ns = getTreeProvider().asNodeState(tokensTree); + TreeProvider tp = when(mock(TreeProvider.class).createReadOnlyTree(ns)).thenReturn(tokensTree).getMock(); + TokenValidatorProvider tvp = new TokenValidatorProvider(ConfigurationParameters.EMPTY, tp); + Validator v = tvp.getRootValidator(ns, ns, new CommitInfo("sid", "uid", CommitMarker.asCommitAttributes())); + assertNotNull(v); + v.childNodeChanged(tokenTree.getName(), mock(NodeState.class), mock(NodeState.class)); + } catch (CommitFailedException e) { + assertTrue(e.isConstraintViolation()); + assertEquals(65, e.getCode()); + throw e; + } finally { + root.refresh(); + } + } + + @Test(expected = CommitFailedException.class) + public void testAddTokenTreeInvalidKey() throws Exception { + Tree tokenTree = getTokenTree(createTokenInfo(tokenProvider, userId)); + tokenTree.setProperty(TokenConstants.TOKEN_ATTRIBUTE_KEY, "someValue"); + + Tree rootTree = root.getTree(PathUtils.ROOT_PATH); + try { + Validator v = createValidator(rootTree, rootTree, tokenTree.getParent().getPath(), true); + v.childNodeAdded(tokenTree.getName(), getTreeProvider().asNodeState(tokenTree)); + } catch (CommitFailedException e) { + assertTrue(e.isConstraintViolation()); + assertEquals(66, e.getCode()); + throw e; + } finally { + root.refresh(); + } + } + + @Test(expected = CommitFailedException.class) + public void testAddTokenTreeMissingExpiry() throws Exception { + Tree tokenTree = getTokenTree(createTokenInfo(tokenProvider, userId)); + tokenTree.removeProperty(TokenConstants.TOKEN_ATTRIBUTE_EXPIRY); + + Tree rootTree = root.getTree(PathUtils.ROOT_PATH); + Validator v = createValidator(rootTree, rootTree, tokenTree.getParent().getPath(), false); + try { + v.childNodeAdded(tokenTree.getName(), getTreeProvider().asNodeState(tokenTree)); + } catch (CommitFailedException e) { + assertTrue(e.isConstraintViolation()); + assertEquals(67, e.getCode()); + throw e; + } finally { + root.refresh(); + } + } + + @NotNull + private Validator createRootValidator(@NotNull Tree before, @NotNull Tree after) { + TokenValidatorProvider tvp = new TokenValidatorProvider(ConfigurationParameters.EMPTY, getTreeProvider()); + Validator v = tvp.getRootValidator(getTreeProvider().asNodeState(before), getTreeProvider().asNodeState(after), new CommitInfo("sid", "uid", CommitMarker.asCommitAttributes())); + assertNotNull(v); + return v; + } + + @NotNull + private Validator createValidator(@NotNull Tree before, @NotNull Tree after, @NotNull String path, boolean isAdd) throws CommitFailedException { + TokenValidatorProvider tvp = new TokenValidatorProvider(ConfigurationParameters.EMPTY, getTreeProvider()); + NodeState b = getTreeProvider().asNodeState(before); + NodeState a = getTreeProvider().asNodeState(after); + Validator v = tvp.getRootValidator(b, a, new CommitInfo("sid", "uid", CommitMarker.asCommitAttributes())); + for (String name : PathUtils.elements(path)) { + assertNotNull(v); + b = b.getChildNode(name); + a = a.getChildNode(name); + v = (isAdd) ? v.childNodeAdded(name, a) : v.childNodeChanged(name, b, a); + } + assertNotNull(v); + return v; + } } \ No newline at end of file
