Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* ********************************************************************
Licensed to Jasig under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Jasig 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.bedework.caldav.server;
import org.bedework.access.AccessException;
import org.bedework.access.AccessPrincipal;
import org.bedework.access.AccessXmlUtil.AccessXmlCb;
import org.bedework.access.Ace;
import org.bedework.access.AceWho;
import org.bedework.access.Acl;
import org.bedework.access.PrivilegeDefs;
import org.bedework.access.WhoDefs;
import org.bedework.caldav.server.CaldavBwNode.PropertyTagXrdEntry;
import org.bedework.caldav.server.calquery.CalData;
import org.bedework.caldav.server.calquery.FreeBusyQuery;
import org.bedework.caldav.server.filter.FilterHandler;
import org.bedework.caldav.server.get.FreeBusyGetHandler;
import org.bedework.caldav.server.get.GetHandler;
import org.bedework.caldav.server.get.IscheduleGetHandler;
import org.bedework.caldav.server.get.ServerInfoGetHandler;
import org.bedework.caldav.server.get.WebcalGetHandler;
import org.bedework.caldav.server.soap.synch.SynchConnections;
import org.bedework.caldav.server.soap.synch.SynchConnectionsMBean;
import org.bedework.caldav.server.sysinterface.CalPrincipalInfo;
import org.bedework.caldav.server.sysinterface.RetrievalMode;
import org.bedework.caldav.server.sysinterface.SysIntf;
import org.bedework.caldav.server.sysinterface.SysIntf.IcalResultType;
import org.bedework.caldav.server.sysinterface.SysIntf.SynchReportData;
import org.bedework.caldav.server.sysinterface.SysIntf.SynchReportData.SynchReportDataItem;
import org.bedework.util.jmx.AnnotatedMBean;
import org.bedework.util.jmx.ManagementContext;
import org.bedework.util.misc.Util;
import org.bedework.util.misc.response.GetEntityResponse;
import org.bedework.util.misc.response.Response;
import org.bedework.util.xml.XmlEmit;
import org.bedework.util.xml.XmlEmit.NameSpace;
import org.bedework.util.xml.XmlUtil;
import org.bedework.util.xml.tagdefs.AppleIcalTags;
import org.bedework.util.xml.tagdefs.AppleServerTags;
import org.bedework.util.xml.tagdefs.BedeworkServerTags;
import org.bedework.util.xml.tagdefs.CalWSXrdDefs;
import org.bedework.util.xml.tagdefs.CaldavDefs;
import org.bedework.util.xml.tagdefs.CaldavTags;
import org.bedework.util.xml.tagdefs.WebdavTags;
import org.bedework.util.xml.tagdefs.XcalTags;
import org.bedework.util.xml.tagdefs.XrdTags;
import org.bedework.util.xml.tagdefs.XsiTags;
import org.bedework.webdav.servlet.common.AccessUtil;
import org.bedework.webdav.servlet.common.Headers;
import org.bedework.webdav.servlet.common.Headers.IfHeaders;
import org.bedework.webdav.servlet.common.MethodBase.MethodInfo;
import org.bedework.webdav.servlet.common.WebdavServlet;
import org.bedework.webdav.servlet.common.WebdavUtils;
import org.bedework.webdav.servlet.shared.PrincipalPropertySearch;
import org.bedework.webdav.servlet.shared.WdEntity;
import org.bedework.webdav.servlet.shared.WdSynchReport;
import org.bedework.webdav.servlet.shared.WdSynchReport.WdSynchReportItem;
import org.bedework.webdav.servlet.shared.WdSysIntf;
import org.bedework.webdav.servlet.shared.WebdavBadRequest;
import org.bedework.webdav.servlet.shared.WebdavException;
import org.bedework.webdav.servlet.shared.WebdavForbidden;
import org.bedework.webdav.servlet.shared.WebdavNsIntf;
import org.bedework.webdav.servlet.shared.WebdavNsNode;
import org.bedework.webdav.servlet.shared.WebdavNsNode.PropertyTagEntry;
import org.bedework.webdav.servlet.shared.WebdavPrincipalNode;
import org.bedework.webdav.servlet.shared.WebdavProperty;
import org.bedework.webdav.servlet.shared.WebdavServerError;
import org.bedework.webdav.servlet.shared.WebdavUnauthorized;
import org.bedework.webdav.servlet.shared.WebdavUnsupportedMediaType;
import org.bedework.webdav.servlet.shared.serverInfo.Application;
import org.bedework.webdav.servlet.shared.serverInfo.Feature;
import org.bedework.webdav.servlet.shared.serverInfo.ServerInfo;
import ietf.params.xml.ns.caldav.FilterType;
import ietf.params.xml.ns.icalendar_2.IcalendarType;
import org.oasis_open.docs.ns.xri.xrd_1.AnyURI;
import org.oasis_open.docs.ns.xri.xrd_1.LinkType;
import org.oasis_open.docs.ns.xri.xrd_1.XRDType;
import org.oasis_open.docs.ws_calendar.ns.soap.GetPropertiesBasePropertyType;
import org.w3c.dom.Element;
import java.io.CharArrayReader;
import java.io.InputStream;
import java.io.Reader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Supplier;
import javax.management.ObjectName;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import static org.bedework.util.misc.response.Response.Status.forbidden;
import static org.bedework.util.misc.response.Response.Status.notFound;
/** This class implements a namespace interface for the webdav abstract
* servlet. One of these interfaces is associated with each current session.
*
*
As a first pass we'll define webdav urls as starting with
* /user/user-name/calendar-name/
*
*
uri resolution should be made part of the core calendar allowing all
* such distinctions to be removed from this code.
*
*
The part following the above prefix probably determines exactly what is
* delivered. We may want the entire calendar (or what we show by default) or
* a single event from the calendar
*
* @author Mike Douglass douglm rpi.edu
*/
public class CaldavBWIntf extends WebdavNsIntf {
/** Namespace prefix based on the request url.
*/
private String namespacePrefix;
private AccessUtil accessUtil;
/** Namespace based on the request url.
*/
@SuppressWarnings("unused")
private String namespace;
SysIntf sysi;
/* true if this is a CalWS server */
private boolean calWs;
private static ServerInfo serverInfo;
/* ====================================================================
* JMX configuration
* ==================================================================== */
/* Marks the bedework end of the synch service. This is a web
service called by the synch engine to get information out of
bedework and to update events and status.
This service should probably be restricted to a given host only.
Coming up on a separate port might help to lock it down.
*/
private boolean synchWs;
/* Marks the bedework end of the notification service. This is a web
service called by the notification engine to get information out of
bedework and to update notifications.
This service should probably be restricted to a given host only.
Coming up on a separate port might help to lock it down.
*/
private boolean notifyWs;
/* Marks the bedework end of the websockets service. That service
acts as a websockets proxy to CalDAV.
*/
private boolean socketWs;
private final static Set registeredMBeans =
new CopyOnWriteArraySet<>();
private static ManagementContext managementContext;
private static SynchConnections synchConn;
/*
static {
try {
synchConn = new SynchConnections();
registerMbean(new ObjectName(synchConn.getServiceName()),
synchConn);
} catch (Throwable e) {
e.printStackTrace();
}
}
*/
public static void registerMbean(final ObjectName key,
final Object bean) {
try {
AnnotatedMBean.registerMBean(getManagementContext(), bean, key);
registeredMBeans.add(key);
} catch (final Throwable e) {
e.printStackTrace();
}
}
/**
* @param key bean objectname
*/
public static void unregister(final ObjectName key) {
if (registeredMBeans.remove(key)) {
try {
getManagementContext().unregisterMBean(key);
} catch (final Throwable e) {
e.printStackTrace();
}
}
}
/**
* @return the management context.
*/
public static ManagementContext getManagementContext() {
if (managementContext == null) {
/* Try to find the jboss mbean server * /
MBeanServer mbsvr = null;
for (MBeanServer svr: MBeanServerFactory.findMBeanServer(null)) {
if (svr.getDefaultDomain().equals("jboss")) {
mbsvr = svr;
break;
}
}
if (mbsvr == null) {
Logger.getLogger(ConfBase.class).warn("Unable to locate jboss mbean server");
}
managementContext = new ManagementContext(mbsvr);
*/
managementContext = new ManagementContext(ManagementContext.DEFAULT_DOMAIN);
}
return managementContext;
}
static void contextInitialized(final ServletContextEvent sce) {
/* We may enter a number of times for each context implementing
DAV or SOAP services.
We cannot set flags such as synchws as static fields because
they are context dependent and the context share a common
set of loaded classes.
We'll only do this once - based on the presence of a management
context.
*/
try {
synchronized (registeredMBeans) {
if (managementContext != null) {
// Already done
return;
}
final ServletContext sc = sce.getServletContext();
synchConn = new SynchConnections();
registerMbean(new ObjectName(synchConn.getServiceName()),
synchConn);
}
} catch (final Throwable t) {
t.printStackTrace();
}
}
static void contextDestroyed(final ServletContextEvent sce) {
synchronized (registeredMBeans) {
if (managementContext == null) {
// Already cleaned up.
return;
}
try {
for (final ObjectName on: registeredMBeans) {
unregister(on);
}
} catch (final Throwable t) {
t.printStackTrace();
} finally {
try {
managementContext.stop();
} catch (final Throwable ignored) {}
managementContext = null;
}
}
}
/* ====================================================================
* Interface methods
* ==================================================================== */
/** Called before any other method is called to allow initialization to
* take place at the first or subsequent requests
*
* @param servlet calling servlet
* @param req http request
* @param methods HashMap table of method info
* @param dumpContent true if we dump content
* @throws WebdavException
*/
@Override
public void init(final WebdavServlet servlet,
final HttpServletRequest req,
final HashMap methods,
final boolean dumpContent) throws WebdavException {
try {
// Needed before any other initialization
calWs = Boolean.parseBoolean(servlet.getInitParameter("calws"));
synchWs = Boolean.parseBoolean(servlet.getInitParameter("synchws"));
notifyWs = Boolean.parseBoolean(servlet.getInitParameter("notifyws"));
socketWs = Boolean.parseBoolean(servlet.getInitParameter("socketws"));
sysi = getSysi(servlet.getInitParameter("sysintfImpl"));
super.init(servlet, req, methods, dumpContent);
namespacePrefix = WebdavUtils.getUrlPrefix(req);
namespace = namespacePrefix + "/schema";
account = sysi.init(req, account, false,
calWs, synchWs, notifyWs, socketWs, null);
accessUtil = new AccessUtil(namespacePrefix, xml,
new CalDavAccessXmlCb(sysi));
} catch (final WebdavException we) {
throw we;
} catch (final Throwable t) {
throw new WebdavException(t);
}
}
public SynchConnectionsMBean getActiveConnections() throws Throwable {
/*
if (conns == null) {
conns = (SynchConnectionsMBean)MBeanUtil.getMBean(
SynchConnectionsMBean.class,
"org.bedework:service=CalDAVSynchConnections");
}
*/
return synchConn;
}
/** See if we can reauthenticate. Use for real-time service which needs to
* authenticate as a particular principal.
*
* @param req http request
* @param account to reinit as
* @param service - true if this is a service call - e.g. iSchedule -
* rather than a real user.
* @param opaqueData - possibly from headers
* @throws WebdavException
*/
public void reAuth(final HttpServletRequest req,
final String account,
final boolean service,
final String opaqueData) throws WebdavException {
try {
if (sysi != null) {
try {
sysi.close();
} catch (final Throwable t) {
throw new WebdavException(t);
}
} else {
sysi = getSysi(servlet.getInitParameter("sysintfImpl"));
}
this.account = account;
sysi.init(req, account, service,
calWs, synchWs, notifyWs, socketWs, opaqueData);
accessUtil = new AccessUtil(namespacePrefix, xml,
new CalDavAccessXmlCb(sysi));
} catch (final Throwable t) {
throw new WebdavException(t);
}
}
/**
* @return boolean
*/
public boolean getCalWS() {
return calWs;
}
/** Get the synch web service flag
*
* @return true if it's a synch service
*/
public boolean getSynchWs() {
return synchWs;
}
/** Get the notify web service flag
*
* @return true if it's a notify service
*/
public boolean getNotifyWs() {
return notifyWs;
}
@Override
public String getDavHeader(final WebdavNsNode node) throws WebdavException {
if (account == null) {
return super.getDavHeader(node) + ", calendar-access";
}
String hdr = super.getDavHeader(node) +
", calendar-access" +
", calendar-schedule" +
", calendar-auto-schedule" +
", calendar-default-alarms" +
", calendarserver-sharing";
if (getSysi().getSystemProperties().getTimezonesByReference()) {
hdr += ", calendar-no-timezone";
}
return hdr;
}
@Override
public ServerInfo getServerInfo() {
if (serverInfo != null) {
return serverInfo;
}
serverInfo = super.getServerInfo();
/* Augment with our services */
//
//
final Application app = new Application("caldav");
app.addFeature(new Feature(CaldavTags.calendarAccess));
app.addFeature(new Feature(CaldavTags.calendarAutoschedule));
app.addFeature(new Feature(CaldavTags.calendarDefaultAlarms));
app.addFeature(new Feature(CaldavTags.calendarNoTimezone));
app.addFeature(new Feature(AppleServerTags.calendarServerSharing));
serverInfo.addApplication(app);
return serverInfo;
}
@Override
public void emitError(final QName errorTag, final String extra,
final XmlEmit xml) {
if (errorTag.equals(CaldavTags.noUidConflict)) {
xml.openTag(errorTag);
if (extra != null) {
xml.property(WebdavTags.href, sysi.getUrlHandler().prefix(extra));
}
xml.closeTag(errorTag);
} else {
super.emitError(errorTag, extra, xml);
}
}
/**
*/
private static class CalDavAccessXmlCb implements AccessXmlCb, Serializable {
private final SysIntf sysi;
private QName errorTag;
private String errorMsg;
CalDavAccessXmlCb(final SysIntf sysi) {
this.sysi = sysi;
}
@Override
public String makeHref(final String id, final int whoType) throws AccessException {
try {
return sysi.makeHref(id, whoType);
} catch (final Throwable t) {
throw new AccessException(t);
}
}
@Override
public AccessPrincipal getPrincipal() throws AccessException {
try {
return sysi.getPrincipal();
} catch (final Throwable t) {
throw new AccessException(t);
}
}
@Override
public AccessPrincipal getPrincipal(final String href) throws AccessException {
try {
return sysi.getPrincipal(sysi.getUrlHandler().unprefix(href));
} catch (final Throwable t) {
throw new AccessException(t);
}
}
@Override
public void setErrorTag(final QName tag) {
errorTag = tag;
}
@Override
public QName getErrorTag() {
return errorTag;
}
@Override
public void setErrorMsg(final String val) {
errorMsg = val;
}
@Override
public String getErrorMsg() {
return errorMsg;
}
}
@Override
public AccessUtil getAccessUtil() {
return accessUtil;
}
@Override
public boolean canPut(final WebdavNsNode node) throws WebdavException {
CalDAVEvent> ev = null;
if (node instanceof CaldavComponentNode) {
final CaldavComponentNode comp = (CaldavComponentNode)node;
ev = comp.getEvent();
} else if (!(node instanceof CaldavResourceNode)) {
return false;
}
if (ev != null) {
return sysi.checkAccess(ev,
PrivilegeDefs.privWriteContent,
true).getAccessAllowed();
} else {
return sysi.checkAccess(node.getCollection(true), // deref - we're trying to put into the target
PrivilegeDefs.privBind, true).getAccessAllowed();
}
}
@Override
public String getAddMemberSuffix() {
return ";add-member";
}
@Override
public boolean getDirectoryBrowsingDisallowed() throws WebdavException {
return sysi.getAuthProperties().getDirectoryBrowsingDisallowed();
}
@Override
public void rollback() {
sysi.rollback();
}
@Override
public void close() throws WebdavException {
sysi.close();
}
@Override
public WdSysIntf getSysIntf() {
return sysi;
}
/**
* @return SysIntf
*/
public SysIntf getSysi() {
return sysi;
}
@Override
public String getSupportedLocks() {
return null; // No locks
/*
return "" +
" " +
" " +
" " +
" " +
"";
*/
}
@Override
public boolean getAccessControl() {
return true;
}
@Override
public void addNamespace(final XmlEmit xml) {
if (calWs) {
xml.addNs(new NameSpace(CalWSXrdDefs.namespace, "CalWS"), true);
xml.addNs(new NameSpace(XsiTags.namespace, "xsi"), false);
xml.addNs(new NameSpace(XrdTags.namespace, "xrd"), false);
// Need these for the time being
xml.addNs(new NameSpace(WebdavTags.namespace, "DAV"), false);
xml.addNs(new NameSpace(CaldavDefs.caldavNamespace, "C"), false);
return;
}
super.addNamespace(xml);
xml.addNs(new NameSpace(CaldavDefs.caldavNamespace, "C"), true);
xml.addNs(new NameSpace(AppleIcalTags.appleIcalNamespace, "AI"), false);
xml.addNs(new NameSpace(CaldavDefs.icalNamespace, "ical"), false);
xml.addNs(new NameSpace(AppleServerTags.appleCaldavNamespace, "CS"), false);
xml.addNs(new NameSpace(BedeworkServerTags.bedeworkCaldavNamespace, "BSS"), false);
}
@Override
public WebdavNsNode getNode(final String uri,
final int existence,
final int nodeType,
final boolean addMember) throws WebdavException {
return getNodeInt(uri, existence, nodeType, addMember,
null, null, null);
}
@Override
public void putNode(final WebdavNsNode node) {
}
@Override
public void delete(final WebdavNsNode node) throws WebdavException {
try {
if (node instanceof CaldavResourceNode) {
final CaldavResourceNode rnode = (CaldavResourceNode)node;
sysi.deleteFile(rnode.getResource());
} else if (node instanceof CaldavComponentNode) {
final CaldavComponentNode cnode = (CaldavComponentNode)node;
final CalDAVEvent> ev = cnode.getEvent();
if (ev != null) {
if (debug()) {
debug("About to delete event " + ev);
}
boolean sendSchedulingMessage = true;
if (sysi.testMode()) {
final String userAgent = getRequest().getHeader("user-agent");
if ((userAgent != null) &&
(userAgent.contains("| END_REQUESTS") ||
userAgent.contains("| START_REQUESTS")) &&
userAgent.contains("| DELETEALL")) {
sendSchedulingMessage = false;
}
}
if (!CalDavHeaders.scheduleReply(getRequest())) {
sendSchedulingMessage = false;
}
sysi.deleteEvent(ev, sendSchedulingMessage);
} else {
if (debug()) {
debug("No event object available");
}
}
} else {
if (!(node instanceof CaldavCalNode)) {
throw new WebdavUnauthorized();
}
final CaldavCalNode cnode = (CaldavCalNode)node;
final CalDAVCollection> col =
(CalDAVCollection>)cnode.getCollection(false); // Don't deref for delete
boolean sendSchedulingMessage = true;
if (sysi.testMode()) {
final String userAgent = getRequest().getHeader("user-agent");
if ((userAgent != null) &&
userAgent.contains("| END_REQUESTS") &&
userAgent.contains("| DELETEALL")) {
sendSchedulingMessage = false;
}
}
sysi.deleteCollection(col, sendSchedulingMessage);
}
} catch (final WebdavException we) {
throw we;
} catch (final Throwable t) {
throw new WebdavException(t);
}
}
@Override
public Collection getChildren(
final WebdavNsNode node,
final Supplier