Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java?rev=1857551&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
Mon Apr 15 07:16:49 2019
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import
org.apache.jackrabbit.oak.spi.security.authorization.permission.EmptyPermissionProvider;
+import
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlPolicy;
+import java.security.Principal;
+import java.util.UUID;
+
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LOCK_MANAGEMENT;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_VERSION_MANAGEMENT;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class TransientPrincipalTest extends AbstractPrincipalBasedTest {
+
+ private String uid = "testSystemUser" + UUID.randomUUID();
+ private Principal principal;
+ private PrincipalBasedAccessControlManager acMgr;
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+
+ principal = getUserManager(root).createSystemUser(uid,
INTERMEDIATE_PATH).getPrincipal();
+ acMgr = new PrincipalBasedAccessControlManager(getMgrProvider(root),
getFilterProvider());
+ }
+
+ @After
+ public void after() throws Exception {
+ try {
+ root.refresh();
+ Authorizable a = getUserManager(root).getAuthorizable(uid);
+ if (a != null) {
+ a.remove();
+ root.commit();
+ }
+ } finally {
+ super.after();
+ }
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of(AuthorizationConfiguration.NAME,
ConfigurationParameters.of(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR,
ImportBehavior.NAME_BESTEFFORT));
+ }
+
+ private PrincipalPolicyImpl getApplicable() throws Exception {
+ JackrabbitAccessControlPolicy[] applicable =
acMgr.getApplicablePolicies(principal);
+ return (PrincipalPolicyImpl) applicable[0];
+ }
+
+ @Test
+ public void testApplicablePolicies() throws Exception {
+ JackrabbitAccessControlPolicy[] applicable =
acMgr.getApplicablePolicies(principal);
+ assertEquals(1, applicable.length);
+ assertTrue(applicable[0] instanceof PrincipalPolicyImpl);
+ assertEquals(principal.getName(), ((PrincipalPolicyImpl)
applicable[0]).getPrincipal().getName());
+ }
+
+ @Test
+ public void testTransientGetSetRemovePolicy() throws Exception {
+ JackrabbitAccessControlPolicy[] policies =
acMgr.getPolicies(principal);
+ assertEquals(0, policies.length);
+
+ PrincipalPolicyImpl policy = getApplicable();
+ acMgr.setPolicy(policy.getPath(), policy);
+
+ policies = acMgr.getPolicies(principal);
+ assertEquals(1, policies.length);
+ assertTrue(policies[0] instanceof PrincipalPolicyImpl);
+
+ policy = (PrincipalPolicyImpl) policies[0];
+ assertTrue(policy.isEmpty());
+
+ policy.addEntry(testContentJcrPath,
privilegesFromNames(JCR_VERSION_MANAGEMENT));
+ acMgr.setPolicy(policy.getPath(), policy);
+
+ policies = acMgr.getPolicies(principal);
+ assertEquals(1, policies.length);
+ assertTrue(policies[0] instanceof PrincipalPolicyImpl);
+
+ policy = (PrincipalPolicyImpl) policies[0];
+ assertEquals(1, policy.size());
+
+ acMgr.removePolicy(policy.getPath(), policy);
+ policies = acMgr.getPolicies(principal);
+ assertEquals(0, policies.length);
+ }
+
+ @Test
+ public void testGetSetRemovePolicy() throws Exception {
+ JackrabbitAccessControlPolicy[] policies =
acMgr.getPolicies(principal);
+ assertEquals(0, policies.length);
+
+ PrincipalPolicyImpl policy = getApplicable();
+ acMgr.setPolicy(policy.getPath(), policy);
+ root.commit();
+
+ policies = acMgr.getPolicies(principal);
+ assertEquals(1, policies.length);
+
+ acMgr.removePolicy(policy.getPath(), policy);
+ root.commit();
+
+ policies = acMgr.getPolicies(principal);
+ assertEquals(0, policies.length);
+ }
+
+ @Test
+ public void testGetEffectivePolicies() throws Exception {
+ AccessControlPolicy[] effective =
acMgr.getEffectivePolicies(ImmutableSet.of(principal));
+ assertEquals(0, effective.length);
+
+ PrincipalPolicyImpl policy = getApplicable();
+ policy.addEntry(testJcrPath, privilegesFromNames(JCR_WRITE));
+ acMgr.setPolicy(policy.getPath(), policy);
+
+ effective = acMgr.getEffectivePolicies(ImmutableSet.of(principal));
+ assertEquals(0, effective.length);
+ }
+
+ @Test
+ public void testGetEffectivePoliciesByPath() throws Exception {
+ setupContentTrees(TEST_OAK_PATH);
+
+ AccessControlPolicy[] effective =
acMgr.getEffectivePolicies(testJcrPath);
+ assertEquals(0, effective.length);
+
+ PrincipalPolicyImpl policy = getApplicable();
+ policy.addEntry(testJcrPath, privilegesFromNames(JCR_WRITE));
+ acMgr.setPolicy(policy.getPath(), policy);
+
+ effective = acMgr.getEffectivePolicies(testJcrPath);
+ assertEquals(0, effective.length);
+ }
+
+ @Test
+ public void testGetPrivileges() throws Exception {
+ setupContentTrees(TEST_OAK_PATH);
+ assertEquals(0, acMgr.getPrivileges(testJcrPath,
ImmutableSet.of(principal)).length);
+
+ // transient modifications => not respected by permission evaluation
+ PrincipalPolicyImpl policy = getApplicable();
+ policy.addEntry(testJcrPath, privilegesFromNames(JCR_LOCK_MANAGEMENT));
+ acMgr.setPolicy(policy.getPath(), policy);
+
+ assertEquals(0, acMgr.getPrivileges(testJcrPath,
ImmutableSet.of(principal)).length);
+ }
+
+ @Test
+ public void testGetPermssionProvider() throws Exception {
+ PrincipalBasedAuthorizationConfiguration pbac =
getPrincipalBasedAuthorizationConfiguration();
+ // with remapped namespaces
+ PermissionProvider pp = pbac.getPermissionProvider(root,
root.getContentSession().getWorkspaceName(), ImmutableSet.of(principal));
+ assertSame(EmptyPermissionProvider.getInstance(), pp);
+
+ // with default ns-mapping as used to create permission provider
+ Principal transientWithDefaultNs =
getConfig(UserConfiguration.class).getUserManager(root,
NamePathMapper.DEFAULT).getAuthorizable(uid).getPrincipal();
+ pp = pbac.getPermissionProvider(root,
root.getContentSession().getWorkspaceName(),
ImmutableSet.of(transientWithDefaultNs));
+ // since permission provider is created with a read-only root the
transient principal node does not exist and
+ // no evaluation will take place
+ assertSame(EmptyPermissionProvider.getInstance(), pp);
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalAbortTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalAbortTest.java?rev=1857551&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalAbortTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalAbortTest.java
Mon Apr 15 07:16:49 2019
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.principal.SystemUserPrincipal;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlPolicy;
+
+import static org.junit.Assert.assertEquals;
+
+public class UnknownPrincipalAbortTest extends AbstractPrincipalBasedTest {
+
+ private PrincipalBasedAccessControlManager acMgr;
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+ acMgr = createAccessControlManager(root);
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of(AuthorizationConfiguration.NAME,
+ ConfigurationParameters.of(
+ ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR,
ImportBehavior.NAME_ABORT)
+ );
+ }
+
+ @Test(expected = AccessControlException.class)
+ public void testGetApplicablePolicies() throws Exception {
+ acMgr.getApplicablePolicies((SystemUserPrincipal) () -> "unknown");
+ }
+
+ @Test(expected = AccessControlException.class)
+ public void testGetPolicies() throws Exception {
+ acMgr.getPolicies((AdminPrincipal) () -> "unknown");
+ }
+
+ @Test(expected = AccessControlException.class)
+ public void testGetEffectivePolicies() throws Exception {
+ AccessControlPolicy[] policies =
acMgr.getEffectivePolicies(ImmutableSet.of(getTestSystemUser().getPrincipal(),
new PrincipalImpl("unknown")));
+ assertEquals(0, policies.length);
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalAbortTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalBesteffortTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalBesteffortTest.java?rev=1857551&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalBesteffortTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalBesteffortTest.java
Mon Apr 15 07:16:49 2019
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.principal.SystemUserPrincipal;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.security.AccessControlPolicy;
+
+import static org.junit.Assert.assertEquals;
+
+public class UnknownPrincipalBesteffortTest extends UnknownPrincipalIgnoreTest
{
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of(AuthorizationConfiguration.NAME,
+ ConfigurationParameters.of(
+ ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR,
ImportBehavior.NAME_BESTEFFORT)
+ );
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalBesteffortTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalIgnoreTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalIgnoreTest.java?rev=1857551&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalIgnoreTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalIgnoreTest.java
Mon Apr 15 07:16:49 2019
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.principal.SystemUserPrincipal;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.security.AccessControlPolicy;
+
+import static org.junit.Assert.assertEquals;
+
+public class UnknownPrincipalIgnoreTest extends AbstractPrincipalBasedTest {
+
+ private PrincipalBasedAccessControlManager acMgr;
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+ acMgr = createAccessControlManager(root);
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of(AuthorizationConfiguration.NAME,
+ ConfigurationParameters.of(
+ ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR,
ImportBehavior.NAME_IGNORE)
+ );
+ }
+
+ @Test
+ public void testGetApplicablePolicies() throws Exception {
+ AccessControlPolicy[] applicable =
acMgr.getApplicablePolicies((SystemUserPrincipal) () -> "unknown");
+ assertEquals(0, applicable.length);
+ }
+
+ @Test
+ public void testGetPolicies() throws Exception {
+ AccessControlPolicy[] policies = acMgr.getPolicies((AdminPrincipal) ()
-> "unknown");
+ assertEquals(0, policies.length);
+ }
+
+ @Test
+ public void testGetEffectivePolicies() throws Exception {
+ AccessControlPolicy[] policies =
acMgr.getEffectivePolicies(ImmutableSet.of(getTestSystemUser().getPrincipal(),
new PrincipalImpl("unknown")));
+ assertEquals(0, policies.length);
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UnknownPrincipalIgnoreTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UtilsTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UtilsTest.java?rev=1857551&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UtilsTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UtilsTest.java
Mon Apr 15 07:16:49 2019
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.Filter;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.Privilege;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Set;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+public class UtilsTest implements Constants {
+
+ private static final Principal PRINCIPAL = new PrincipalImpl("name");
+ private static final String INVALID_PRIVILEGE_NAME = "invalid";
+
+ private static Tree mockTree(boolean exists, @NotNull String name,
@Nullable String type) {
+ return MockUtility.mockTree(name, type, exists);
+ }
+
+ private static Filter mockFilter(boolean canHandle) {
+ Filter filter = Mockito.mock(Filter.class);
+ when(filter.canHandle(any(Set.class))).thenReturn(canHandle);
+ return filter;
+ }
+
+ private static PrivilegeManager mockPrivilegeManager() throws
RepositoryException {
+ PrivilegeManager privilegeManager =
Mockito.mock(PrivilegeManager.class);
+
when(privilegeManager.getPrivilege(any(String.class))).then((Answer<Privilege>)
invocationOnMock -> {
+ Privilege p = Mockito.mock(Privilege.class);
+ when(p.getName()).thenReturn(invocationOnMock.getArgument(0));
+ return p;
+ });
+
when(privilegeManager.getPrivilege(INVALID_PRIVILEGE_NAME)).thenThrow(new
AccessControlException());
+ return privilegeManager;
+ }
+
+ @Test
+ public void testIsPrincipalPolicyTreeNotExists() {
+ assertFalse(Utils.isPrincipalPolicyTree(mockTree(false,
NT_REP_PRINCIPAL_POLICY, REP_PRINCIPAL_POLICY)));
+ }
+
+ @Test
+ public void testIsPrincipalPolicyTreeWrongName() {
+ assertFalse(Utils.isPrincipalPolicyTree(mockTree(true,
REP_RESTRICTIONS, NT_REP_PRINCIPAL_POLICY)));
+ }
+
+ @Test
+ public void testIsPrincipalPolicyTreeWrongType() {
+ assertFalse(Utils.isPrincipalPolicyTree(mockTree(true,
REP_PRINCIPAL_POLICY, NT_REP_RESTRICTIONS)));
+ }
+
+ @Test
+ public void testIsPrincipalPolicyTreeMissingType() {
+ assertFalse(Utils.isPrincipalPolicyTree(mockTree(true,
REP_PRINCIPAL_POLICY, null)));
+ }
+
+ @Test
+ public void testIsPrincipalPolicyTreeWrongNameType() {
+ assertFalse(Utils.isPrincipalPolicyTree(mockTree(true,
REP_RESTRICTIONS, NT_REP_RESTRICTIONS)));
+ }
+
+ @Test
+ public void testIsPrincipalPolicyTree() {
+ assertTrue(Utils.isPrincipalPolicyTree(mockTree(true,
REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY))); }
+
+ @Test(expected = AccessControlException.class)
+ public void testCanHandleNullName() throws Exception {
+ Utils.canHandle(Mockito.mock(Principal.class), mockFilter(true),
ImportBehavior.ABORT);
+ }
+
+ @Test(expected = AccessControlException.class)
+ public void testCanHandleEmptyName() throws Exception {
+ Utils.canHandle(new PrincipalImpl(""), mockFilter(true),
ImportBehavior.ABORT);
+ }
+
+ @Test(expected = AccessControlException.class)
+ public void testCanHandleUnsupportedPrincipalAbort() throws Exception {
+ Utils.canHandle(PRINCIPAL, mockFilter(false), ImportBehavior.ABORT);
+ }
+
+ @Test
+ public void testCanHandleUnsupportedPrincipalIgnore() throws Exception {
+ assertFalse(Utils.canHandle(PRINCIPAL, mockFilter(false),
ImportBehavior.IGNORE));
+ }
+
+ @Test
+ public void testCanHandleUnsupportedPrincipalBestEffort() throws Exception
{
+ assertFalse(Utils.canHandle(PRINCIPAL, mockFilter(false),
ImportBehavior.BESTEFFORT));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCanHandleIllegalImportBehavior() throws Exception {
+ assertFalse(Utils.canHandle(PRINCIPAL, mockFilter(true), -1));
+ }
+
+ @Test
+ public void testCanHandle() throws Exception {
+ for (int behavior : new int[] {ImportBehavior.ABORT,
ImportBehavior.BESTEFFORT, ImportBehavior.IGNORE}) {
+ assertTrue(Utils.canHandle(PRINCIPAL, mockFilter(true), behavior));
+ }
+ }
+
+ @Test
+ public void testPrivilegesFromNamesEmptyNames() {
+ assertArrayEquals(new Privilege[0],
Utils.privilegesFromOakNames(Collections.emptySet(),
Mockito.mock(PrivilegeManager.class), NamePathMapper.DEFAULT));
+ }
+
+ @Test
+ public void testPrivilegesFromNamesInvalidName() throws Exception {
+ assertArrayEquals(new Privilege[0],
Utils.privilegesFromOakNames(Collections.singleton(INVALID_PRIVILEGE_NAME),
mockPrivilegeManager(), NamePathMapper.DEFAULT));
+ }
+
+ @Test
+ public void testPrivilegesFromNamesRemapped() throws Exception {
+ NamePathMapper mapper = Mockito.mock(NamePathMapper.class);
+ when(mapper.getJcrName(any())).thenReturn("c");
+
+ Privilege[] privs = Utils.privilegesFromOakNames(Sets.newHashSet("a",
"b"), mockPrivilegeManager(), mapper);
+ assertEquals(2, privs.length);
+ for (Privilege p : privs) {
+ assertEquals("c", p.getName());
+ }
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/UtilsTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/VersionTreePermissionTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/VersionTreePermissionTest.java?rev=1857551&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/VersionTreePermissionTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/VersionTreePermissionTest.java
Mon Apr 15 07:16:49 2019
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.plugins.version.ReadOnlyVersionManager;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import
org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.version.VersionConstants;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.Principal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.JcrConstants.JCR_BASEVERSION;
+import static org.apache.jackrabbit.JcrConstants.JCR_FROZENNODE;
+import static org.apache.jackrabbit.JcrConstants.JCR_ISCHECKEDOUT;
+import static org.apache.jackrabbit.JcrConstants.JCR_VERSIONHISTORY;
+import static org.apache.jackrabbit.JcrConstants.NT_VERSIONEDCHILD;
+import static
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.MockUtility.mockNodeState;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class VersionTreePermissionTest extends AbstractPrincipalBasedTest {
+ private Principal testPrincipal;
+ private PrincipalBasedPermissionProvider permissionProvider;
+
+ private String contentPath;
+ private String childPath;
+ private String grandchildPath;
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+
+ testPrincipal = getTestSystemUser().getPrincipal();
+ setupContentTrees(TEST_OAK_PATH);
+
+ contentPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 3);
+ childPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 2);
+ grandchildPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 1);
+
+ // setup permissions on childPath + TEST_OAK_PATH
+ PrincipalPolicyImpl policy =
setupPrincipalBasedAccessControl(testPrincipal,
getNamePathMapper().getJcrPath(childPath), JCR_READ);
+ addPrincipalBasedEntry(policy,
getNamePathMapper().getJcrPath(TEST_OAK_PATH),
PrivilegeConstants.JCR_VERSION_MANAGEMENT);
+
+ // versionabel nodes: contentPath + grandChildPath + TEST_OAK_PATH
+ // -> TEST_OAK_PATH versionable node holds policy, grandchildPath get
permissions inherited, and contentPath has no permissions granted
+ Tree typeRoot = root.getTree(NodeTypeConstants.NODE_TYPES_PATH);
+ for (String path : new String[] {contentPath, grandchildPath,
TEST_OAK_PATH}) {
+ Tree versionable = root.getTree(path);
+ TreeUtil.addMixin(root.getTree(path),
NodeTypeConstants.MIX_VERSIONABLE, typeRoot, "uid");
+ }
+ root.commit();
+
+ // force creation of a new versions (except for TEST_OAK_PATH)
+ for (String path : new String[] {contentPath, grandchildPath}) {
+ root.getTree(path).setProperty(JCR_ISCHECKEDOUT, false);
+ root.commit();
+ root.getTree(path).setProperty(JCR_ISCHECKEDOUT, true);
+ root.commit();
+ }
+
+ permissionProvider = createPermissionProvider(root, testPrincipal);
+ }
+
+ @Override
+ protected NamePathMapper getNamePathMapper() {
+ return NamePathMapper.DEFAULT;
+ }
+
+ @NotNull
+ private String getPathFromReference(@NotNull String treePath, @NotNull
String refProperty) {
+ Tree tree = root.getTree(treePath);
+ String path = new
IdentifierManager(root).getPath(tree.getProperty(refProperty));
+ checkNotNull(path);
+ return path;
+ }
+
+ @NotNull
+ private AbstractTreePermission getTreePermission(@NotNull String path) {
+ Tree tree = root.getTree(PathUtils.ROOT_PATH);
+ TreePermission tp = permissionProvider.getTreePermission(tree,
TreePermission.EMPTY);
+ for (String elem : PathUtils.elements(path)) {
+ tree = tree.getChild(elem);
+ tp = permissionProvider.getTreePermission(tree, tp);
+ }
+ assertTrue(tp instanceof AbstractTreePermission);
+ return (AbstractTreePermission) tp;
+ }
+
+ @Test
+ public void testGetTreePermissionVersionHistory() {
+ String vhPath = getPathFromReference(TEST_OAK_PATH,
JCR_VERSIONHISTORY);
+ AbstractTreePermission tp = getTreePermission(vhPath);
+
+ assertSame(TreeType.VERSION, tp.getType());
+ assertNotEquals(vhPath, tp.getTree().getPath());
+ assertSame(permissionProvider, tp.getPermissionProvider());
+ }
+
+ @Test
+ public void testGetTreePermissionVersion() {
+ String versionPath = getPathFromReference(TEST_OAK_PATH,
JCR_BASEVERSION);
+ AbstractTreePermission tp = getTreePermission(versionPath);
+
+ assertSame(TreeType.VERSION, tp.getType());
+ assertNotEquals(versionPath, tp.getTree().getPath());
+ assertSame(permissionProvider, tp.getPermissionProvider());
+ }
+
+ @Test
+ public void testGetChildPermissionRootVersionNode() {
+ String vhPath = getPathFromReference(contentPath, JCR_VERSIONHISTORY);
+ AbstractTreePermission tp = getTreePermission(vhPath);
+
+ TreePermission rootversionTp =
tp.getChildPermission(VersionConstants.JCR_ROOTVERSION,
mockNodeState(VersionConstants.NT_VERSION));
+ assertTrue(rootversionTp instanceof AbstractTreePermission);
+
+ assertSame(tp.getTree(), ((AbstractTreePermission)
rootversionTp).getTree());
+ }
+
+ @Test
+ public void testGetChildPermissionVersion1Node() {
+ String vhPath = getPathFromReference(TEST_OAK_PATH,
JCR_VERSIONHISTORY);
+ AbstractTreePermission tp = getTreePermission(vhPath);
+
+ TreePermission versionTp = tp.getChildPermission("1.0",
mockNodeState(VersionConstants.NT_VERSION));
+ assertTrue(versionTp instanceof AbstractTreePermission);
+
+ assertSame(tp.getTree(), ((AbstractTreePermission)
versionTp).getTree());
+ }
+
+ @Test
+ public void testGetChildPermissionLabelsNode() {
+ String vhPath = getPathFromReference(contentPath, JCR_VERSIONHISTORY);
+ AbstractTreePermission tp = getTreePermission(vhPath);
+
+ TreePermission labelsTp =
tp.getChildPermission(VersionConstants.JCR_VERSIONLABELS,
mockNodeState(VersionConstants.NT_VERSIONLABELS));
+ assertTrue(labelsTp instanceof AbstractTreePermission);
+
+ assertSame(tp.getTree(), ((AbstractTreePermission)
labelsTp).getTree());
+ }
+
+ @Test
+ public void testGetChildPermissionFrozenNode() {
+ String v1Path = getPathFromReference(grandchildPath, JCR_BASEVERSION);
+ Tree v1Tree = root.getTree(v1Path);
+ assertTrue(v1Tree.exists());
+
+ AbstractTreePermission tp = getTreePermission(v1Path);
+ TreePermission frozenTp =
tp.getChildPermission(VersionConstants.JCR_FROZENNODE,
getTreeProvider().asNodeState(v1Tree.getChild(JCR_FROZENNODE)));
+
+ assertSame(tp.getTree(), ((AbstractTreePermission)
frozenTp).getTree());
+ }
+
+ @Test
+ public void testVersionedChildNode() {
+ String path = PathUtils.concat(getPathFromReference(contentPath,
JCR_BASEVERSION), VersionConstants.JCR_FROZENNODE,
PathUtils.getName(childPath));
+ AbstractTreePermission tp = getTreePermission(path);
+
+ String versionedChildName = PathUtils.getName(grandchildPath);
+ String versionedChildPath = PathUtils.concat(path, versionedChildName);
+ Tree versionedChildTree = root.getTree(versionedChildPath);
+ assertEquals(NT_VERSIONEDCHILD,
TreeUtil.getPrimaryTypeName(versionedChildTree));
+
+ TreePermission versionedChildTp =
tp.getChildPermission(versionedChildName,
getTreeProvider().asNodeState(versionedChildTree));
+ assertTrue(versionedChildTp instanceof AbstractTreePermission);
+
+ Tree childVersionHistory =
root.getTree(getPathFromReference(versionedChildPath,
VersionConstants.JCR_CHILD_VERSION_HISTORY));
+ assertTrue(childVersionHistory.exists());
+ Tree versionable = ReadOnlyVersionManager.getInstance(root,
getNamePathMapper()).getVersionable(childVersionHistory,
root.getContentSession().getWorkspaceName());
+
+ assertEquals(versionable.getPath(), ((AbstractTreePermission)
versionedChildTp).getTree().getPath());
+ }
+
+ @Test
+ public void testVersionedChildNodePointingToRemovedVH() throws
CommitFailedException {
+ root.getTree(TEST_OAK_PATH).remove();
+ root.commit();
+ permissionProvider.refresh();
+
+ String path = PathUtils.concat(getPathFromReference(grandchildPath,
JCR_BASEVERSION), JCR_FROZENNODE);
+ AbstractTreePermission tp = getTreePermission(path);
+
+ String versionedChildName = PathUtils.getName(TEST_OAK_PATH);
+ String versionedChildPath = PathUtils.concat(path, versionedChildName);
+ Tree versionedChildTree = root.getTree(versionedChildPath);
+ assertEquals(NT_VERSIONEDCHILD,
TreeUtil.getPrimaryTypeName(versionedChildTree));
+
+ TreePermission versionedChildTp =
tp.getChildPermission(versionedChildName,
getTreeProvider().asNodeState(versionedChildTree));
+ assertTrue(versionedChildTp instanceof AbstractTreePermission);
+
+ assertEquals(TEST_OAK_PATH, ((AbstractTreePermission)
versionedChildTp).getTree().getPath());
+ assertTrue(versionedChildTp.canRead());
+ // version-mgt permission still granted because it is not stored on
the removed node
+ assertTrue(versionedChildTp.isGranted(Permissions.VERSION_MANAGEMENT));
+ }
+
+
+ @Test
+ public void testGetChildPermissionCopiedChild() {
+ String frozenPath = PathUtils.concat(getPathFromReference(contentPath,
JCR_BASEVERSION), JCR_FROZENNODE);
+ AbstractTreePermission tp = getTreePermission(frozenPath);
+
+ String copiedChildName = PathUtils.getName(childPath);
+ Tree copiedChildTree = root.getTree(PathUtils.concat(frozenPath,
copiedChildName));
+
+ TreePermission copiedChildTp = tp.getChildPermission(copiedChildName,
getTreeProvider().asNodeState(copiedChildTree));
+ assertTrue(copiedChildTp instanceof AbstractTreePermission);
+
+ assertEquals(childPath, ((AbstractTreePermission)
copiedChildTp).getTree().getPath());
+ }
+
+ @Test
+ public void testIsGrantedVersionHistoryNode() {
+ String vhPath = getPathFromReference(contentPath, JCR_VERSIONHISTORY);
+ AbstractTreePermission tp = getTreePermission(vhPath);
+ assertFalse(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+
+ vhPath = getPathFromReference(grandchildPath, JCR_VERSIONHISTORY);
+ tp = getTreePermission(vhPath);
+ assertTrue(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+
+ vhPath = getPathFromReference(TEST_OAK_PATH, JCR_VERSIONHISTORY);
+ tp = getTreePermission(vhPath);
+ assertTrue(tp.canRead());
+ assertTrue(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+ }
+
+ @Test
+ public void testIsGrantedVersionNode() {
+ String vPath = getPathFromReference(contentPath, JCR_BASEVERSION);
+ AbstractTreePermission tp = getTreePermission(vPath);
+ assertFalse(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+
+ vPath = getPathFromReference(grandchildPath, JCR_BASEVERSION);
+ tp = getTreePermission(vPath);
+ assertTrue(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+
+ vPath = getPathFromReference(TEST_OAK_PATH, JCR_BASEVERSION);
+ tp = getTreePermission(vPath);
+ assertTrue(tp.canRead());
+ assertTrue(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+ }
+
+ @Test
+ public void testIsGrantedFrozenNode() {
+ String frozenPath = PathUtils.concat(getPathFromReference(contentPath,
JCR_BASEVERSION), JCR_FROZENNODE);
+ AbstractTreePermission tp = getTreePermission(frozenPath);
+ assertFalse(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+
+ frozenPath = PathUtils.concat(getPathFromReference(grandchildPath,
JCR_BASEVERSION), JCR_FROZENNODE);
+ tp = getTreePermission(frozenPath);
+ assertTrue(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+
+ frozenPath = PathUtils.concat(getPathFromReference(TEST_OAK_PATH,
JCR_BASEVERSION), JCR_FROZENNODE);
+ tp = getTreePermission(frozenPath);
+ assertTrue(tp.canRead());
+ assertTrue(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+ }
+
+ @Test
+ public void testIsGrantedCopiedChild() {
+ String copiedChildPath =
PathUtils.concat(getPathFromReference(contentPath, JCR_BASEVERSION),
JCR_FROZENNODE, PathUtils.getName(childPath));
+ assertTrue(root.getTree(copiedChildPath).exists());
+
+ AbstractTreePermission tp = getTreePermission(copiedChildPath);
+ assertTrue(tp.canRead());
+ assertFalse(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+ }
+
+ @Test
+ public void testIsGrantedVersionedChild() {
+ String versionedChildPath =
PathUtils.concat(getPathFromReference(grandchildPath, JCR_BASEVERSION),
JCR_FROZENNODE, PathUtils.getName(TEST_OAK_PATH));
+ assertTrue(root.getTree(versionedChildPath).exists());
+
+ AbstractTreePermission tp = getTreePermission(versionedChildPath);
+ assertTrue(tp.canRead());
+ assertTrue(tp.isGranted(Permissions.VERSION_MANAGEMENT));
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/VersionTreePermissionTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/pom.xml?rev=1857551&r1=1857550&r2=1857551&view=diff
==============================================================================
--- jackrabbit/oak/trunk/pom.xml (original)
+++ jackrabbit/oak/trunk/pom.xml Mon Apr 15 07:16:49 2019
@@ -67,6 +67,7 @@
<module>oak-it-osgi</module>
<module>oak-pojosr</module>
<module>oak-authorization-cug</module>
+ <module>oak-authorization-principalbased</module>
<module>oak-exercise</module>
<module>oak-examples</module>
<module>oak-it</module>