import javax.jcr.NamespaceException;
import javax.jcr.Node;
+import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
import org.argeo.cms.ui.jcr.model.WorkspaceElem;
import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.naming.LdapAttrs;
-import org.argeo.node.NodeTypes;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.swt.graphics.Image;
else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_RESOURCE))
return JcrImages.BINARY;
try {
- // optimizes
- if (node.hasProperty(LdapAttrs.uid.property()) && node.isNodeType(NodeTypes.NODE_USER_HOME))
+ // TODO check workspace type?
+ if (node.getDepth() == 1 && node.hasProperty(Property.JCR_ID))
return JcrImages.HOME;
+
+ // optimizes
+// if (node.hasProperty(LdapAttrs.uid.property()) && node.isNodeType(NodeTypes.NODE_USER_HOME))
+// return JcrImages.HOME;
} catch (NamespaceException e) {
// node namespace is not registered in this repo
}
public void testWriteReadCsv() throws Exception {
// session().setNamespacePrefix("argeo", ArgeoNames.ARGEO_NAMESPACE);
- InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/node/node.cnd"));
+ InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/node/ldap.cnd"));
CndImporter.registerNodeTypes(reader, session());
reader.close();
reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/argeo.cnd"));
package org.argeo.cms.auth;
import java.time.ZonedDateTime;
+import java.util.Collection;
import java.util.Locale;
import java.util.UUID;
import javax.naming.ldap.LdapName;
+import javax.security.auth.Subject;
import org.argeo.naming.LdapAttrs;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.useradmin.Authorization;
/** An authenticated user session. */
final static String SESSION_UUID = LdapAttrs.entryUUID.name();
final static String SESSION_LOCAL_ID = LdapAttrs.uniqueIdentifier.name();
- // public String getId();
-
UUID getUuid();
LdapName getUserDn();
boolean isValid();
- // public Session getDataSession(String cn, String workspace, Repository
- // repository);
- //
- // public void releaseDataSession(String cn, Session session);
-
- // public void addHttpSession(HttpServletRequest request);
-
- // public void cleanUp();
+ /** @return The {@link CmsSession} for this {@link Subject} or null. */
+ static CmsSession getCmsSession(BundleContext bc, Subject subject) {
+ if (subject.getPrivateCredentials(CmsSessionId.class).isEmpty())
+ return null;
+ CmsSessionId cmsSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next();
+ String uuid = cmsSessionId.getUuid().toString();
+ Collection<ServiceReference<CmsSession>> sr;
+ try {
+ sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")");
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e);
+ }
+ ServiceReference<CmsSession> cmsSessionRef;
+ if (sr.size() == 1) {
+ cmsSessionRef = sr.iterator().next();
+ return bc.getService(cmsSessionRef);
+ } else if (sr.size() == 0) {
+ return null;
+ } else
+ throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid);
+ }
}
import java.util.UUID;
+import javax.security.auth.Subject;
+
import org.argeo.cms.CmsException;
+/**
+ * The ID of a {@link CmsSession}, which must be available in the private
+ * credentials of an authenticated {@link Subject}.
+ */
public class CmsSessionId {
private final UUID uuid;
return getSubject().getPrivateCredentials(SecretKey.class);
}
+ public Session newDataSession(String cn, String workspace, Repository repository) {
+ return login(repository, workspace);
+ }
+
public synchronized Session getDataSession(String cn, String workspace, Repository repository) {
// FIXME make it more robust
if (workspace == null)
package org.argeo.cms.internal.http;
import java.io.Serializable;
-import java.util.LinkedHashMap;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
private final String alias;
- private LinkedHashMap<Session, CmsSessionImpl> cmsSessions = new LinkedHashMap<>();
+// private LinkedHashMap<Session, CmsSessionImpl> cmsSessions = new LinkedHashMap<>();
public CmsSessionProvider(String alias) {
this.alias = alias;
public Session getSession(HttpServletRequest request, Repository rep, String workspace)
throws javax.jcr.LoginException, ServletException, RepositoryException {
+ // a client is scanning parent URLs.
+ if (workspace == null)
+ return null;
+
CmsSessionImpl cmsSession = WebCmsSessionImpl.getCmsSession(request);
- // if (cmsSession == null)
- // return anonymousSession(request, rep, workspace);
if (log.isTraceEnabled()) {
log.trace("Get JCR session from " + cmsSession);
}
- Session session = cmsSession.getDataSession(alias, workspace, rep);
- cmsSessions.put(session, cmsSession);
+ Session session = cmsSession.newDataSession(alias, workspace, rep);
+// cmsSessions.put(session, cmsSession);
return session;
}
- // private synchronized Session anonymousSession(HttpServletRequest request,
- // Repository repository, String workspace) {
- // // TODO rather log in here as anonymous?
- // LoginContext lc = (LoginContext)
- // request.getAttribute(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
- // if (lc == null)
- // throw new CmsException("No login context available");
- // // optimize
- // Session session;
- // try {
- // session = Subject.doAs(lc.getSubject(), new
- // PrivilegedExceptionAction<Session>() {
- // @Override
- // public Session run() throws Exception {
- // return repository.login(workspace);
- // }
- // });
- // } catch (Exception e) {
- // throw new CmsException("Cannot log in to JCR", e);
- // }
- // return session;
- // }
-
- public synchronized void releaseSession(Session session) {
- if (cmsSessions.containsKey(session)) {
- CmsSessionImpl cmsSession = cmsSessions.get(session);
- cmsSession.releaseDataSession(alias, session);
- } else {
- log.warn("JCR session " + session + " not found in CMS session list. Logging it out...");
- JcrUtils.logoutQuietly(session);
- }
+ public void releaseSession(Session session) {
+ JcrUtils.logoutQuietly(session);
+// if (cmsSessions.containsKey(session)) {
+// CmsSessionImpl cmsSession = cmsSessions.get(session);
+// cmsSession.releaseDataSession(alias, session);
+// } else {
+// log.warn("JCR session " + session + " not found in CMS session list. Logging it out...");
+// JcrUtils.logoutQuietly(session);
+// }
}
}
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
+import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.security.auth.login.LoginContext;
import org.argeo.cms.CmsException;
+import org.argeo.jackrabbit.security.JackrabbitSecurityUtils;
import org.argeo.jcr.JcrRepositoryWrapper;
import org.argeo.jcr.JcrUtils;
import org.argeo.node.NodeConstants;
-import org.argeo.node.NodeNames;
-import org.argeo.node.NodeTypes;
import org.argeo.node.NodeUtils;
/**
class HomeRepository extends JcrRepositoryWrapper implements KernelConstants {
/** The home base path. */
- private String homeBasePath = KernelConstants.DEFAULT_HOME_BASE_PATH;
- private String usersBasePath = KernelConstants.DEFAULT_USERS_BASE_PATH;
- private String groupsBasePath = KernelConstants.DEFAULT_GROUPS_BASE_PATH;
+// private String homeBasePath = KernelConstants.DEFAULT_HOME_BASE_PATH;
+// private String usersBasePath = KernelConstants.DEFAULT_USERS_BASE_PATH;
+// private String groupsBasePath = KernelConstants.DEFAULT_GROUPS_BASE_PATH;
private Set<String> checkedUsers = new HashSet<String>();
private SimpleDateFormat usersDatePath = new SimpleDateFormat("YYYY/MM");
private String defaultHomeWorkspace = NodeConstants.HOME;
+ private String defaultGroupsWorkspace = NodeConstants.GROUPS;
+ private String defaultGuestsWorkspace = NodeConstants.GUESTS;
private final boolean remote;
public HomeRepository(Repository repository, boolean remote) {
@Override
public Void run() {
- Session adminSession = null;
- try {
- adminSession = JcrUtils.loginOrCreateWorkspace(getRepository(defaultHomeWorkspace),
- defaultHomeWorkspace);
- initJcr(adminSession);
- } catch (RepositoryException e) {
- throw new CmsException("Cannot init JCR home", e);
- } finally {
- JcrUtils.logoutQuietly(adminSession);
- }
+ loginOrCreateWorkspace(defaultHomeWorkspace);
+ loginOrCreateWorkspace(defaultGroupsWorkspace);
return null;
}
}
}
+ private void loginOrCreateWorkspace(String workspace) {
+ Session adminSession = null;
+ try {
+ adminSession = JcrUtils.loginOrCreateWorkspace(getRepository(workspace), workspace);
+// JcrUtils.addPrivilege(adminSession, "/", NodeConstants.ROLE_USER, Privilege.JCR_READ);
+
+// initJcr(adminSession);
+ } catch (RepositoryException e) {
+ throw new CmsException("Cannot init JCR home", e);
+ } finally {
+ JcrUtils.logoutQuietly(adminSession);
+ }
+ }
+
@Override
public Session login(Credentials credentials, String workspaceName)
throws LoginException, NoSuchWorkspaceException, RepositoryException {
return defaultHomeWorkspace;
}
+ protected String getGroupsWorkspace() {
+ // TODO base on JAAS Subject metadata
+ return defaultGroupsWorkspace;
+ }
+
+ protected String getGuestsWorkspace() {
+ // TODO base on JAAS Subject metadata
+ return defaultGuestsWorkspace;
+ }
+
@Override
protected void processNewSession(Session session, String workspaceName) {
String username = session.getUserID();
private void initJcr(Session adminSession) {
try {
// JcrUtils.mkdirs(adminSession, homeBasePath);
- JcrUtils.mkdirs(adminSession, groupsBasePath);
+// JcrUtils.mkdirs(adminSession, groupsBasePath);
adminSession.save();
// JcrUtils.addPrivilege(adminSession, homeBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
try {
Node userHome = NodeUtils.getUserHome(adminSession, username);
if (userHome == null) {
- String homePath = generateUserPath(username);
- if (adminSession.itemExists(homePath))// duplicate user id
- userHome = adminSession.getNode(homePath).getParent().addNode(JcrUtils.lastPathElement(homePath));
- else
- userHome = JcrUtils.mkdirs(adminSession, homePath);
- // userHome = JcrUtils.mkfolders(session, homePath);
- userHome.addMixin(NodeTypes.NODE_USER_HOME);
+// String homePath = generateUserPath(username);
+ String userId = extractUserId(username);
+// if (adminSession.itemExists(homePath))// duplicate user id
+// userHome = adminSession.getNode(homePath).getParent().addNode(JcrUtils.lastPathElement(homePath));
+// else
+// userHome = JcrUtils.mkdirs(adminSession, homePath);
+ userHome = adminSession.getRootNode().addNode(userId);
+// userHome.addMixin(NodeTypes.NODE_USER_HOME);
userHome.addMixin(NodeType.MIX_CREATED);
- userHome.setProperty(NodeNames.LDAP_UID, username);
+ userHome.setProperty(Property.JCR_ID, username);
+// userHome.setProperty(NodeNames.LDAP_UID, username);
adminSession.save();
- JcrUtils.clearAccessControList(adminSession, homePath, username);
- JcrUtils.addPrivilege(adminSession, homePath, username, Privilege.JCR_ALL);
+ JcrUtils.clearAccessControList(adminSession, userHome.getPath(), username);
+ JcrUtils.addPrivilege(adminSession, userHome.getPath(), username, Privilege.JCR_ALL);
+// JackrabbitSecurityUtils.denyPrivilege(adminSession, userHome.getPath(), NodeConstants.ROLE_USER,
+// Privilege.JCR_READ);
}
if (adminSession.hasPendingChanges())
adminSession.save();
// }
}
+ private String extractUserId(String username) {
+ LdapName dn;
+ try {
+ dn = new LdapName(username);
+ } catch (InvalidNameException e) {
+ throw new CmsException("Invalid name " + username, e);
+ }
+ String userId = dn.getRdn(dn.size() - 1).getValue().toString();
+ return userId;
+// int atIndex = userId.indexOf('@');
+// if (atIndex < 0) {
+// return homeBasePath+'/' + userId;
+// } else {
+// return usersBasePath + '/' + usersDatePath.format(new Date()) + '/' + userId;
+// }
+ }
+
public void createWorkgroup(LdapName dn) {
- Session adminSession = KernelUtils.openAdminSession(this);
+ String groupsWorkspace = getGroupsWorkspace();
+ Session adminSession = KernelUtils.openAdminSession(getRepository(groupsWorkspace), groupsWorkspace);
String cn = dn.getRdn(dn.size() - 1).getValue().toString();
Node newWorkgroup = NodeUtils.getGroupHome(adminSession, cn);
if (newWorkgroup != null) {
// TODO enhance transformation of cn to a valid node name
// String relPath = cn.replaceAll("[^a-zA-Z0-9]", "_");
String relPath = JcrUtils.replaceInvalidChars(cn);
- newWorkgroup = JcrUtils.mkdirs(adminSession.getNode(groupsBasePath), relPath, NodeType.NT_UNSTRUCTURED);
- newWorkgroup.addMixin(NodeTypes.NODE_GROUP_HOME);
+ newWorkgroup = adminSession.getRootNode().addNode(relPath, NodeType.NT_UNSTRUCTURED);
+// newWorkgroup = JcrUtils.mkdirs(adminSession.getNode(groupsBasePath), relPath, NodeType.NT_UNSTRUCTURED);
+// newWorkgroup.addMixin(NodeTypes.NODE_GROUP_HOME);
newWorkgroup.addMixin(NodeType.MIX_CREATED);
- newWorkgroup.setProperty(NodeNames.LDAP_CN, cn);
+ newWorkgroup.setProperty(Property.JCR_ID, dn.toString());
+// newWorkgroup.setProperty(NodeNames.LDAP_CN, cn);
adminSession.save();
JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_ALL);
adminSession.save();
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.argeo.commons</groupId>
<artifactId>org.argeo.node.api</artifactId>
<version>2.1.86-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms</artifactId>
+ <version>2.1.86-SNAPSHOT</version>
+ </dependency>
<!-- TESTING -->
<dependency>
package org.argeo.security.jackrabbit;
+import java.security.Principal;
import java.util.Map;
+import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
- public void init(Session systemSession, Map configuration)
- throws RepositoryException {
+ public void init(Session systemSession, Map configuration) throws RepositoryException {
if (!configuration.containsKey(PARAM_ALLOW_UNKNOWN_PRINCIPALS))
configuration.put(PARAM_ALLOW_UNKNOWN_PRINCIPALS, "true");
+ if (!configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS))
+ configuration.put(PARAM_OMIT_DEFAULT_PERMISSIONS, "true");
super.init(systemSession, configuration);
}
+ @Override
+ public boolean canAccessRoot(Set<Principal> principals) throws RepositoryException {
+ return super.canAccessRoot(principals);
+ }
+
}
package org.argeo.security.jackrabbit;
import java.security.Principal;
+import java.util.HashSet;
+import java.util.Properties;
import java.util.Set;
+import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.core.DefaultSecurityManager;
import org.apache.jackrabbit.core.security.AMContext;
import org.apache.jackrabbit.core.security.SystemPrincipal;
import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
+import org.argeo.cms.auth.CmsSession;
import org.argeo.node.NodeConstants;
import org.argeo.node.security.AnonymousPrincipal;
import org.argeo.node.security.DataAdminPrincipal;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
/** Customises Jackrabbit security. */
public class ArgeoSecurityManager extends DefaultSecurityManager {
+ private final static Log log = LogFactory.getLog(ArgeoSecurityManager.class);
+
+ private BundleContext cmsBundleContext = null;
+
+ public ArgeoSecurityManager() {
+ if (FrameworkUtil.getBundle(CmsSession.class) != null) {
+ cmsBundleContext = FrameworkUtil.getBundle(CmsSession.class).getBundleContext();
+ }
+ }
+
@Override
public AccessManager getAccessManager(Session session, AMContext amContext) throws RepositoryException {
synchronized (getSystemSession()) {
}
}
+ @Override
+ protected PrincipalProvider createDefaultPrincipalProvider(Properties[] moduleConfig) throws RepositoryException {
+ return super.createDefaultPrincipalProvider(moduleConfig);
+ }
+
/** Called once when the session is created */
@Override
public String getUserID(Subject subject, String workspaceName) throws RepositoryException {
boolean isJackrabbitSystem = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
boolean isRegularUser = !userPrincipal.isEmpty();
+ CmsSession cmsSession = null;
+ if (cmsBundleContext != null) {
+ cmsSession = CmsSession.getCmsSession(cmsBundleContext, subject);
+ if (log.isTraceEnabled())
+ log.trace("Opening JCR session for CMS session " + cmsSession);
+ }
+
if (isAnonymous) {
if (isDataAdmin || isJackrabbitSystem || isRegularUser)
throw new IllegalStateException("Inconsistent " + subject);
@Override
protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
WorkspaceAccessManager wam = super.createDefaultWorkspaceAccessManager();
- return new ArgeoWorkspaceAccessManagerImpl(wam);
+ ArgeoWorkspaceAccessManagerImpl workspaceAccessManager = new ArgeoWorkspaceAccessManagerImpl(wam);
+ if (log.isTraceEnabled())
+ log.trace("Created workspace access manager");
+ return workspaceAccessManager;
}
private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
public void init(Session systemSession) throws RepositoryException {
wam.init(systemSession);
+ Repository repository = systemSession.getRepository();
+ if (log.isTraceEnabled())
+ log.trace("Initialised workspace access manager on repository " + repository
+ + ", systemSession workspace: " + systemSession.getWorkspace().getName());
}
public void close() throws RepositoryException {
public boolean grants(Set<Principal> principals, String workspaceName) throws RepositoryException {
// TODO: implements finer access to workspaces
+ if (log.isTraceEnabled())
+ log.trace("Grants " + new HashSet<>(principals) + " access to workspace '" + workspaceName + "'");
return true;
+ // return wam.grants(principals, workspaceName);
}
}
--- /dev/null
+package org.argeo.jackrabbit.security;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.argeo.jcr.JcrUtils;
+
+/** Utilities around Jackrabbit security extensions. */
+public class JackrabbitSecurityUtils {
+ private final static Log log = LogFactory.getLog(JackrabbitSecurityUtils.class);
+
+ /**
+ * Convenience method for denying a single privilege to a principal (user or
+ * role), typically jcr:all
+ */
+ public synchronized static void denyPrivilege(Session session, String path, String principal, String privilege)
+ throws RepositoryException {
+ List<Privilege> privileges = new ArrayList<Privilege>();
+ privileges.add(session.getAccessControlManager().privilegeFromName(privilege));
+ denyPrivileges(session, path, () -> principal, privileges);
+ }
+
+ /**
+ * Deny privileges on a path to a {@link Principal}. The path must already
+ * exist. Session is saved. Synchronized to prevent concurrent modifications of
+ * the same node.
+ */
+ public synchronized static Boolean denyPrivileges(Session session, String path, Principal principal,
+ List<Privilege> privs) throws RepositoryException {
+ // make sure the session is in line with the persisted state
+ session.refresh(false);
+ JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session.getAccessControlManager();
+ JackrabbitAccessControlList acl = (JackrabbitAccessControlList) JcrUtils.getAccessControlList(acm, path);
+
+// accessControlEntries: for (AccessControlEntry ace : acl.getAccessControlEntries()) {
+// Principal currentPrincipal = ace.getPrincipal();
+// if (currentPrincipal.getName().equals(principal.getName())) {
+// Privilege[] currentPrivileges = ace.getPrivileges();
+// if (currentPrivileges.length != privs.size())
+// break accessControlEntries;
+// for (int i = 0; i < currentPrivileges.length; i++) {
+// Privilege currP = currentPrivileges[i];
+// Privilege p = privs.get(i);
+// if (!currP.getName().equals(p.getName())) {
+// break accessControlEntries;
+// }
+// }
+// return false;
+// }
+// }
+
+ Privilege[] privileges = privs.toArray(new Privilege[privs.size()]);
+ acl.addEntry(principal, privileges, false);
+ acm.setPolicy(path, acl);
+ if (log.isDebugEnabled()) {
+ StringBuffer privBuf = new StringBuffer();
+ for (Privilege priv : privs)
+ privBuf.append(priv.getName());
+ log.debug("Denied privileges " + privBuf + " to " + principal.getName() + " on " + path + " in '"
+ + session.getWorkspace().getName() + "'");
+ }
+ session.refresh(true);
+ session.save();
+ return true;
+ }
+
+ /** Singleton. */
+ private JackrabbitSecurityUtils() {
+
+ }
+}
return true;
}
- /** Gets access control list for this path, throws exception if not found */
+ /**
+ * Gets the first available access control list for this path, throws exception
+ * if not found
+ */
public synchronized static AccessControlList getAccessControlList(AccessControlManager acm, String path)
throws RepositoryException {
// search for an access control list
AccessControlList acl = null;
AccessControlPolicyIterator policyIterator = acm.getApplicablePolicies(path);
- if (policyIterator.hasNext()) {
+ applicablePolicies: if (policyIterator.hasNext()) {
while (policyIterator.hasNext()) {
AccessControlPolicy acp = policyIterator.nextAccessControlPolicy();
- if (acp instanceof AccessControlList)
+ if (acp instanceof AccessControlList) {
acl = ((AccessControlList) acp);
+ break applicablePolicies;
+ }
}
} else {
AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
- for (AccessControlPolicy acp : existingPolicies) {
- if (acp instanceof AccessControlList)
+ existingPolicies: for (AccessControlPolicy acp : existingPolicies) {
+ if (acp instanceof AccessControlList) {
acl = ((AccessControlList) acp);
+ break existingPolicies;
+ }
}
}
if (acl != null)
-Provide-Capability: cms.datamodel;name=node;cnd=/org/argeo/node/node.cnd
\ No newline at end of file
+Provide-Capability: cms.datamodel;name=node;cnd=/org/argeo/node/ldap.cnd;abstract=true
*/
String NODE = "node";
String HOME = "home";
+ String GROUPS = "groups";
+ String GUESTS = "guests";
+ String PUBLIC = "public";
/*
* BASE DNs
package org.argeo.node;
/** JCR types in the http://www.argeo.org/node namespace */
+@Deprecated
public interface NodeNames {
String LDAP_UID = "ldap:"+NodeConstants.UID;
String LDAP_CN = "ldap:"+NodeConstants.CN;
package org.argeo.node;
/** JCR types in the http://www.argeo.org/node namespace */
+@Deprecated
public interface NodeTypes {
String NODE_USER_HOME = "node:userHome";
String NODE_GROUP_HOME = "node:groupHome";
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
-import javax.jcr.query.qom.Constraint;
-import javax.jcr.query.qom.DynamicOperand;
-import javax.jcr.query.qom.QueryObjectModelFactory;
-import javax.jcr.query.qom.Selector;
-import javax.jcr.query.qom.StaticOperand;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
import javax.security.auth.AuthPermission;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
* @param username the username of the user
*/
public static Node getUserHome(Session session, String username) {
+// try {
+// QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
+// Selector sel = qomf.selector(NodeTypes.NODE_USER_HOME, "sel");
+// DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_UID);
+// StaticOperand sop = qomf.literal(session.getValueFactory().createValue(username));
+// Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
+// Query query = qomf.createQuery(sel, constraint, null, null);
+// return querySingleNode(query);
+// } catch (RepositoryException e) {
+// throw new RuntimeException("Cannot find home for user " + username, e);
+// }
+
try {
- QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
- Selector sel = qomf.selector(NodeTypes.NODE_USER_HOME, "sel");
- DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_UID);
- StaticOperand sop = qomf.literal(session.getValueFactory().createValue(username));
- Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
- Query query = qomf.createQuery(sel, constraint, null, null);
- return querySingleNode(query);
+ checkUserWorkspace(session, username);
+ String homePath = getHomePath(username);
+ if (session.itemExists(homePath))
+ return session.getNode(homePath);
+ // legacy
+ homePath = "/home/" + username;
+ if (session.itemExists(homePath))
+ return session.getNode(homePath);
+ return null;
} catch (RepositoryException e) {
throw new RuntimeException("Cannot find home for user " + username, e);
}
}
+ private static String getHomePath(String username) {
+ LdapName dn;
+ try {
+ dn = new LdapName(username);
+ } catch (InvalidNameException e) {
+ throw new IllegalArgumentException("Invalid name " + username, e);
+ }
+ String userId = dn.getRdn(dn.size() - 1).getValue().toString();
+ return '/' + userId;
+ }
+
+ private static void checkUserWorkspace(Session session, String username) {
+ String workspaceName = session.getWorkspace().getName();
+ if (!NodeConstants.HOME.equals(workspaceName))
+ throw new IllegalArgumentException(workspaceName + " is not the home workspace for user " + username);
+ }
+
/**
* Returns the home node of the user or null if none was found.
*
- * @param session the session to use in order to perform the search, this can be
- * a session with a different user ID than the one searched,
- * typically when a system or admin session is used.
- * @param cn the name of the group
+ * @param session the session to use in order to perform the search, this can
+ * be a session with a different user ID than the one searched,
+ * typically when a system or admin session is used.
+ * @param groupname the name of the group
*/
- public static Node getGroupHome(Session session, String cn) {
+ public static Node getGroupHome(Session session, String groupname) {
+// try {
+// QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
+// Selector sel = qomf.selector(NodeTypes.NODE_GROUP_HOME, "sel");
+// DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_CN);
+// StaticOperand sop = qomf.literal(session.getValueFactory().createValue(cn));
+// Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
+// Query query = qomf.createQuery(sel, constraint, null, null);
+// return querySingleNode(query);
+// } catch (RepositoryException e) {
+// throw new RuntimeException("Cannot find home for group " + cn, e);
+// }
+
try {
- QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
- Selector sel = qomf.selector(NodeTypes.NODE_GROUP_HOME, "sel");
- DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_CN);
- StaticOperand sop = qomf.literal(session.getValueFactory().createValue(cn));
- Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
- Query query = qomf.createQuery(sel, constraint, null, null);
- return querySingleNode(query);
+ checkGroupWorkspace(session, groupname);
+ String homePath = getGroupPath(groupname);
+ if (session.itemExists(homePath))
+ return session.getNode(homePath);
+ // legacy
+ homePath = "/groups/" + groupname;
+ if (session.itemExists(homePath))
+ return session.getNode(homePath);
+ return null;
} catch (RepositoryException e) {
- throw new RuntimeException("Cannot find home for user " + cn, e);
+ throw new RuntimeException("Cannot find home for group " + groupname, e);
+ }
+
+ }
+
+ private static String getGroupPath(String groupname) {
+ String cn;
+ try {
+ LdapName dn = new LdapName(groupname);
+ cn = dn.getRdn(dn.size() - 1).getValue().toString();
+ } catch (InvalidNameException e) {
+ cn = groupname;
}
+ return '/' + cn;
+ }
+
+ private static void checkGroupWorkspace(Session session, String groupname) {
+ String workspaceName = session.getWorkspace().getName();
+ if (!NodeConstants.GROUPS.equals(workspaceName))
+ throw new IllegalArgumentException(workspaceName + " is not the group workspace for group " + groupname);
}
/**
--- /dev/null
+<ldap = 'http://www.argeo.org/ns/ldap'>
-<ldap = 'http://www.argeo.org/ns/ldap'>
<node = 'http://www.argeo.org/ns/node'>
[node:userHome]