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 2020/09/30 15:04:14 UTC
svn commit: r1882156 - in /jackrabbit/oak/trunk/oak-core: ./
src/main/java/org/apache/jackrabbit/oak/security/user/
src/main/java/org/apache/jackrabbit/oak/security/user/autosave/
src/main/java/org/apache/jackrabbit/oak/security/user/query/
Author: angela
Date: Wed Sep 30 15:04:14 2020
New Revision: 1882156
URL: http://svn.apache.org/viewvc?rev=1882156&view=rev
Log:
OAK-9247 : Sonar findings and minor improvements in o.a.j.oak.security.user
Modified:
jackrabbit/oak/trunk/oak-core/pom.xml
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AbstractGroupPrincipal.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizableIterator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/GroupImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/PasswordHistoryException.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserPrincipalProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/autosave/AuthorizableWrapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/QueryUtil.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java
Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Wed Sep 30 15:04:14 2020
@@ -183,6 +183,7 @@
<include>org.apache.jackrabbit.oak.security.authorization.permission</include>
<include>org.apache.jackrabbit.oak.security.authorization.restriction</include>
<include>org.apache.jackrabbit.oak.security.internal</include>
+ <include>org.apache.jackrabbit.oak.security.user</include>
</includes>
<excludes>
<exclude>*Test</exclude>
@@ -198,7 +199,6 @@
<rule>
<element>PACKAGE</element>
<includes>
- <include>org.apache.jackrabbit.oak.security.user</include>
<include>org.apache.jackrabbit.oak.security.authentication.token</include>
</includes>
<excludes>
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AbstractGroupPrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AbstractGroupPrincipal.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AbstractGroupPrincipal.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AbstractGroupPrincipal.java Wed Sep 30 15:04:14 2020
@@ -16,15 +16,8 @@
*/
package org.apache.jackrabbit.oak.security.user;
-import java.security.Principal;
-import java.util.Enumeration;
-import java.util.Iterator;
-import javax.jcr.RepositoryException;
-
-import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterators;
-
import org.apache.jackrabbit.api.security.principal.GroupPrincipal;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
@@ -35,6 +28,11 @@ import org.jetbrains.annotations.NotNull
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Iterator;
+
/**
* Base class for {@code Group} principals.
*/
@@ -95,19 +93,16 @@ abstract class AbstractGroupPrincipal ex
throw new IllegalStateException(msg, e);
}
- Iterator<Principal> principals = Iterators.transform(members, new Function<Authorizable, Principal>() {
- @Override
- public Principal apply(Authorizable authorizable) {
- if (authorizable == null) {
- return null;
- }
- try {
- return authorizable.getPrincipal();
- } catch (RepositoryException e) {
- String msg = "Internal error while retrieving principal: " + e.getMessage();
- log.error(msg);
- throw new IllegalStateException(msg, e);
- }
+ Iterator<Principal> principals = Iterators.transform(members, authorizable -> {
+ if (authorizable == null) {
+ return null;
+ }
+ try {
+ return authorizable.getPrincipal();
+ } catch (RepositoryException e) {
+ String msg = "Internal error while retrieving principal: " + e.getMessage();
+ log.error(msg);
+ throw new IllegalStateException(msg, e);
}
});
return Iterators.asEnumeration(Iterators.filter(principals, Predicates.<Object>notNull()));
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizableIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizableIterator.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizableIterator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizableIterator.java Wed Sep 30 15:04:14 2020
@@ -16,19 +16,20 @@
*/
package org.apache.jackrabbit.oak.security.user;
-import java.util.Iterator;
-import javax.jcr.RangeIterator;
-import javax.jcr.RepositoryException;
-
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.oak.spi.security.user.AuthorizableType;
+import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jcr.RangeIterator;
+import javax.jcr.RepositoryException;
+import java.util.Iterator;
+import java.util.function.Predicate;
+
/**
* AuthorizableIterator...
*/
@@ -97,7 +98,7 @@ final class AuthorizableIterator impleme
public Authorizable apply(String oakPath) {
try {
Authorizable a = userManager.getAuthorizableByOakPath(oakPath);
- if (predicate.apply(a)) {
+ if (predicate.test(a)) {
return a;
}
} catch (RepositoryException e) {
@@ -111,12 +112,12 @@ final class AuthorizableIterator impleme
private final AuthorizableType authorizableType;
- AuthorizableTypePredicate(AuthorizableType authorizableType) {
+ AuthorizableTypePredicate(@NotNull AuthorizableType authorizableType) {
this.authorizableType = authorizableType;
}
@Override
- public boolean apply(Authorizable authorizable) {
+ public boolean test(Authorizable authorizable) {
return authorizableType.isType(authorizable);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/GroupImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/GroupImpl.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/GroupImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/GroupImpl.java Wed Sep 30 15:04:14 2020
@@ -261,39 +261,11 @@ class GroupImpl extends AuthorizableImpl
if (Strings.isNullOrEmpty(memberId)) {
throw new ConstraintViolationException("MemberId must not be null or empty.");
}
- if (getID().equals(memberId)) {
- String msg = "Attempt to add or remove a group as member of itself (" + getID() + ").";
- log.debug(msg);
- continue;
+ if (isValidMemberId(memberId, importBehavior)) {
+ // memberId can be processed -> remove from failedIds and generate contentID
+ failedIds.remove(memberId);
+ updateMap.put(mp.getContentID(memberId), memberId);
}
-
- if (ImportBehavior.BESTEFFORT != importBehavior) {
- Authorizable member = getUserManager().getAuthorizable(memberId);
- String msg = null;
- if (member == null) {
- msg = "Attempt to add or remove a non-existing member '" + memberId + "' with ImportBehavior = " + ImportBehavior.nameFromValue(importBehavior);
- } else if (member.isGroup()) {
- if (((AuthorizableImpl) member).isEveryone()) {
- log.debug("Attempt to add everyone group as member.");
- continue;
- } else if (isCyclicMembership((Group) member)) {
- msg = "Cyclic group membership detected for group " + getID() + " and member " + member.getID();
- }
- }
- if (msg != null) {
- if (ImportBehavior.ABORT == importBehavior) {
- throw new ConstraintViolationException(msg);
- } else {
- // ImportBehavior.IGNORE is default in UserUtil.getImportBehavior
- log.debug(msg);
- continue;
- }
- }
- }
-
- // memberId can be processed -> remove from failedIds and generate contentID
- failedIds.remove(memberId);
- updateMap.put(mp.getContentID(memberId), memberId);
}
Set<String> processedIds = Sets.newHashSet(updateMap.values());
@@ -312,6 +284,38 @@ class GroupImpl extends AuthorizableImpl
return failedIds;
}
+ private boolean isValidMemberId(@NotNull String memberId, int importBehavior) throws RepositoryException {
+ if (getID().equals(memberId)) {
+ log.debug("Attempt to add or remove a group as member of itself ({}).", getID());
+ return false;
+ }
+
+ if (ImportBehavior.BESTEFFORT != importBehavior) {
+ Authorizable member = getUserManager().getAuthorizable(memberId);
+ String msg = null;
+ if (member == null) {
+ msg = "Attempt to add or remove a non-existing member '" + memberId + "' with ImportBehavior = " + ImportBehavior.nameFromValue(importBehavior);
+ } else if (member.isGroup()) {
+ if (((AuthorizableImpl) member).isEveryone()) {
+ log.debug("Attempt to add everyone group as member.");
+ return false;
+ } else if (isCyclicMembership((Group) member)) {
+ msg = "Cyclic group membership detected for group " + getID() + " and member " + member.getID();
+ }
+ }
+ if (msg != null) {
+ if (ImportBehavior.ABORT == importBehavior) {
+ throw new ConstraintViolationException(msg);
+ } else {
+ // ImportBehavior.IGNORE is default in UserUtil.getImportBehavior
+ log.debug(msg);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
private boolean isCyclicMembership(@NotNull Group member) throws RepositoryException {
return member.isMember(this);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java Wed Sep 30 15:04:14 2020
@@ -151,51 +151,7 @@ class MembershipProvider extends Authori
final Iterable<String> refPaths = identifierManager.getReferences(
authorizableTree, REP_MEMBERS, NT_REP_MEMBER_REFERENCES, true
);
-
- return new AbstractMemberIterator(refPaths.iterator()) {
- @Override
- protected String internalGetNext(@NotNull String propPath) {
- String next = null;
-
- String groupPath = getGroupPath(propPath);
- if (groupPath != null) {
- if (processedPaths.add(groupPath)) {
- // we didn't see this path before, so continue
- next = groupPath;
- if (includeInherited) {
- // inject a parent iterator if inherited memberships is requested
- Tree group = getByPath(groupPath, AuthorizableType.GROUP);
- if (group != null) {
- remember(group);
- }
- }
- }
- } else {
- log.debug("Not a membership reference property {}", propPath);
- }
- return next;
- }
-
- @NotNull
- @Override
- protected Iterator<String> getNextIterator(@NotNull Tree groupTree) {
- return getMembership(groupTree, true, processedPaths);
- }
-
- @Nullable
- private String getGroupPath(@NotNull String membersPropPath) {
- int index = membersPropPath.indexOf('/' + REP_MEMBERS_LIST);
- if (index < 0) {
- index = membersPropPath.indexOf('/' + REP_MEMBERS);
- }
-
- if (index > 0) {
- return membersPropPath.substring(0, index);
- } else {
- return null;
- }
- }
- };
+ return new MembershipIterator(refPaths.iterator(), includeInherited, processedPaths);
}
/**
@@ -506,4 +462,59 @@ class MembershipProvider extends Authori
@NotNull
protected abstract Iterator<String> getNextIterator(@NotNull Tree groupTree);
}
+
+ private final class MembershipIterator extends AbstractMemberIterator {
+
+ private final boolean includeInherited;
+ private final Set<String> processedPaths;
+
+ private MembershipIterator(@NotNull Iterator<String> references, boolean includeInherited, @NotNull Set<String> processedPaths) {
+ super(references);
+ this.includeInherited = includeInherited;
+ this.processedPaths = processedPaths;
+ }
+
+ @Override
+ protected String internalGetNext(@NotNull String propPath) {
+ String next = null;
+
+ String groupPath = getGroupPath(propPath);
+ if (groupPath != null) {
+ if (processedPaths.add(groupPath)) {
+ // we didn't see this path before, so continue
+ next = groupPath;
+ if (includeInherited) {
+ // inject a parent iterator if inherited memberships is requested
+ Tree group = getByPath(groupPath, AuthorizableType.GROUP);
+ if (group != null) {
+ remember(group);
+ }
+ }
+ }
+ } else {
+ log.debug("Not a membership reference property {}", propPath);
+ }
+ return next;
+ }
+
+ @NotNull
+ @Override
+ protected Iterator<String> getNextIterator(@NotNull Tree groupTree) {
+ return getMembership(groupTree, true, processedPaths);
+ }
+
+ @Nullable
+ private String getGroupPath(@NotNull String membersPropPath) {
+ int index = membersPropPath.indexOf('/' + REP_MEMBERS_LIST);
+ if (index < 0) {
+ index = membersPropPath.indexOf('/' + REP_MEMBERS);
+ }
+
+ if (index > 0) {
+ return membersPropPath.substring(0, index);
+ } else {
+ return null;
+ }
+ }
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/PasswordHistoryException.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/PasswordHistoryException.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/PasswordHistoryException.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/PasswordHistoryException.java Wed Sep 30 15:04:14 2020
@@ -16,11 +16,13 @@
*/
package org.apache.jackrabbit.oak.security.user;
+import org.jetbrains.annotations.NotNull;
+
import javax.jcr.nodetype.ConstraintViolationException;
class PasswordHistoryException extends ConstraintViolationException {
- PasswordHistoryException(String message) {
+ PasswordHistoryException(@NotNull String message) {
super(message);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java Wed Sep 30 15:04:14 2020
@@ -77,8 +77,8 @@ final class UserContext implements Conte
// group node (missing node type information on non-existing location)
return USER_PROPERTY_NAMES.contains(name)
|| GROUP_PROPERTY_NAMES.contains(name)
- || path.contains(REP_MEMBERS)
|| path.contains(REP_MEMBERS_LIST)
+ || path.contains(REP_MEMBERS)
|| path.contains(REP_PWD);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImporter.java Wed Sep 30 15:04:14 2020
@@ -234,78 +234,15 @@ class UserImporter implements ProtectedP
String propName = propInfo.getName();
if (REP_AUTHORIZABLE_ID.equals(propName)) {
- if (!isValid(def, NT_REP_AUTHORIZABLE, false)) {
- return false;
- }
- String id = propInfo.getTextValue().getString();
- Authorizable existing = userManager.getAuthorizable(id);
- if (existing == null) {
- String msg = "Cannot handle protected PropInfo " + propInfo + ". Invalid rep:authorizableId.";
- log.warn(msg);
- throw new ConstraintViolationException(msg);
- }
-
- if (a.getPath().equals(existing.getPath())) {
- parent.setProperty(REP_AUTHORIZABLE_ID, id);
- } else {
- throw new AuthorizableExistsException(id);
- }
- return true;
-
+ return importAuthorizableId(parent, a, propInfo, def);
} else if (REP_PRINCIPAL_NAME.equals(propName)) {
- if (!isValid(def, NT_REP_AUTHORIZABLE, false)) {
- return false;
- }
-
- String principalName = propInfo.getTextValue().getString();
- Principal principal = new PrincipalImpl(principalName);
- userManager.checkValidPrincipal(principal, a.isGroup());
- userManager.setPrincipal(parent, principal);
-
- /*
- Remember principal of new user/group for further processing
- of impersonators
- */
- principals.put(principalName, a.getPrincipal());
-
- return true;
+ return importPrincipalName(parent, a, propInfo, def);
} else if (REP_PASSWORD.equals(propName)) {
- if (a.isGroup() || !isValid(def, NT_REP_USER, false)) {
- log.warn("Unexpected authorizable or definition for property rep:password");
- return false;
- }
- if (((User) a).isSystemUser()) {
- log.warn("System users may not have a password set.");
- return false;
- }
-
- String pw = propInfo.getTextValue().getString();
- userManager.setPassword(parent, a.getID(), pw, true);
- currentPw = pw;
-
- return true;
-
+ return importPassword(parent, a, propInfo, def);
} else if (REP_IMPERSONATORS.equals(propName)) {
- if (a.isGroup() || !isValid(def, MIX_REP_IMPERSONATABLE, true)) {
- log.warn("Unexpected authorizable or definition for property rep:impersonators");
- return false;
- }
-
- // since impersonators may be imported later on, postpone processing
- // to the end.
- // see -> process References
- referenceTracker.processedReference(new Impersonators(parent.getPath(), propInfo.getTextValues()));
- return true;
-
+ return importImpersonators(parent, a, propInfo, def);
} else if (REP_DISABLED.equals(propName)) {
- if (a.isGroup() || !isValid(def, NT_REP_USER, false)) {
- log.warn("Unexpected authorizable or definition for property rep:disabled");
- return false;
- }
-
- ((User) a).disable(propInfo.getTextValue().getString());
- return true;
-
+ return importDisabled(a, propInfo, def);
} else if (REP_MEMBERS.equals(propName)) {
if (!a.isGroup() || !isValid(def, NT_REP_MEMBER_REFERENCES, true)) {
return false;
@@ -389,7 +326,7 @@ class UserImporter implements ProtectedP
Authorizable auth = null;
if (isMemberNode(protectedParent)) {
Tree groupTree = protectedParent;
- while (isMemberNode(groupTree) && !groupTree.isRoot()) {
+ while (isMemberNode(groupTree)) {
groupTree = groupTree.getParent();
}
auth = userManager.getAuthorizable(groupTree);
@@ -458,9 +395,88 @@ class UserImporter implements ProtectedP
definition.getDeclaringNodeType().isNodeType(namePathMapper.getJcrName(oakNodeTypeName));
}
+ private boolean importAuthorizableId(@NotNull Tree parent, @NotNull Authorizable a, @NotNull PropInfo propInfo, @NotNull PropertyDefinition def) throws RepositoryException {
+ if (!isValid(def, NT_REP_AUTHORIZABLE, false)) {
+ return false;
+ }
+ String id = propInfo.getTextValue().getString();
+ Authorizable existing = userManager.getAuthorizable(id);
+ if (existing == null) {
+ String msg = "Cannot handle protected PropInfo " + propInfo + ". Invalid rep:authorizableId.";
+ log.warn(msg);
+ throw new ConstraintViolationException(msg);
+ }
+
+ if (a.getPath().equals(existing.getPath())) {
+ parent.setProperty(REP_AUTHORIZABLE_ID, id);
+ } else {
+ throw new AuthorizableExistsException(id);
+ }
+ return true;
+
+ }
+
+ private boolean importPrincipalName(@NotNull Tree parent, @NotNull Authorizable a, @NotNull PropInfo propInfo, @NotNull PropertyDefinition def) throws RepositoryException {
+ if (!isValid(def, NT_REP_AUTHORIZABLE, false)) {
+ return false;
+ }
+
+ String principalName = propInfo.getTextValue().getString();
+ Principal principal = new PrincipalImpl(principalName);
+ userManager.checkValidPrincipal(principal, a.isGroup());
+ userManager.setPrincipal(parent, principal);
+
+ /*
+ Remember principal of new user/group for further processing
+ of impersonators
+ */
+ principals.put(principalName, a.getPrincipal());
+ return true;
+ }
+
+ private boolean importPassword(@NotNull Tree parent, @NotNull Authorizable a, @NotNull PropInfo propInfo, @NotNull PropertyDefinition def) throws RepositoryException {
+ if (a.isGroup() || !isValid(def, NT_REP_USER, false)) {
+ log.warn("Unexpected authorizable or definition for property rep:password");
+ return false;
+ }
+ if (((User) a).isSystemUser()) {
+ log.warn("System users may not have a password set.");
+ return false;
+ }
+
+ String pw = propInfo.getTextValue().getString();
+ userManager.setPassword(parent, a.getID(), pw, true);
+ currentPw = pw;
+
+ return true;
+ }
+
+ private boolean importImpersonators(@NotNull Tree parent, @NotNull Authorizable a, @NotNull PropInfo propInfo, @NotNull PropertyDefinition def) {
+ if (a.isGroup() || !isValid(def, MIX_REP_IMPERSONATABLE, true)) {
+ log.warn("Unexpected authorizable or definition for property rep:impersonators");
+ return false;
+ }
+
+ // since impersonators may be imported later on, postpone processing
+ // to the end.
+ // see -> process References
+ referenceTracker.processedReference(new Impersonators(parent.getPath(), propInfo.getTextValues()));
+ return true;
+ }
+
+ private boolean importDisabled(@NotNull Authorizable a, @NotNull PropInfo propInfo, @NotNull PropertyDefinition def) throws RepositoryException {
+ if (a.isGroup() || !isValid(def, NT_REP_USER, false)) {
+ log.warn("Unexpected authorizable or definition for property rep:disabled");
+ return false;
+ }
+
+ ((User) a).disable(propInfo.getTextValue().getString());
+ return true;
+ }
+
private static boolean isMemberNode(@NotNull Tree tree) {
//noinspection deprecation
- return tree.exists() && NT_REP_MEMBERS.equals(TreeUtil.getPrimaryTypeName(tree));
+ return tree.exists() && !tree.isRoot() && NT_REP_MEMBERS.equals(TreeUtil.getPrimaryTypeName(tree));
}
private static boolean isMemberReferencesListNode(@NotNull Tree tree) {
@@ -512,15 +528,13 @@ class UserImporter implements ProtectedP
*/
private void handleFailure(String msg) throws ConstraintViolationException {
switch (importBehavior) {
+ case ImportBehavior.ABORT:
+ throw new ConstraintViolationException(msg);
case ImportBehavior.IGNORE:
case ImportBehavior.BESTEFFORT:
+ default:
log.warn(msg);
break;
- case ImportBehavior.ABORT:
- throw new ConstraintViolationException(msg);
- default:
- // no other behavior. nothing to do.
-
}
}
@@ -566,37 +580,8 @@ class UserImporter implements ProtectedP
Authorizable dm = declMembers.next();
toRemove.put(dm.getID(), dm);
}
-
- Map<String, Authorizable> toAdd = Maps.newHashMapWithExpectedSize(members.size());
Map<String, String> nonExisting = Maps.newHashMap();
-
- for (String contentId : members) {
- String remapped = referenceTracker.get(contentId);
- String memberContentId = (remapped == null) ? contentId : remapped;
-
- Authorizable member = null;
- try {
- Tree n = getIdentifierManager().getTree(memberContentId);
- member = userManager.getAuthorizable(n);
- } catch (RepositoryException e) {
- // no such node or failed to retrieve authorizable
- // warning is logged below.
- }
- if (member != null) {
- if (toRemove.remove(member.getID()) == null) {
- toAdd.put(member.getID(), member);
- } // else: no need to remove from rep:members
- } else {
- handleFailure("New member of " + gr + ": No such authorizable (NodeID = " + memberContentId + ')');
- if (importBehavior == ImportBehavior.BESTEFFORT) {
- log.debug("ImportBehavior.BESTEFFORT: Remember non-existing member for processing.");
- /* since we ignore the set of failed ids later on and
- don't know the real memberId => use fake memberId as
- value in the map */
- nonExisting.put(contentId, "-");
- }
- }
- }
+ Map<String, Authorizable> toAdd = getAuthorizablesToAdd(gr, toRemove, nonExisting);
// 2. adjust members of the group
if (!toRemove.isEmpty()) {
@@ -629,6 +614,39 @@ class UserImporter implements ProtectedP
}
@NotNull
+ Map<String, Authorizable> getAuthorizablesToAdd(@NotNull Group gr, @NotNull Map<String, Authorizable> toRemove,
+ @NotNull Map<String, String> nonExisting) throws RepositoryException {
+ Map<String, Authorizable> toAdd = Maps.newHashMapWithExpectedSize(members.size());
+ for (String contentId : members) {
+ // NOTE: no need to check for re-mapped uuids with the referenceTracker because
+ // ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW is not supported for user/group imports (see line 189)
+ Authorizable member = null;
+ try {
+ Tree n = getIdentifierManager().getTree(contentId);
+ member = userManager.getAuthorizable(n);
+ } catch (RepositoryException e) {
+ // no such node or failed to retrieve authorizable
+ // warning is logged below.
+ }
+ if (member != null) {
+ if (toRemove.remove(member.getID()) == null) {
+ toAdd.put(member.getID(), member);
+ } // else: no need to remove from rep:members
+ } else {
+ handleFailure("New member of " + gr + ": No such authorizable (NodeID = " + contentId + ')');
+ if (importBehavior == ImportBehavior.BESTEFFORT) {
+ log.debug("ImportBehavior.BESTEFFORT: Remember non-existing member for processing.");
+ /* since we ignore the set of failed ids later on and
+ don't know the real memberId => use fake memberId as
+ value in the map */
+ nonExisting.put(contentId, "-");
+ }
+ }
+ }
+ return toAdd;
+ }
+
+ @NotNull
private IdentifierManager getIdentifierManager() {
if (identifierManager == null) {
identifierManager = new IdentifierManager(root);
@@ -680,6 +698,25 @@ class UserImporter implements ProtectedP
}
// 2. adjust set of impersonators
+ List<String> nonExisting = updateImpersonators(a, imp, toRemove, toAdd);
+ if (!nonExisting.isEmpty()) {
+ Tree userTree = checkNotNull(root.getTree(a.getPath()));
+ // copy over all existing impersonators to the nonExisting list
+ PropertyState impersonators = userTree.getProperty(REP_IMPERSONATORS);
+ if (impersonators != null) {
+ for (String existing : impersonators.getValue(STRINGS)) {
+ nonExisting.add(existing);
+ }
+ }
+ // and write back the complete list including those principal
+ // names that are unknown to principal provider.
+ userTree.setProperty(REP_IMPERSONATORS, nonExisting, Type.STRINGS);
+ }
+ }
+
+ @NotNull
+ private List<String> updateImpersonators(@NotNull Authorizable a, @NotNull Impersonation imp,
+ @NotNull Map<String, Principal> toRemove, @NotNull List<String> toAdd) throws RepositoryException {
for (Principal p : toRemove.values()) {
if (!imp.revokeImpersonation(p)) {
String principalName = p.getName();
@@ -700,20 +737,7 @@ class UserImporter implements ProtectedP
}
}
}
-
- if (!nonExisting.isEmpty()) {
- Tree userTree = checkNotNull(root.getTree(a.getPath()));
- // copy over all existing impersonators to the nonExisting list
- PropertyState impersonators = userTree.getProperty(REP_IMPERSONATORS);
- if (impersonators != null) {
- for (String existing : impersonators.getValue(STRINGS)) {
- nonExisting.add(existing);
- }
- }
- // and write back the complete list including those principal
- // names that are unknown to principal provider.
- userTree.setProperty(REP_IMPERSONATORS, nonExisting, Type.STRINGS);
- }
+ return nonExisting;
}
@NotNull
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserPrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserPrincipalProvider.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserPrincipalProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserPrincipalProvider.java Wed Sep 30 15:04:14 2020
@@ -20,6 +20,7 @@ import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal;
@@ -228,7 +229,7 @@ class UserPrincipalProvider implements P
if (AuthorizableType.GROUP == type) {
return createGroupPrincipal(authorizableTree);
} else if (AuthorizableType.USER == type) {
- return createUserPrincipal(UserUtil.getAuthorizableId(authorizableTree, type), authorizableTree);
+ return createUserPrincipal(UserUtil.getAuthorizableId(authorizableTree, AuthorizableType.USER), authorizableTree);
}
}
return null;
@@ -272,15 +273,15 @@ class UserPrincipalProvider implements P
@NotNull
private Set<Principal> getGroupMembership(@NotNull Tree authorizableTree) {
- Set<Principal> groupPrincipals = null;
+ Set<Principal> groupPrincipals = new HashSet<>();
boolean doCache = cacheEnabled && UserUtil.isType(authorizableTree, AuthorizableType.USER);
+ boolean doLoad = true;
if (doCache) {
- groupPrincipals = readGroupsFromCache(authorizableTree);
+ doLoad = readGroupsFromCache(authorizableTree, groupPrincipals);
}
// caching not configured or cache expired: use the membershipProvider to calculate
- if (groupPrincipals == null) {
- groupPrincipals = new HashSet<>();
+ if (doLoad) {
Iterator<String> groupPaths = membershipProvider.getMembership(authorizableTree, true);
while (groupPaths.hasNext()) {
Tree groupTree = userProvider.getAuthorizableByPath(groupPaths.next());
@@ -319,12 +320,7 @@ class UserPrincipalProvider implements P
}
cache.setProperty(CacheConstants.REP_EXPIRATION, LongUtils.calculateExpirationTime(expiration));
- String value = (groupPrincipals.isEmpty()) ? "" : Joiner.on(",").join(Iterables.transform(groupPrincipals, new Function<Principal, String>() {
- @Override
- public String apply(Principal input) {
- return Text.escape(input.getName());
- }
- }));
+ String value = (groupPrincipals.isEmpty()) ? "" : Joiner.on(",").join(Iterables.transform(groupPrincipals, input -> Text.escape(input.getName())));
cache.setProperty(CacheConstants.REP_GROUP_PRINCIPAL_NAMES, value);
root.commit(CacheValidatorProvider.asCommitAttributes());
@@ -337,31 +333,29 @@ class UserPrincipalProvider implements P
}
}
- @Nullable
- private Set<Principal> readGroupsFromCache(@NotNull Tree authorizableNode) {
+ private boolean readGroupsFromCache(@NotNull Tree authorizableNode, @NotNull Set<Principal> groups) {
Tree principalCache = authorizableNode.getChild(CacheConstants.REP_CACHE);
if (!principalCache.exists()) {
log.debug("No group cache at {}", authorizableNode.getPath());
- return null;
+ return true;
}
if (isValidCache(principalCache)) {
log.debug("Reading group membership at {}", authorizableNode.getPath());
String str = TreeUtil.getString(principalCache, CacheConstants.REP_GROUP_PRINCIPAL_NAMES);
- if (str == null || str.isEmpty()) {
- return new HashSet<>(1);
+ if (Strings.isNullOrEmpty(str)) {
+ return false;
}
- Set<Principal> groups = new HashSet<>();
for (String s : Text.explode(str, ',')) {
final String name = Text.unescape(s);
groups.add(new CachedGroupPrincipal(name, namePathMapper, root, config));
}
- return groups;
+ return false;
} else {
log.debug("Expired group cache for {}", authorizableNode.getPath());
- return null;
+ return true;
}
}
@@ -466,7 +460,7 @@ class UserPrincipalProvider implements P
@Override
Iterator<Authorizable> getMembers() throws RepositoryException {
org.apache.jackrabbit.api.security.user.Group g = getGroup();
- return (g == null) ? Collections.<Authorizable>emptyIterator() : g.getMembers();
+ return (g == null) ? Collections.emptyIterator() : g.getMembers();
}
@Nullable
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java Wed Sep 30 15:04:14 2020
@@ -290,8 +290,8 @@ class UserProvider extends AuthorizableB
* @throws RepositoryException If an error occurs
*/
private Tree createFolderNodes(@NotNull String nodeName,
- boolean isGroup,
- @Nullable String intermediatePath) throws RepositoryException {
+ boolean isGroup,
+ @Nullable String intermediatePath) throws RepositoryException {
String authRoot = (isGroup) ? groupPath : userPath;
String folderPath = new StringBuilder()
.append(authRoot)
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/autosave/AuthorizableWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/autosave/AuthorizableWrapper.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/autosave/AuthorizableWrapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/autosave/AuthorizableWrapper.java Wed Sep 30 15:04:14 2020
@@ -41,10 +41,10 @@ final class AuthorizableWrapper<T extend
}
static Iterator<Authorizable> createIterator(Iterator<Authorizable> dlgs, AutoSaveEnabledManager mgr) {
- return Iterators.transform(dlgs, new AuthorizableWrapper<Authorizable>(mgr));
+ return Iterators.transform(dlgs, new AuthorizableWrapper<>(mgr));
}
static Iterator<Group> createGroupIterator(Iterator<Group> dlgs, AutoSaveEnabledManager mgr) {
- return Iterators.transform(dlgs, new AuthorizableWrapper<Group>(mgr));
+ return Iterators.transform(dlgs, new AuthorizableWrapper<>(mgr));
}
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/QueryUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/QueryUtil.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/QueryUtil.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/QueryUtil.java Wed Sep 30 15:04:14 2020
@@ -32,6 +32,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.user.util.UserUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.jackrabbit.api.security.user.QueryBuilder.Direction.ASCENDING;
@@ -41,7 +42,7 @@ import static org.apache.jackrabbit.api.
*/
public final class QueryUtil {
- private static final org.slf4j.Logger log = LoggerFactory.getLogger(GroupPredicate.class);
+ private static final Logger log = LoggerFactory.getLogger(QueryUtil.class);
private QueryUtil() {}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java?rev=1882156&r1=1882155&r2=1882156&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java Wed Sep 30 15:04:14 2020
@@ -204,7 +204,7 @@ public class UserQueryManager {
stmt.append(ISO9075.encode(propName));
if (exact) {
stmt.append("='");
- stmt.append(value.replaceAll("'", "''"));
+ stmt.append(value.replace("'", "''"));
stmt.append('\'');
} else {
stmt.append(",'%");
@@ -276,8 +276,7 @@ public class UserQueryManager {
Iterator<Authorizable> authorizables = Iterators.transform(resultRows.iterator(), new ResultRowToAuthorizable(userManager, root, type));
return Iterators.filter(authorizables, new UniqueResultPredicate());
} catch (ParseException e) {
- log.warn("Invalid user query: " + statement, e);
- throw new RepositoryException(e);
+ throw new RepositoryException("Invalid user query "+statement, e);
}
}