You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2021/07/22 15:20:36 UTC
[jackrabbit-oak] branch trunk updated: OAK-9511 : Improvements to
security related Delegators in org.apache.jackrabbit.oak.jcr.delegate
This is an automated email from the ASF dual-hosted git repository.
angela pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/trunk by this push:
new 36f9c23 OAK-9511 : Improvements to security related Delegators in org.apache.jackrabbit.oak.jcr.delegate
36f9c23 is described below
commit 36f9c2395be765a7317827d4124d593f22bbad26
Author: angela <an...@adobe.com>
AuthorDate: Thu Jul 22 17:20:12 2021 +0200
OAK-9511 : Improvements to security related Delegators in org.apache.jackrabbit.oak.jcr.delegate
---
.../delegate/AccessControlManagerDelegator.java | 28 +--
.../oak/jcr/delegate/AuthorizableDelegator.java | 35 ++--
.../oak/jcr/delegate/GroupDelegator.java | 30 +--
.../oak/jcr/delegate/ImpersonationDelegator.java | 12 +-
.../JackrabbitAccessControlManagerDelegator.java | 37 ++--
.../jcr/delegate/PrincipalManagerDelegator.java | 22 +-
.../jcr/delegate/PrivilegeManagerDelegator.java | 19 +-
.../oak/jcr/delegate/SessionDelegate.java | 22 +-
.../jackrabbit/oak/jcr/delegate/UserDelegator.java | 10 +-
.../oak/jcr/delegate/UserManagerDelegator.java | 43 +---
.../oak/jcr/delegate/WorkspaceDelegate.java | 25 ++-
...elegateTest.java => AbstractDelegatorTest.java} | 66 ++----
.../jcr/delegate/AuthorizableDelegatorTest.java | 232 +++++++++++++++++++++
.../jcr/delegate/ImpersonationDelegatorTest.java | 89 ++++++++
...ackrabbitAccessControlManagerDelegatorTest.java | 205 ++++++++++++++++++
.../delegate/PrincipalManagerDelegatorTest.java | 128 ++++++++++++
.../oak/jcr/delegate/SessionDelegateTest.java | 76 +------
.../oak/jcr/delegate/UserManagerDelegatorTest.java | 217 +++++++++++++++++++
18 files changed, 999 insertions(+), 297 deletions(-)
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AccessControlManagerDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AccessControlManagerDelegator.java
index c64ef28..80bb337 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AccessControlManagerDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AccessControlManagerDelegator.java
@@ -38,7 +38,7 @@ public class AccessControlManagerDelegator implements AccessControlManager {
private final SessionDelegate delegate;
private final AccessControlManager acManager;
- public AccessControlManagerDelegator(SessionDelegate delegate, AccessControlManager acManager) {
+ public AccessControlManagerDelegator(@NotNull SessionDelegate delegate, @NotNull AccessControlManager acManager) {
this.acManager = acManager;
this.delegate = delegate;
}
@@ -48,7 +48,7 @@ public class AccessControlManagerDelegator implements AccessControlManager {
return delegate.perform(new SessionOperation<Privilege[]>("getSupportedPrivileges") {
@NotNull
@Override
- public Privilege[] perform() throws RepositoryException {
+ public Privilege @NotNull [] perform() throws RepositoryException {
return acManager.getSupportedPrivileges(absPath);
}
});
@@ -66,8 +66,7 @@ public class AccessControlManagerDelegator implements AccessControlManager {
}
@Override
- public boolean hasPrivileges(final String absPath, final Privilege[] privileges)
- throws RepositoryException {
+ public boolean hasPrivileges(final String absPath, final Privilege[] privileges) throws RepositoryException {
return delegate.perform(new SessionOperation<Boolean>("hasPrivileges") {
@NotNull
@Override
@@ -80,9 +79,8 @@ public class AccessControlManagerDelegator implements AccessControlManager {
@Override
public Privilege[] getPrivileges(final String absPath) throws RepositoryException {
return delegate.perform(new SessionOperation<Privilege[]>("getPrivileges") {
- @NotNull
@Override
- public Privilege[] perform() throws RepositoryException {
+ public Privilege @NotNull [] perform() throws RepositoryException {
return acManager.getPrivileges(absPath);
}
});
@@ -91,29 +89,25 @@ public class AccessControlManagerDelegator implements AccessControlManager {
@Override
public AccessControlPolicy[] getPolicies(final String absPath) throws RepositoryException {
return delegate.perform(new SessionOperation<AccessControlPolicy[]>("getPolicies") {
- @NotNull
@Override
- public AccessControlPolicy[] perform() throws RepositoryException {
+ public AccessControlPolicy @NotNull [] perform() throws RepositoryException {
return acManager.getPolicies(absPath);
}
});
}
@Override
- public AccessControlPolicy[] getEffectivePolicies(final String absPath)
- throws RepositoryException {
+ public AccessControlPolicy[] getEffectivePolicies(final String absPath) throws RepositoryException {
return delegate.perform(new SessionOperation<AccessControlPolicy[]>("getEffectivePolicies") {
- @NotNull
@Override
- public AccessControlPolicy[] perform() throws RepositoryException {
+ public AccessControlPolicy @NotNull [] perform() throws RepositoryException {
return acManager.getEffectivePolicies(absPath);
}
});
}
@Override
- public AccessControlPolicyIterator getApplicablePolicies(final String absPath)
- throws RepositoryException {
+ public AccessControlPolicyIterator getApplicablePolicies(final String absPath) throws RepositoryException {
return delegate.perform(new SessionOperation<AccessControlPolicyIterator>("getApplicablePolicies") {
@NotNull
@Override
@@ -124,8 +118,7 @@ public class AccessControlManagerDelegator implements AccessControlManager {
}
@Override
- public void setPolicy(final String absPath, final AccessControlPolicy policy)
- throws RepositoryException {
+ public void setPolicy(final String absPath, final AccessControlPolicy policy) throws RepositoryException {
delegate.performVoid(new SessionOperation<Void>("setPolicy", true) {
@Override
public void performVoid() throws RepositoryException {
@@ -135,8 +128,7 @@ public class AccessControlManagerDelegator implements AccessControlManager {
}
@Override
- public void removePolicy(final String absPath, final AccessControlPolicy policy)
- throws RepositoryException {
+ public void removePolicy(final String absPath, final AccessControlPolicy policy) throws RepositoryException {
delegate.performVoid(new SessionOperation<Void>("removePolicy", true) {
@Override
public void performVoid() throws RepositoryException {
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegator.java
index b54eca5..bf27824 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegator.java
@@ -19,15 +19,6 @@
package org.apache.jackrabbit.oak.jcr.delegate;
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.security.Principal;
-import java.util.Iterator;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
@@ -36,6 +27,14 @@ import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
/**
* Base class for {@link GroupDelegator} and {@link UserDelegator}.
*/
@@ -50,6 +49,7 @@ abstract class AuthorizableDelegator implements Authorizable {
this.delegate = delegate;
}
+ @Nullable
static Authorizable wrap(@NotNull SessionDelegate sessionDelegate, @Nullable Authorizable authorizable) {
if (authorizable == null) {
return null;
@@ -61,6 +61,7 @@ abstract class AuthorizableDelegator implements Authorizable {
}
}
+ @NotNull
static Authorizable unwrap(@NotNull Authorizable authorizable) {
if (authorizable.isGroup()) {
return GroupDelegator.unwrap((Group) authorizable);
@@ -115,13 +116,7 @@ abstract class AuthorizableDelegator implements Authorizable {
@Override
public Iterator<Group> perform() throws RepositoryException {
Iterator<Group> groups = delegate.declaredMemberOf();
- return Iterators.transform(groups, new Function<Group, Group>() {
- @Nullable
- @Override
- public Group apply(@Nullable Group group) {
- return GroupDelegator.wrap(sessionDelegate, group);
- }
- });
+ return Iterators.transform(Iterators.filter(groups, Objects::nonNull), group -> GroupDelegator.wrap(sessionDelegate, group));
}
});
}
@@ -134,13 +129,7 @@ abstract class AuthorizableDelegator implements Authorizable {
@Override
public Iterator<Group> perform() throws RepositoryException {
Iterator<Group> groups = delegate.memberOf();
- return Iterators.transform(groups, new Function<Group, Group>() {
- @Nullable
- @Override
- public Group apply(@Nullable Group group) {
- return GroupDelegator.wrap(sessionDelegate, group);
- }
- });
+ return Iterators.transform(Iterators.filter(groups, Objects::nonNull), group -> GroupDelegator.wrap(sessionDelegate, group));
}
});
}
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/GroupDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/GroupDelegator.java
index a09380a..b4fb5f7 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/GroupDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/GroupDelegator.java
@@ -23,13 +23,11 @@ import java.util.Iterator;
import java.util.Set;
import javax.jcr.RepositoryException;
-import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* This implementation of {@code Group} delegates back to a
@@ -39,16 +37,13 @@ import org.jetbrains.annotations.Nullable;
*/
final class GroupDelegator extends AuthorizableDelegator implements Group {
- private GroupDelegator(SessionDelegate sessionDelegate, Group groupDelegate) {
+ private GroupDelegator(@NotNull SessionDelegate sessionDelegate, @NotNull Group groupDelegate) {
super(sessionDelegate, groupDelegate);
}
- static Group wrap(@NotNull SessionDelegate sessionDelegate, Group group) {
- if (group == null) {
- return null;
- } else {
- return new GroupDelegator(sessionDelegate, group);
- }
+ @NotNull
+ static Group wrap(@NotNull SessionDelegate sessionDelegate, @NotNull Group group) {
+ return new GroupDelegator(sessionDelegate, group);
}
@NotNull
@@ -60,6 +55,7 @@ final class GroupDelegator extends AuthorizableDelegator implements Group {
}
}
+ @NotNull
private Group getDelegate() {
return (Group) delegate;
}
@@ -73,13 +69,7 @@ final class GroupDelegator extends AuthorizableDelegator implements Group {
@Override
public Iterator<Authorizable> perform() throws RepositoryException {
Iterator<Authorizable> authorizables = getDelegate().getDeclaredMembers();
- return Iterators.transform(authorizables, new Function<Authorizable, Authorizable>() {
- @Nullable
- @Override
- public Authorizable apply(@Nullable Authorizable authorizable) {
- return wrap(sessionDelegate, authorizable);
- }
- });
+ return Iterators.transform(authorizables, authorizable -> wrap(sessionDelegate, authorizable));
}
});
}
@@ -92,13 +82,7 @@ final class GroupDelegator extends AuthorizableDelegator implements Group {
@Override
public Iterator<Authorizable> perform() throws RepositoryException {
Iterator<Authorizable> authorizables = getDelegate().getMembers();
- return Iterators.transform(authorizables, new Function<Authorizable, Authorizable>() {
- @Nullable
- @Override
- public Authorizable apply(@Nullable Authorizable authorizable) {
- return wrap(sessionDelegate, authorizable);
- }
- });
+ return Iterators.transform(authorizables, authorizable -> wrap(sessionDelegate, authorizable));
}
});
}
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegator.java
index 1f1e1c7..da9e279 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegator.java
@@ -38,21 +38,19 @@ import org.jetbrains.annotations.NotNull;
* @see SessionDelegate#perform(SessionOperation)
*/
final class ImpersonationDelegator implements Impersonation {
+
private final SessionDelegate sessionDelegate;
private final Impersonation impersonationDelegate;
- private ImpersonationDelegator(SessionDelegate sessionDelegate, Impersonation impersonationDelegate) {
+ private ImpersonationDelegator(@NotNull SessionDelegate sessionDelegate, @NotNull Impersonation impersonationDelegate) {
checkArgument(!(impersonationDelegate instanceof ImpersonationDelegator));
this.sessionDelegate = sessionDelegate;
this.impersonationDelegate = impersonationDelegate;
}
- static Impersonation wrap(SessionDelegate sessionDelegate, Impersonation impersonation) {
- if (impersonation == null) {
- return null;
- } else {
- return new ImpersonationDelegator(sessionDelegate, impersonation);
- }
+ @NotNull
+ static Impersonation wrap(@NotNull SessionDelegate sessionDelegate, @NotNull Impersonation impersonation) {
+ return new ImpersonationDelegator(sessionDelegate, impersonation);
}
@NotNull
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegator.java
index f842c5e..2ab4abd 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegator.java
@@ -41,12 +41,12 @@ import org.jetbrains.annotations.Nullable;
* @see SessionDelegate#perform(SessionOperation)
*/
public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccessControlManager {
+
private final JackrabbitAccessControlManager jackrabbitACManager;
private final SessionDelegate delegate;
private final AccessControlManagerDelegator jcrACManager;
- public JackrabbitAccessControlManagerDelegator(SessionDelegate delegate,
- JackrabbitAccessControlManager acManager) {
+ public JackrabbitAccessControlManagerDelegator(@NotNull SessionDelegate delegate, @NotNull JackrabbitAccessControlManager acManager) {
this.jackrabbitACManager = acManager;
this.delegate = delegate;
this.jcrACManager = new AccessControlManagerDelegator(delegate, acManager);
@@ -54,12 +54,10 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
@NotNull
@Override
- public JackrabbitAccessControlPolicy[] getApplicablePolicies(@NotNull final Principal principal)
- throws RepositoryException {
+ public JackrabbitAccessControlPolicy[] getApplicablePolicies(@NotNull final Principal principal) throws RepositoryException {
return delegate.perform(new SessionOperation<JackrabbitAccessControlPolicy[]>("getApplicablePolicies") {
- @NotNull
@Override
- public JackrabbitAccessControlPolicy[] perform() throws RepositoryException {
+ public JackrabbitAccessControlPolicy @NotNull [] perform() throws RepositoryException {
return jackrabbitACManager.getApplicablePolicies(principal);
}
});
@@ -67,12 +65,10 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
@NotNull
@Override
- public JackrabbitAccessControlPolicy[] getPolicies(@NotNull final Principal principal)
- throws RepositoryException {
+ public JackrabbitAccessControlPolicy[] getPolicies(@NotNull final Principal principal) throws RepositoryException {
return delegate.perform(new SessionOperation<JackrabbitAccessControlPolicy[]>("getPolicies") {
- @NotNull
@Override
- public JackrabbitAccessControlPolicy[] perform() throws RepositoryException {
+ public JackrabbitAccessControlPolicy @NotNull [] perform() throws RepositoryException {
return jackrabbitACManager.getPolicies(principal);
}
});
@@ -80,12 +76,10 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
@NotNull
@Override
- public AccessControlPolicy[] getEffectivePolicies(@NotNull final Set<Principal> principals)
- throws RepositoryException {
+ public AccessControlPolicy[] getEffectivePolicies(@NotNull final Set<Principal> principals) throws RepositoryException {
return delegate.perform(new SessionOperation<AccessControlPolicy[]>("getEffectivePolicies") {
- @NotNull
@Override
- public AccessControlPolicy[] perform() throws RepositoryException {
+ public AccessControlPolicy @NotNull [] perform() throws RepositoryException {
return jackrabbitACManager.getEffectivePolicies(principals);
}
});
@@ -105,12 +99,10 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
@NotNull
@Override
- public Privilege[] getPrivileges(@Nullable final String absPath, @NotNull final Set<Principal> principals)
- throws RepositoryException {
+ public Privilege[] getPrivileges(@Nullable final String absPath, @NotNull final Set<Principal> principals) throws RepositoryException {
return delegate.perform(new SessionOperation<Privilege[]>("getPrivileges") {
- @NotNull
@Override
- public Privilege[] perform() throws RepositoryException {
+ public Privilege @NotNull [] perform() throws RepositoryException {
return jackrabbitACManager.getPrivileges(absPath, principals);
}
});
@@ -149,8 +141,7 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
}
@Override
- public boolean hasPrivileges(String absPath, Privilege[] privileges)
- throws RepositoryException {
+ public boolean hasPrivileges(String absPath, Privilege[] privileges) throws RepositoryException {
return jcrACManager.hasPrivileges(absPath, privileges);
}
@@ -170,8 +161,7 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
}
@Override
- public AccessControlPolicyIterator getApplicablePolicies(String absPath)
- throws RepositoryException {
+ public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws RepositoryException {
return jcrACManager.getApplicablePolicies(absPath);
}
@@ -181,8 +171,7 @@ public class JackrabbitAccessControlManagerDelegator implements JackrabbitAccess
}
@Override
- public void removePolicy(String absPath, AccessControlPolicy policy)
- throws RepositoryException {
+ public void removePolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
jcrACManager.removePolicy(absPath, policy);
}
}
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegator.java
index 22deb7b..114546b 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegator.java
@@ -21,8 +21,6 @@ package org.apache.jackrabbit.oak.jcr.delegate;
import java.security.Principal;
-import javax.jcr.RepositoryException;
-
import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
@@ -37,11 +35,11 @@ import org.jetbrains.annotations.Nullable;
* @see SessionDelegate#perform(SessionOperation)
*/
public class PrincipalManagerDelegator implements PrincipalManager, PrincipalQueryManager {
+
private final SessionDelegate delegate;
private final PrincipalManager principalManager;
- public PrincipalManagerDelegator(SessionDelegate delegate,
- PrincipalManager principalManager) {
+ public PrincipalManagerDelegator(@NotNull SessionDelegate delegate, @NotNull PrincipalManager principalManager) {
this.principalManager = principalManager;
this.delegate = delegate;
}
@@ -60,16 +58,12 @@ public class PrincipalManagerDelegator implements PrincipalManager, PrincipalQue
@Nullable
@Override
public Principal getPrincipal(@NotNull final String principalName) {
- try {
- return delegate.performNullable(new SessionOperation<Principal>("getPrincipal") {
- @Override
- public Principal performNullable() {
- return principalManager.getPrincipal(principalName);
- }
- });
- } catch (RepositoryException e) {
- throw new RuntimeException("Unexpected exception thrown by operation 'getPrincipal'", e);
- }
+ return delegate.safePerformNullable(new SessionOperation<Principal>("getPrincipal") {
+ @Override
+ public Principal performNullable() {
+ return principalManager.getPrincipal(principalName);
+ }
+ });
}
@NotNull
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrivilegeManagerDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrivilegeManagerDelegator.java
index fb1af7b..dd50bc6 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrivilegeManagerDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PrivilegeManagerDelegator.java
@@ -19,17 +19,14 @@
package org.apache.jackrabbit.oak.jcr.delegate;
-import javax.jcr.AccessDeniedException;
-import javax.jcr.NamespaceException;
-import javax.jcr.RepositoryException;
-import javax.jcr.security.AccessControlException;
-import javax.jcr.security.Privilege;
-
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.Privilege;
+
/**
* This implementation of {@code PrivilegeManager} delegates back to a
* delegatee wrapping each call into a {@link SessionOperation} closure.
@@ -37,10 +34,11 @@ import org.jetbrains.annotations.Nullable;
* @see SessionDelegate#perform(SessionOperation)
*/
public class PrivilegeManagerDelegator implements PrivilegeManager {
+
private final PrivilegeManager pm;
private final SessionDelegate delegate;
- public PrivilegeManagerDelegator(SessionDelegate delegate, PrivilegeManager pm) {
+ public PrivilegeManagerDelegator(@NotNull SessionDelegate delegate, @NotNull PrivilegeManager pm) {
this.pm = pm;
this.delegate = delegate;
}
@@ -49,9 +47,8 @@ public class PrivilegeManagerDelegator implements PrivilegeManager {
@Override
public Privilege[] getRegisteredPrivileges() throws RepositoryException {
return delegate.perform(new SessionOperation<Privilege[]>("getRegisteredPrivileges") {
- @NotNull
@Override
- public Privilege[] perform() throws RepositoryException {
+ public Privilege @NotNull [] perform() throws RepositoryException {
return pm.getRegisteredPrivileges();
}
});
@@ -59,7 +56,7 @@ public class PrivilegeManagerDelegator implements PrivilegeManager {
@NotNull
@Override
- public Privilege getPrivilege(@NotNull final String privilegeName) throws AccessControlException, RepositoryException {
+ public Privilege getPrivilege(@NotNull final String privilegeName) throws RepositoryException {
return delegate.perform(new SessionOperation<Privilege>("getPrivilege") {
@NotNull
@Override
@@ -71,7 +68,7 @@ public class PrivilegeManagerDelegator implements PrivilegeManager {
@NotNull
@Override
- public Privilege registerPrivilege(@NotNull final String privilegeName, final boolean isAbstract, @Nullable final String[] declaredAggregateNames) throws AccessDeniedException, NamespaceException, RepositoryException {
+ public Privilege registerPrivilege(@NotNull final String privilegeName, final boolean isAbstract, @Nullable final String[] declaredAggregateNames) throws RepositoryException {
return delegate.perform(new SessionOperation<Privilege>("registerPrivilege", true) {
@NotNull
@Override
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
index cfab8f4..ab8013f 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
@@ -179,7 +179,7 @@ public class SessionDelegate {
* @return synchronized iterator
*/
public <T> Iterator<T> sync(Iterator<T> iterator) {
- return new SynchronizedIterator<T>(iterator, lock);
+ return new SynchronizedIterator<>(iterator, lock);
}
/**
@@ -293,6 +293,7 @@ public class SessionDelegate {
* @return the result of {@code sessionOperation.perform()}
* @see #getRoot()
*/
+ @NotNull
public <T> T safePerform(SessionOperation<T> sessionOperation) {
try {
return perform(sessionOperation);
@@ -301,6 +302,25 @@ public class SessionDelegate {
}
}
+ /**
+ * Same as {@link #performNullable(SessionOperation)} unless this method expects
+ * {@link SessionOperation#performNullable} <em>not</em> to throw a {@code RepositoryException}.
+ * Such exceptions will be wrapped into a {@code RuntimeException} and rethrown as they
+ * are considered an internal error.
+ *
+ * @param sessionOperation the {@code SessionOperation} to perform
+ * @param <T> return type of {@code sessionOperation}
+ * @return the result of {@code sessionOperation.performNullable()}
+ */
+ @Nullable
+ public <T> T safePerformNullable(SessionOperation<T> sessionOperation) {
+ try {
+ return performNullable(sessionOperation);
+ } catch (RepositoryException e) {
+ throw new RuntimeException("Unexpected exception thrown by operation " + sessionOperation, e);
+ }
+ }
+
@NotNull
public ContentSession getContentSession() {
return contentSession;
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserDelegator.java
index 1e2043c..982f446 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserDelegator.java
@@ -40,12 +40,9 @@ final class UserDelegator extends AuthorizableDelegator implements User {
super(sessionDelegate, userDelegate);
}
- static User wrap(SessionDelegate sessionDelegate, User user) {
- if (user == null) {
- return null;
- } else {
- return new UserDelegator(sessionDelegate, user);
- }
+ @NotNull
+ static User wrap(@NotNull SessionDelegate sessionDelegate, @NotNull User user) {
+ return new UserDelegator(sessionDelegate, user);
}
@NotNull
@@ -57,6 +54,7 @@ final class UserDelegator extends AuthorizableDelegator implements User {
}
}
+ @NotNull
private User getDelegate() {
return (User) delegate;
}
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegator.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegator.java
index eaa5853..a21b6b5 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegator.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegator.java
@@ -19,17 +19,8 @@
package org.apache.jackrabbit.oak.jcr.delegate;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.security.Principal;
-import java.util.Iterator;
-
-import javax.jcr.RepositoryException;
-
-import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.Query;
import org.apache.jackrabbit.api.security.user.User;
@@ -39,6 +30,12 @@ import org.apache.jackrabbit.oak.spi.security.user.util.UserUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+import java.util.Iterator;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
/**
* This implementation of {@code UserManager} delegates back to a
* delegatee wrapping each call into a {@link UserManager} closure.
@@ -51,7 +48,7 @@ public class UserManagerDelegator implements UserManager {
private final UserManager userManagerDelegate;
public UserManagerDelegator(final SessionDelegate sessionDelegate, UserManager userManagerDelegate) {
- checkState(!(userManagerDelegate instanceof UserManagerDelegator));
+ checkArgument(!(userManagerDelegate instanceof UserManagerDelegator));
this.sessionDelegate = sessionDelegate;
this.userManagerDelegate = userManagerDelegate;
}
@@ -114,13 +111,7 @@ public class UserManagerDelegator implements UserManager {
@Override
public Iterator<Authorizable> perform() throws RepositoryException {
Iterator<Authorizable> authorizables = userManagerDelegate.findAuthorizables(relPath, value);
- return Iterators.transform(authorizables, new Function<Authorizable, Authorizable>() {
- @Nullable
- @Override
- public Authorizable apply(Authorizable authorizable) {
- return AuthorizableDelegator.wrap(sessionDelegate, authorizable);
- }
- });
+ return Iterators.transform(authorizables, authorizable -> AuthorizableDelegator.wrap(sessionDelegate, authorizable));
}
});
}
@@ -133,13 +124,7 @@ public class UserManagerDelegator implements UserManager {
@Override
public Iterator<Authorizable> perform() throws RepositoryException {
Iterator<Authorizable> authorizables = userManagerDelegate.findAuthorizables(relPath, value, searchType);
- return Iterators.transform(authorizables, new Function<Authorizable, Authorizable>() {
- @Nullable
- @Override
- public Authorizable apply(Authorizable authorizable) {
- return AuthorizableDelegator.wrap(sessionDelegate, authorizable);
- }
- });
+ return Iterators.transform(authorizables, authorizable -> AuthorizableDelegator.wrap(sessionDelegate, authorizable));
}
});
}
@@ -152,20 +137,14 @@ public class UserManagerDelegator implements UserManager {
@Override
public Iterator<Authorizable> perform() throws RepositoryException {
Iterator<Authorizable> authorizables = userManagerDelegate.findAuthorizables(query);
- return Iterators.transform(authorizables, new Function<Authorizable, Authorizable>() {
- @Nullable
- @Override
- public Authorizable apply(Authorizable authorizable) {
- return AuthorizableDelegator.wrap(sessionDelegate, authorizable);
- }
- });
+ return Iterators.transform(authorizables, authorizable -> AuthorizableDelegator.wrap(sessionDelegate, authorizable));
}
});
}
@NotNull
@Override
- public User createUser(@NotNull final String userID, @Nullable final String password) throws AuthorizableExistsException, RepositoryException {
+ public User createUser(@NotNull final String userID, @Nullable final String password) throws RepositoryException {
return sessionDelegate.perform(new UserManagerOperation<User>(sessionDelegate, "createUser", true) {
@NotNull
@Override
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/WorkspaceDelegate.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/WorkspaceDelegate.java
index a2a5704..8353e4a 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/WorkspaceDelegate.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/WorkspaceDelegate.java
@@ -43,6 +43,7 @@ import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissio
import org.apache.jackrabbit.oak.spi.version.VersionConstants;
import org.apache.jackrabbit.util.Text;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
@@ -67,7 +68,7 @@ public class WorkspaceDelegate {
* @param destPath oak path to the destination
* @throws RepositoryException
*/
- public void copy(String srcPath, String destPath) throws RepositoryException {
+ public void copy(@NotNull String srcPath, @NotNull String destPath) throws RepositoryException {
SessionDelegate sessionDelegate = context.getSessionDelegate();
AccessManager accessManager = context.getAccessManager();
Root root = sessionDelegate.getContentSession().getLatestRoot();
@@ -114,29 +115,28 @@ public class WorkspaceDelegate {
this.destName = destName;
}
- public void perform(@NotNull Root root, @NotNull String userId) throws RepositoryException {
+ public void perform(@NotNull Root root, @Nullable String userId) throws RepositoryException {
try {
Tree typeRoot = root.getTree(NODE_TYPES_PATH);
copy(source, destParent, destName, typeRoot, userId);
updateReferences(source, destParent.getChild(destName));
- Map<String, String> copyInfo = new HashMap<String, String>();
+ Map<String, String> copyInfo = new HashMap<>();
copyInfo.put("copy-source", source.getPath());
if (TreeUtil.isNodeType(source, JcrConstants.MIX_VERSIONABLE, typeRoot)) {
String sourceBaseVersionId = source.getProperty(JcrConstants.JCR_BASEVERSION).getValue(Type.STRING);
copyInfo.put(VersionConstants.JCR_COPIED_FROM, sourceBaseVersionId);
}
- root.commit(ImmutableMap.<String, Object>copyOf(copyInfo));
+ root.commit(ImmutableMap.copyOf(copyInfo));
} catch (CommitFailedException e) {
throw e.asRepositoryException();
}
}
- private void copy(Tree source, Tree destParent, String destName, Tree typeRoot, String userId)
+ private void copy(@NotNull Tree source, @NotNull Tree destParent, @NotNull String destName, @NotNull Tree typeRoot, @Nullable String userId)
throws RepositoryException {
String primaryType = TreeUtil.getPrimaryTypeName(source);
- Tree dest = TreeUtil.addChild(
- destParent, destName, primaryType, typeRoot, userId);
+ Tree dest = TreeUtil.addChild(destParent, destName, primaryType, typeRoot, userId);
for (PropertyState property : source.getProperties()) {
String propName = property.getName();
if (JCR_MIXINTYPES.equals(propName)) {
@@ -168,8 +168,7 @@ public class WorkspaceDelegate {
* @param src the source tree of the copy operation.
* @param dest the unprocessed copy of the tree.
*/
- private void updateReferences(Tree src, Tree dest)
- throws RepositoryException {
+ private void updateReferences(@NotNull Tree src, @NotNull Tree dest) {
for (PropertyState prop : src.getProperties()) {
if (isReferenceType(prop) && !VersionConstants.VERSION_PROPERTY_NAMES.contains(prop.getName())) {
updateProperty(prop, dest);
@@ -180,7 +179,7 @@ public class WorkspaceDelegate {
}
}
- private boolean isReferenceType(PropertyState property) {
+ private static boolean isReferenceType(@NotNull PropertyState property) {
Type<?> type = property.getType();
return (type == Type.REFERENCE
|| type == Type.REFERENCES
@@ -188,11 +187,11 @@ public class WorkspaceDelegate {
|| type == Type.WEAKREFERENCES);
}
- private void updateProperty(PropertyState prop, Tree dest) {
+ private void updateProperty(@NotNull PropertyState prop, @NotNull Tree dest) {
boolean multi = prop.isArray();
boolean weak = prop.getType() == Type.WEAKREFERENCE
|| prop.getType() == Type.WEAKREFERENCES;
- List<String> ids = new ArrayList<String>();
+ List<String> ids = new ArrayList<>();
for (int i = 0; i < prop.count(); i++) {
String id;
if (weak) {
@@ -221,7 +220,7 @@ public class WorkspaceDelegate {
dest.setProperty(p);
}
- private void translateId(String id, List<String> ids) {
+ private void translateId(@NotNull String id, @NotNull List<String> ids) {
String newId = translated.get(id);
if (newId != null) {
ids.add(newId);
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/AbstractDelegatorTest.java
similarity index 69%
copy from oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java
copy to oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/AbstractDelegatorTest.java
index 9fc7ed8..68a35e9 100644
--- a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/AbstractDelegatorTest.java
@@ -31,9 +31,10 @@ import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
import org.apache.jackrabbit.oak.stats.Clock;
import org.apache.jackrabbit.oak.stats.StatisticManager;
import org.jetbrains.annotations.NotNull;
-import org.junit.Test;
import org.mockito.MockSettings;
import org.mockito.stubbing.Answer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.concurrent.Executors;
@@ -42,25 +43,31 @@ import java.util.concurrent.ScheduledExecutorService;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
-public class SessionDelegateTest {
+public abstract class AbstractDelegatorTest {
+ private static final Logger log = LoggerFactory.getLogger(AbstractDelegatorTest.class);
+
+ @NotNull
+ static SessionDelegate mockSessionDelegate() {
+ PermissionProvider pp = mock(PermissionProvider.class);
+ return mockSessionDelegate(mockRoot(pp, true), pp);
+ }
+
@NotNull
- private static SessionDelegate mockSessionDelegate(@NotNull Root root, @NotNull PermissionProvider pp) {
+ static SessionDelegate mockSessionDelegate(@NotNull Root root, @NotNull PermissionProvider pp) {
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
Whiteboard wb = new DefaultWhiteboard();
StatisticManager statisticManager = new StatisticManager(wb, executorService);
- return new SessionDelegate(mockContentSession(root), mockSecurityProvider(root, pp),
- RefreshStrategy.Composite.create(), new ThreadLocal<>(), statisticManager, new Clock.Virtual());
+ return spy(new SessionDelegate(mockContentSession(root), mockSecurityProvider(root, pp),
+ RefreshStrategy.Composite.create(), new ThreadLocal<>(), statisticManager, new Clock.Virtual()));
}
@NotNull
- private static Root mockRoot(@NotNull PermissionProvider pp, boolean permissionAware) {
+ static Root mockRoot(@NotNull PermissionProvider pp, boolean permissionAware) {
MockSettings s = withSettings();
if (permissionAware) {
s.extraInterfaces(PermissionAware.class);
@@ -101,45 +108,4 @@ public class SessionDelegateTest {
when(root.getContentSession()).thenReturn(cs);
return cs;
}
-
- @Test
- public void testRefreshAware() {
- PermissionProvider pp = mock(PermissionProvider.class);
- Root r = mockRoot(pp, true);
- SessionDelegate delegate = mockSessionDelegate(r, pp);
-
- PermissionAware pa = (PermissionAware) r;
- verify(pa, never()).getPermissionProvider();
-
- // calling refresh without permissionprovider field being assigned
- delegate.refresh(true);
- delegate.refresh(false);
- verify(pp, times(2)).refresh();
-
- // calling refresh with permissionprovider field being assigned
- delegate.getPermissionProvider();
- delegate.refresh(true);
- delegate.refresh(false);
- verify(pp, times(4)).refresh();
-
- verify(pa, times(1)).getPermissionProvider();
- }
-
- @Test
- public void testRefreshUnaware() {
- PermissionProvider pp = mock(PermissionProvider.class);
- Root r = mockRoot(pp, false);
- SessionDelegate delegate = mockSessionDelegate(r, pp);
-
- // calling refresh without permissionprovider field being assigned
- delegate.refresh(true);
- delegate.refresh(false);
- verify(pp, times(2)).refresh();
-
- // calling refresh with permissionprovider field being assigned
- delegate.getPermissionProvider();
- delegate.refresh(true);
- delegate.refresh(false);
- verify(pp, times(6)).refresh();
- }
}
\ No newline at end of file
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegatorTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegatorTest.java
new file mode 100644
index 0000000..4bdb4f5
--- /dev/null
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/AuthorizableDelegatorTest.java
@@ -0,0 +1,232 @@
+/*
+ * 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.jcr.delegate;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import javax.jcr.Value;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+public class AuthorizableDelegatorTest extends AbstractDelegatorTest {
+
+ private final SessionDelegate sessionDelegate = mockSessionDelegate();
+ private final Authorizable authorizable = mock(Authorizable.class);
+ private final Authorizable user = when(mock(Authorizable.class, withSettings().extraInterfaces(User.class)).isGroup()).thenReturn(false).getMock();
+ private final Authorizable group = when(mock(Authorizable.class, withSettings().extraInterfaces(Group.class)).isGroup()).thenReturn(true).getMock();
+ private final AuthorizableDelegator ad = mockDelegator(sessionDelegate, authorizable);
+
+ private static AuthorizableDelegator mockDelegator(@NotNull SessionDelegate sd, @NotNull Authorizable a) {
+ return mock(AuthorizableDelegator.class, withSettings().useConstructor(sd, a).defaultAnswer(CALLS_REAL_METHODS));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCreateFromDelegator() {
+ new AuthorizableDelegator(sessionDelegate, ad) {};
+ }
+
+ @Test
+ public void testWrap() {
+ assertNull(AuthorizableDelegator.wrap(sessionDelegate, null));
+
+ Authorizable a = AuthorizableDelegator.wrap(sessionDelegate, group);
+ assertTrue(a instanceof GroupDelegator);
+
+ a = AuthorizableDelegator.wrap(sessionDelegate, user);
+ assertTrue(a instanceof UserDelegator);
+
+ verify(user).isGroup();
+ verify(group).isGroup();
+ verifyNoMoreInteractions(user, group);
+ verifyNoInteractions(sessionDelegate);
+ }
+
+ @Test
+ public void testUnwrap() {
+ Authorizable a = AuthorizableDelegator.unwrap(group);
+ assertSame(group, a);
+
+ a = AuthorizableDelegator.unwrap(user);
+ assertSame(user, a);
+
+ verify(user).isGroup();
+ verify(group).isGroup();
+ verifyNoMoreInteractions(user, group, sessionDelegate);
+ }
+
+ @Test
+ public void testUnwrapDelegator() throws Exception {
+ Authorizable gDelegator = AuthorizableDelegator.wrap(sessionDelegate, group);
+ Authorizable a = AuthorizableDelegator.unwrap(gDelegator);
+ assertSame(group, a);
+
+ Authorizable uDelegator = AuthorizableDelegator.wrap(sessionDelegate, user);
+ a = AuthorizableDelegator.unwrap(uDelegator);
+ assertSame(user, a);
+
+ verify(user, times(2)).isGroup();
+ verify(group, times(2)).isGroup();
+ verify(sessionDelegate, times(2)).safePerform(any(SessionOperation.class));
+ verify(sessionDelegate, times(2)).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(user, group, sessionDelegate);
+ }
+
+ @Test
+ public void testIsGroup() throws Exception {
+ ad.isGroup();
+
+ verify(authorizable).isGroup();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verify(sessionDelegate).safePerform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testGetId() throws Exception {
+ ad.getID();
+
+ verify(authorizable).getID();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testGetPrincipal() throws Exception {
+ ad.getPrincipal();
+
+ verify(authorizable).getPrincipal();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testMemberOf() throws Exception {
+ doReturn(Collections.emptyIterator()).when(authorizable).memberOf();
+ ad.memberOf();
+
+ verify(authorizable).memberOf();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testDeclaredMemberOf() throws Exception {
+ doReturn(Collections.emptyIterator()).when(authorizable).declaredMemberOf();
+ ad.declaredMemberOf();
+
+ verify(authorizable).declaredMemberOf();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testRemove() throws Exception {
+ ad.remove();
+
+ verify(authorizable).remove();
+ verify(sessionDelegate).performVoid(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testGetPropertyNames() throws Exception {
+ ad.getPropertyNames();
+ ad.getPropertyNames("rel/path");
+
+ verify(authorizable).getPropertyNames();
+ verify(authorizable).getPropertyNames("rel/path");
+ verify(sessionDelegate, times(2)).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testHasProperty() throws Exception {
+ ad.hasProperty("rel/path");
+ verify(authorizable).hasProperty("rel/path");
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testGetProperty() throws Exception {
+ ad.getProperty("rel/path");
+ verify(authorizable).getProperty("rel/path");
+ verify(sessionDelegate).performNullable(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testSetProperty() throws Exception {
+ Value v = mock(Value.class);
+ ad.setProperty("rel/path", v);
+ ad.setProperty("rel/path", new Value[] {v});
+ verify(authorizable).setProperty("rel/path", v);
+ verify(authorizable).setProperty("rel/path", new Value[] {v});
+ verify(sessionDelegate, times(2)).performVoid(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testRemoveProperty() throws Exception {
+ ad.removeProperty("rel/path");
+ verify(authorizable).removeProperty("rel/path");
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testGetPath() throws Exception {
+ ad.getPath();
+
+ verify(authorizable).getPath();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(authorizable, sessionDelegate);
+ }
+
+ @Test
+ public void testEquals() {
+ AuthorizableDelegator delegator = (AuthorizableDelegator) AuthorizableDelegator.wrap(sessionDelegate, user);
+ assertTrue(delegator.equals(delegator));
+ assertNotEquals(delegator, user);
+
+ AuthorizableDelegator uDelegator = (AuthorizableDelegator) AuthorizableDelegator.wrap(sessionDelegate, user);
+ assertEquals(delegator, uDelegator);
+
+ AuthorizableDelegator gDelegator = (AuthorizableDelegator) AuthorizableDelegator.wrap(sessionDelegate, group);
+ assertNotEquals(delegator, gDelegator);
+ }
+}
\ No newline at end of file
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegatorTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegatorTest.java
new file mode 100644
index 0000000..ded4042
--- /dev/null
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/ImpersonationDelegatorTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.jcr.delegate;
+
+import org.apache.jackrabbit.api.security.user.Impersonation;
+import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import java.security.Principal;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class ImpersonationDelegatorTest extends AbstractDelegatorTest {
+
+ private final SessionDelegate sessionDelegate = mockSessionDelegate();
+ private final Impersonation impersonation = mock(Impersonation.class);
+ private final ImpersonationDelegator delegator = mockDelegator(sessionDelegate, impersonation);
+
+ private static ImpersonationDelegator mockDelegator(@NotNull SessionDelegate sd, @NotNull Impersonation impersonation) {
+ Impersonation i = ImpersonationDelegator.wrap(sd, impersonation);
+ assertTrue(i instanceof ImpersonationDelegator);
+ return spy((ImpersonationDelegator) i);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testWrapDelegator() {
+ ImpersonationDelegator.wrap(sessionDelegate, delegator);
+ }
+
+ @Test
+ public void testGetImpersonators() throws Exception {
+ delegator.getImpersonators();
+
+ verify(impersonation).getImpersonators();
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(impersonation, sessionDelegate);
+ }
+
+ @Test
+ public void testGrantImpersonation() throws Exception {
+ Principal principal = mock(Principal.class);
+ delegator.grantImpersonation(principal);
+
+ verify(impersonation).grantImpersonation(principal);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(impersonation, sessionDelegate);
+ }
+
+ @Test
+ public void testRevokeImpersonation() throws Exception {
+ Principal principal = mock(Principal.class);
+ delegator.revokeImpersonation(principal);
+
+ verify(impersonation).revokeImpersonation(principal);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(impersonation, sessionDelegate);
+ }
+
+ @Test
+ public void testAllows() throws Exception {
+ Subject subject = new Subject();
+ delegator.allows(subject);
+
+ verify(impersonation).allows(subject);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(impersonation, sessionDelegate);
+ }
+}
\ No newline at end of file
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegatorTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegatorTest.java
new file mode 100644
index 0000000..5ee5367
--- /dev/null
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/JackrabbitAccessControlManagerDelegatorTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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.jcr.delegate;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
+import org.junit.Test;
+
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+import java.security.Principal;
+import java.util.Collections;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class JackrabbitAccessControlManagerDelegatorTest extends AbstractDelegatorTest {
+
+ private final SessionDelegate sessionDelegate = mockSessionDelegate();
+ private final JackrabbitAccessControlManager jrAcMgr = mock(JackrabbitAccessControlManager.class);
+ private final Principal principal = mock(Principal.class);
+ private final String absPath = "/path";
+
+ private final JackrabbitAccessControlManagerDelegator delegator = new JackrabbitAccessControlManagerDelegator(sessionDelegate, jrAcMgr);
+
+ @Test
+ public void testGetApplicablePoliciesByPrincipal() throws Exception {
+ delegator.getApplicablePolicies(principal);
+
+ verify(jrAcMgr).getApplicablePolicies(principal);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetPoliciesByPrincipal() throws Exception {
+ delegator.getPolicies(principal);
+
+ verify(jrAcMgr).getPolicies(principal);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetEffectivePoliciesByPrincipals() throws Exception {
+ delegator.getEffectivePolicies(Collections.singleton(principal));
+
+ verify(jrAcMgr).getEffectivePolicies(Collections.singleton(principal));
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testHasPrivilegesByPrincipals() throws Exception {
+ delegator.hasPrivileges(absPath, Collections.singleton(principal), new Privilege[0]);
+
+ verify(jrAcMgr).hasPrivileges(absPath, Collections.singleton(principal), new Privilege[0]);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetPrivilegesByPrincipals() throws Exception {
+ delegator.getPrivileges(absPath, Collections.singleton(principal));
+
+ verify(jrAcMgr).getPrivileges(absPath, Collections.singleton(principal));
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetPrivilegeCollectionByPrincipals() throws Exception {
+ delegator.getPrivilegeCollection(absPath, Collections.singleton(principal));
+
+ verify(jrAcMgr).getPrivilegeCollection(absPath, Collections.singleton(principal));
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetPrivilegeCollection() throws Exception {
+ delegator.getPrivilegeCollection(absPath);
+
+ verify(jrAcMgr).getPrivilegeCollection(absPath);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetSupportedPrivileges() throws Exception {
+ delegator.getSupportedPrivileges(absPath);
+
+ verify(jrAcMgr).getSupportedPrivileges(absPath);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testPrivilegeFromName() throws Exception {
+ delegator.privilegeFromName("name");
+
+ verify(jrAcMgr).privilegeFromName("name");
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testHasPrivileges() throws Exception {
+ delegator.hasPrivileges(absPath, new Privilege[0]);
+
+ verify(jrAcMgr).hasPrivileges(absPath, new Privilege[0]);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetPrivileges() throws Exception {
+ delegator.getPrivileges(absPath);
+
+ verify(jrAcMgr).getPrivileges(absPath);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+
+ @Test
+ public void testGetApplicablePolicies() throws Exception {
+ delegator.getApplicablePolicies(absPath);
+
+ verify(jrAcMgr).getApplicablePolicies(absPath);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetPolicies() throws Exception {
+ delegator.getPolicies(absPath);
+
+ verify(jrAcMgr).getPolicies(absPath);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testGetEffectivePolicies() throws Exception {
+ delegator.getEffectivePolicies(absPath);
+
+ verify(jrAcMgr).getEffectivePolicies(absPath);
+ verify(sessionDelegate).perform(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testSetPolicy() throws Exception {
+ AccessControlPolicy policy = mock(AccessControlPolicy.class);
+ delegator.setPolicy(absPath, policy);
+
+ verify(jrAcMgr).setPolicy(absPath, policy);
+ verify(sessionDelegate).performVoid(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+
+ @Test
+ public void testRemovePolicy() throws Exception {
+ AccessControlPolicy policy = mock(AccessControlPolicy.class);
+ delegator.removePolicy(absPath, policy);
+
+ verify(jrAcMgr).removePolicy(absPath, policy);
+ verify(sessionDelegate).performVoid(any(SessionOperation.class));
+ verifyNoMoreInteractions(jrAcMgr, sessionDelegate);
+ verifyNoInteractions(principal);
+ }
+}
\ No newline at end of file
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegatorTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegatorTest.java
new file mode 100644
index 0000000..9c3865d
--- /dev/null
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/PrincipalManagerDelegatorTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.jcr.delegate;
+
+import com.google.common.collect.Iterators;
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalQueryManager;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.withSettings;
+
+public class PrincipalManagerDelegatorTest extends AbstractDelegatorTest {
+
+ private final SessionDelegate sessionDelegate = mockSessionDelegate();
+ private final PrincipalManager principalManager = mock(PrincipalManager.class);
+ private final Principal principal = mock(Principal.class);
+
+ private final PrincipalManagerDelegator delegator = new PrincipalManagerDelegator(sessionDelegate, principalManager);
+
+ private static void verifySavePerform(@NotNull SessionDelegate sessionDelegate, int times) throws RepositoryException {
+ verify(sessionDelegate, times(times)).safePerform(any(SessionOperation.class));
+ verify(sessionDelegate, times(times)).perform(any(SessionOperation.class));
+ }
+
+ @Test
+ public void testHasPrincipal() throws Exception {
+ delegator.hasPrincipal("name");
+
+ verify(principalManager).hasPrincipal("name");
+ verifySavePerform(sessionDelegate, 1);
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+
+ @Test
+ public void testGetPrincipal() throws Exception {
+ delegator.getPrincipal("name");
+
+ verify(principalManager).getPrincipal("name");
+ verify(sessionDelegate).safePerformNullable(any(SessionOperation.class));
+ verify(sessionDelegate).performNullable(any(SessionOperation.class));
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+
+ @Test
+ public void testFindPrincipals() throws Exception {
+ PrincipalIterator it = mock(PrincipalIterator.class);
+ doReturn(it).when(principalManager).findPrincipals(anyString(), anyInt());
+
+ String simpleFilter = "simpleFilter";
+ delegator.findPrincipals(simpleFilter);
+ delegator.findPrincipals(simpleFilter, PrincipalManager.SEARCH_TYPE_NOT_GROUP);
+ delegator.findPrincipals(simpleFilter, true, PrincipalManager.SEARCH_TYPE_GROUP, 6, 0);
+
+ verify(principalManager).findPrincipals(simpleFilter);
+ verify(principalManager).findPrincipals(simpleFilter, PrincipalManager.SEARCH_TYPE_NOT_GROUP);
+ verify(principalManager).findPrincipals(simpleFilter, PrincipalManager.SEARCH_TYPE_GROUP);
+ verify(it).skip(6);
+ verifySavePerform(sessionDelegate, 3);
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+
+ @Test
+ public void testFindPrincipalsOnPrincipalQueryManager() throws Exception {
+ PrincipalManager pm = mock(PrincipalManager.class, withSettings().extraInterfaces(PrincipalQueryManager.class));
+ PrincipalManagerDelegator del = new PrincipalManagerDelegator(sessionDelegate, pm);
+ del.findPrincipals("simpleFilter", false, PrincipalManager.SEARCH_TYPE_ALL, 25, 2);
+
+ verify((PrincipalQueryManager) pm).findPrincipals("simpleFilter", false, PrincipalManager.SEARCH_TYPE_ALL, 25, 2);
+
+ verifySavePerform(sessionDelegate, 1);
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+
+ @Test
+ public void testGetPrincipals() throws Exception {
+ delegator.getPrincipals(PrincipalManager.SEARCH_TYPE_ALL);
+
+ verify(principalManager).getPrincipals(PrincipalManager.SEARCH_TYPE_ALL);
+ verifySavePerform(sessionDelegate, 1);
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+
+ @Test
+ public void testGetGroupMembership() throws Exception {
+ delegator.getGroupMembership(principal);
+
+ verify(principalManager).getGroupMembership(principal);
+ verifySavePerform(sessionDelegate, 1);
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+
+ @Test
+ public void testGetEveryone() throws Exception {
+ delegator.getEveryone();
+
+ verify(principalManager).getEveryone();
+ verifySavePerform(sessionDelegate, 1);
+ verifyNoMoreInteractions(principalManager, sessionDelegate);
+ }
+}
\ No newline at end of file
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java
index 9fc7ed8..89c7ca2 100644
--- a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegateTest.java
@@ -16,91 +16,17 @@
*/
package org.apache.jackrabbit.oak.jcr.delegate;
-import org.apache.jackrabbit.oak.Oak;
-import org.apache.jackrabbit.oak.api.AuthInfo;
-import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.Root;
-import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.jcr.session.RefreshStrategy;
-import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
-import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionAware;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
-import org.apache.jackrabbit.oak.spi.whiteboard.DefaultWhiteboard;
-import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
-import org.apache.jackrabbit.oak.stats.Clock;
-import org.apache.jackrabbit.oak.stats.StatisticManager;
-import org.jetbrains.annotations.NotNull;
import org.junit.Test;
-import org.mockito.MockSettings;
-import org.mockito.stubbing.Answer;
-import java.util.Collections;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
-
-public class SessionDelegateTest {
-
- @NotNull
- private static SessionDelegate mockSessionDelegate(@NotNull Root root, @NotNull PermissionProvider pp) {
- ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
- Whiteboard wb = new DefaultWhiteboard();
- StatisticManager statisticManager = new StatisticManager(wb, executorService);
- return new SessionDelegate(mockContentSession(root), mockSecurityProvider(root, pp),
- RefreshStrategy.Composite.create(), new ThreadLocal<>(), statisticManager, new Clock.Virtual());
- }
-
- @NotNull
- private static Root mockRoot(@NotNull PermissionProvider pp, boolean permissionAware) {
- MockSettings s = withSettings();
- if (permissionAware) {
- s.extraInterfaces(PermissionAware.class);
- }
- Root r = mock(Root.class, s);
- Answer answer = invocationOnMock -> {
- pp.refresh();
- return invocationOnMock;
- };
- doAnswer(answer).when(r).refresh();
- doAnswer(answer).when(r).rebase();
-
- Tree t = mock(Tree.class);
- when(t.getChild(anyString())).thenReturn(t);
- when(r.getTree(anyString())).thenReturn(t);
- if (permissionAware) {
- when(((PermissionAware) r).getPermissionProvider()).thenReturn(pp);
- }
- return r;
- }
-
- @NotNull
- private static SecurityProvider mockSecurityProvider(@NotNull Root root, @NotNull PermissionProvider pp) {
- AuthorizationConfiguration authorizationConfiguration = mock(AuthorizationConfiguration.class);
- when(authorizationConfiguration.getPermissionProvider(root, Oak.DEFAULT_WORKSPACE_NAME, Collections.emptySet())).thenReturn(pp);
-
- SecurityProvider securityProvider = mock(SecurityProvider.class);
- when(securityProvider.getConfiguration(AuthorizationConfiguration.class)).thenReturn(authorizationConfiguration);
- return securityProvider;
- }
-
- @NotNull
- private static ContentSession mockContentSession(@NotNull Root root) {
- ContentSession cs = when(mock(ContentSession.class).getAuthInfo()).thenReturn(AuthInfo.EMPTY).getMock();
- when(cs.getWorkspaceName()).thenReturn(Oak.DEFAULT_WORKSPACE_NAME);
- when(cs.getLatestRoot()).thenReturn(root);
- when(root.getContentSession()).thenReturn(cs);
- return cs;
- }
+public class SessionDelegateTest extends AbstractDelegatorTest {
@Test
public void testRefreshAware() {
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegatorTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegatorTest.java
new file mode 100644
index 0000000..b860a79
--- /dev/null
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/delegate/UserManagerDelegatorTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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.jcr.delegate;
+
+import com.google.common.collect.Iterators;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.Query;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.jcr.session.operation.UserManagerOperation;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import java.security.Principal;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+public class UserManagerDelegatorTest extends AbstractDelegatorTest {
+
+ private final SessionDelegate sessionDelegate = mockSessionDelegate();
+ private final UserManager um = mock(UserManager.class);
+ private final Authorizable user = when(mock(Authorizable.class, withSettings().extraInterfaces(User.class)).isGroup()).thenReturn(false).getMock();
+ private final Authorizable group = when(mock(Authorizable.class, withSettings().extraInterfaces(Group.class)).isGroup()).thenReturn(true).getMock();
+
+ private final UserManagerDelegator delegator = new UserManagerDelegator(sessionDelegate, um);
+
+ private static void verifySessionDelegatePerform(@NotNull SessionDelegate sessionDelegate, int times) throws Exception {
+ verify(sessionDelegate, times(times)).checkAlive();
+ verify(sessionDelegate, times(times)).isAlive();
+ verify(sessionDelegate, times(times)).perform(any(UserManagerOperation.class));
+ }
+
+ private static void verifySessionDelegatePerformNullable(@NotNull SessionDelegate sessionDelegate, int times) throws Exception {
+ verify(sessionDelegate, times(times)).checkAlive();
+ verify(sessionDelegate, times(times)).isAlive();
+ verify(sessionDelegate, times(times)).performNullable(any(UserManagerOperation.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCreateFromDelegator() {
+ new UserManagerDelegator(sessionDelegate, delegator);
+ }
+
+ @Test
+ public void testGetAuthorizableById() throws Exception {
+ assertNull(delegator.getAuthorizable("id"));
+
+ doReturn(user).when(um).getAuthorizable("id");
+ Authorizable a = delegator.getAuthorizable("id");
+ assertTrue(a instanceof UserDelegator);
+
+ verify(um, times(2)).getAuthorizable("id");
+ verify(user).isGroup();
+ verifySessionDelegatePerformNullable(sessionDelegate, 2);
+ verifyNoMoreInteractions(um, user, sessionDelegate);
+ verifyNoMoreInteractions(group);
+ }
+
+ @Test
+ public void testGetAuthorizableByPrincipal() throws Exception {
+ Principal principal = mock(Principal.class);
+ assertNull(delegator.getAuthorizable(principal));
+
+ doReturn(group).when(um).getAuthorizable(principal);
+ Authorizable a = delegator.getAuthorizable(principal);
+ assertTrue(a instanceof GroupDelegator);
+
+ verify(um, times(2)).getAuthorizable(principal);
+ verify(group).isGroup();
+ verifySessionDelegatePerformNullable(sessionDelegate, 2);
+ verifyNoMoreInteractions(um, group, sessionDelegate);
+ verifyNoMoreInteractions(user);
+ }
+
+ @Test
+ public void testGetAuthorizableByPath() throws Exception {
+ String path = "/path";
+ assertNull(delegator.getAuthorizableByPath(path));
+
+ doReturn(user).when(um).getAuthorizableByPath(path);
+ Authorizable a = delegator.getAuthorizableByPath(path);
+ assertTrue(a instanceof UserDelegator);
+
+ verify(um, times(2)).getAuthorizableByPath(path);
+ verify(user).isGroup();
+ verifySessionDelegatePerformNullable(sessionDelegate, 2);
+ verifyNoMoreInteractions(um, user, sessionDelegate);
+ verifyNoMoreInteractions(group);
+ }
+
+ @Test
+ public void testFindAuthorizables() throws Exception {
+ Query query = mock(Query.class);
+ doReturn(Iterators.emptyIterator()).when(um).findAuthorizables(query);
+ doReturn(Iterators.emptyIterator()).when(um).findAuthorizables(anyString(), anyString());
+ doReturn(Iterators.emptyIterator()).when(um).findAuthorizables(anyString(), anyString(), anyInt());
+
+ delegator.findAuthorizables(query);
+ delegator.findAuthorizables("rel/path", "value");
+ delegator.findAuthorizables("rel/path", "value", UserManager.SEARCH_TYPE_AUTHORIZABLE);
+
+ verify(um).findAuthorizables(query);
+ verify(um).findAuthorizables("rel/path", "value");
+ verify(um).findAuthorizables("rel/path", "value", UserManager.SEARCH_TYPE_AUTHORIZABLE);
+
+ verifySessionDelegatePerform(sessionDelegate, 3);
+ verifyNoMoreInteractions(um, sessionDelegate);
+ }
+
+ @Test
+ public void testCreateUser() throws Exception {
+ doReturn(user).when(um).createUser(anyString(), anyString());
+ doReturn(user).when(um).createUser(anyString(), anyString(), any(Principal.class), anyString());
+
+ Principal p = mock(Principal.class);
+ User u1 = delegator.createUser("uid", "pw");
+ User u2 = delegator.createUser("uid", "pw", p, "rel/path");
+ assertTrue(u1 instanceof UserDelegator);
+ assertTrue(u2 instanceof UserDelegator);
+
+ verify(um).createUser("uid", "pw");
+ verify(um).createUser("uid", "pw", p, "rel/path");
+
+ verifySessionDelegatePerform(sessionDelegate, 2);
+ verifyNoMoreInteractions(um, sessionDelegate);
+ verifyNoInteractions(user);
+ }
+
+ @Test
+ public void testCreateSystemUser() throws Exception {
+ doReturn(user).when(um).createSystemUser(anyString(), anyString());
+
+ User u = delegator.createSystemUser("sys-uid", "rel/path");
+ assertTrue(u instanceof UserDelegator);
+
+ verify(um).createSystemUser("sys-uid", "rel/path");
+ verifySessionDelegatePerform(sessionDelegate, 1);
+ verifyNoMoreInteractions(um, sessionDelegate);
+ verifyNoInteractions(user);
+ }
+
+ @Test
+ public void testCreateGroup() throws Exception {
+ doReturn(group).when(um).createGroup(anyString());
+ doReturn(group).when(um).createGroup(anyString(), any(Principal.class), anyString());
+ doReturn(group).when(um).createGroup(any(Principal.class));
+ doReturn(group).when(um).createGroup(any(Principal.class), anyString());
+
+ Principal p = mock(Principal.class);
+ assertTrue(delegator.createGroup("groupId") instanceof GroupDelegator);
+ assertTrue(delegator.createGroup("groupId", p, "rel/path") instanceof GroupDelegator);
+ assertTrue(delegator.createGroup(p) instanceof GroupDelegator);
+ assertTrue(delegator.createGroup(p, "rel/path") instanceof GroupDelegator);
+
+ verify(um).createGroup("groupId");
+ verify(um).createGroup("groupId", p, "rel/path");
+ verify(um).createGroup(p);
+ verify(um).createGroup(p, "rel/path");
+
+ verifySessionDelegatePerform(sessionDelegate, 4);
+ verifyNoMoreInteractions(um, sessionDelegate);
+ verifyNoInteractions(group);
+ }
+
+
+ @Test
+ public void testIsAutoSave() throws Exception {
+ delegator.isAutoSave();
+
+ verify(um).isAutoSave();
+ verify(sessionDelegate).checkAlive();
+ verify(sessionDelegate).isAlive();
+ verify(sessionDelegate).safePerform(any(UserManagerOperation.class));
+ verify(sessionDelegate).perform(any(UserManagerOperation.class));
+ verifyNoMoreInteractions(um, sessionDelegate);
+ }
+
+ @Test
+ public void testAutoSave() throws Exception {
+ delegator.autoSave(true);
+ delegator.autoSave(false);
+
+ verify(um, times(2)).autoSave(anyBoolean());
+ verify(sessionDelegate, times(2)).checkAlive();
+ verify(sessionDelegate, times(2)).isAlive();
+ verify(sessionDelegate, times(2)).performVoid(any(UserManagerOperation.class));
+ verifyNoMoreInteractions(um, sessionDelegate);
+ }
+}
\ No newline at end of file