<property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
<property name="osgi.http.whiteboard.servlet.multipart.enabled" type="String" value="true"/>
<reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
+ <reference bind="addSubmissionListener" cardinality="0..n" interface="org.argeo.support.xforms.FormSubmissionListener" name="FormSubmissionListener" policy="dynamic" unbind="removeSubmissionListener"/>
</scr:component>
<artifactId>org.argeo.suite.core</artifactId>
<version>2.1.16-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>org.argeo.support.xforms</artifactId>
+ <version>2.1.16-SNAPSHOT</version>
+ </dependency>
</dependencies>
</project>
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
+import java.util.HashSet;
+import java.util.Set;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Node;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeUtils;
+import org.argeo.cms.auth.CmsSession;
import org.argeo.cms.servlet.ServletAuthUtils;
-import org.argeo.entity.EntityNames;
-import org.argeo.entity.EntityType;
import org.argeo.jcr.Jcr;
import org.argeo.jcr.JcrUtils;
+import org.argeo.suite.SuiteUtils;
import org.argeo.support.odk.OrxType;
+import org.argeo.support.xforms.FormSubmissionListener;
/** Receives a form submission. */
public class OdkSubmissionServlet extends HttpServlet {
private Repository repository;
+ private Set<FormSubmissionListener> submissionListeners = new HashSet<>();
+
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/xml; charset=utf-8");
Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req);
try {
- Node submissions = JcrUtils.mkdirs(session,
- "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE);
- Node submission = submissions.addNode(submissionNameFormatter.format(Instant.now()),
+// Node submissions = JcrUtils.mkdirs(session,
+// "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE);
+ CmsSession cmsSession = ServletAuthUtils.getCmsSession(req);
+
+ ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(ServletAuthUtils.class.getClassLoader());
+ Session adminSession = null;
+ try {
+ // TODO centralise at a deeper level
+ adminSession = NodeUtils.openDataAdminSession(repository, null);
+ SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
+ } finally {
+ Jcr.logout(adminSession);
+ Thread.currentThread().setContextClassLoader(currentContextCl);
+ }
+
+ Node cmsSessionNode = SuiteUtils.getCmsSessionNode(session, cmsSession);
+ Node submission = cmsSessionNode.addNode(submissionNameFormatter.format(Instant.now()),
OrxType.submission.get());
for (Part part : req.getParts()) {
if (log.isDebugEnabled())
}
}
session.save();
+ for (FormSubmissionListener submissionListener : submissionListeners) {
+ submissionListener.formSubmissionReceived(submission);
+ }
} catch (RepositoryException e) {
e.printStackTrace();
resp.setStatus(503);
this.repository = repository;
}
+ public synchronized void addSubmissionListener(FormSubmissionListener listener) {
+ submissionListeners.add(listener);
+ }
+
+ public synchronized void removeSubmissionListener(FormSubmissionListener listener) {
+ submissionListeners.remove(listener);
+ }
}
--- /dev/null
+package org.argeo.support.xforms;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/** Called when a user has received a new form submission. */
+public interface FormSubmissionListener {
+ /** Called after a form submission has been stored in the user area. */
+ void formSubmissionReceived(Node node) throws RepositoryException;
+}
import javax.jcr.nodetype.NodeType;
import javax.jcr.security.Privilege;
import javax.naming.ldap.LdapName;
+import javax.security.auth.x500.X500Principal;
import org.argeo.cms.auth.CmsSession;
import org.argeo.entity.EntityType;
+import org.argeo.jackrabbit.security.JackrabbitSecurityUtils;
import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import org.argeo.naming.LdapAttrs;
userNode.setProperty(LdapAttrs.distinguishedName.property(), userDn.toString());
userNode.setProperty(LdapAttrs.uid.property(), uid);
adminSession.save();
+ JackrabbitSecurityUtils.denyPrivilege(adminSession, userNode.getPath(), SuiteRole.coworker.dn(),
+ Privilege.JCR_READ);
+ JcrUtils.addPrivilege(adminSession, userNode.getPath(), new X500Principal(userDn.toString()).getName(),
+ Privilege.JCR_ALL);
} else {
userNode = usersBase.getNode(uid);
}
}
}
- public static Node getOrCreateSessionDir(Session adminSession, CmsSession cmsSession) {
+ public static Node getCmsSessionNode(Session session, CmsSession cmsSession) {
+ try {
+ return session.getNode(getUserNodePath(cmsSession.getUserDn()) + '/' + cmsSession.getUuid().toString());
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot get session dir for " + cmsSession, e);
+ }
+ }
+
+ public static Node getOrCreateCmsSessionNode(Session adminSession, CmsSession cmsSession) {
try {
LdapName userDn = cmsSession.getUserDn();
// String uid = userDn.get(userDn.size() - 1);
// userNode = usersBase.getNode(uid);
// }
String cmsSessionUuid = cmsSession.getUuid().toString();
- Node userDir;
+ Node cmsSessionNode;
if (!userNode.hasNode(cmsSessionUuid)) {
- userDir = userNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED);
- userDir.addMixin(NodeType.MIX_CREATED);
+ cmsSessionNode = userNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED);
+ cmsSessionNode.addMixin(NodeType.MIX_CREATED);
adminSession.save();
- JcrUtils.addPrivilege(adminSession, userDir.getPath(), cmsSession.getUserDn().toString(),
+ JcrUtils.addPrivilege(adminSession, cmsSessionNode.getPath(), cmsSession.getUserRole(),
Privilege.JCR_ALL);
} else {
- userDir = userNode.getNode(cmsSessionUuid);
+ cmsSessionNode = userNode.getNode(cmsSessionUuid);
}
- return userDir;
+ return cmsSessionNode;
} catch (RepositoryException e) {
throw new JcrException("Cannot create session dir for " + cmsSession, e);
}
import org.argeo.entity.EntityType;
import org.argeo.jcr.JcrUtils;
import org.argeo.maintenance.AbstractMaintenanceService;
+import org.argeo.suite.SuiteRole;
/** Initialises an Argeo Suite backend. */
public class SuiteMaintenanceService extends AbstractMaintenanceService {
public void configurePrivileges(Session adminSession) throws RepositoryException {
JcrUtils.addPrivilege(adminSession, EntityType.user.basePath(), NodeConstants.ROLE_USER_ADMIN,
Privilege.JCR_ALL);
+ JcrUtils.addPrivilege(adminSession, "/", SuiteRole.coworker.dn(), Privilege.JCR_READ);
}
}
Session adminSession = null;
try {
adminSession = NodeUtils.openDataAdminSession(getRepository(), null);
- Node userDir = SuiteUtils.getOrCreateSessionDir(adminSession, cmsSession);
+ Node userDir = SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
ui.initSessions(getRepository(), userDir.getPath());
} finally {
Jcr.logout(adminSession);