/*
* *
* Copyright (C) 2014 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* /
*/
package org.anhonesteffort.flock.sync.calendar;
import org.anhonesteffort.flock.util.guava.Optional;
import org.anhonesteffort.flock.sync.HidingDavCollectionMixin;
import org.anhonesteffort.flock.webdav.WebDavConstants;
import org.anhonesteffort.flock.webdav.caldav.CalDavConstants;
import org.anhonesteffort.flock.crypto.MasterCipher;
import org.anhonesteffort.flock.sync.HidingDavStore;
import org.anhonesteffort.flock.crypto.HidingUtil;
import org.anhonesteffort.flock.webdav.DavClient;
import org.anhonesteffort.flock.webdav.PropertyParseException;
import org.anhonesteffort.flock.webdav.caldav.CalDavCollection;
import org.anhonesteffort.flock.webdav.caldav.CalDavStore;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.LinkedList;
import java.util.List;
/**
* Programmer: rhodey
*/
public class HidingCalDavStore implements HidingDavStore<HidingCalDavCollection> {
private MasterCipher masterCipher;
private CalDavStore calDavStore;
public HidingCalDavStore(MasterCipher masterCipher,
String hostHREF,
String username,
String password,
Optional<String> currentUserPrincipal,
Optional<String> calendarHomeSet)
throws DavException, IOException
{
this.masterCipher = masterCipher;
this.calDavStore = new CalDavStore(hostHREF, username, password, currentUserPrincipal, calendarHomeSet);
}
public HidingCalDavStore(MasterCipher masterCipher,
DavClient client,
Optional<String> currentUserPrincipal,
Optional<String> calendarHomeSet) {
this.masterCipher = masterCipher;
this.calDavStore = new CalDavStore(client, currentUserPrincipal, calendarHomeSet);
}
@Override
public String getHostHREF() {
return calDavStore.getHostHREF();
}
public Optional<String> getCalendarHomeSet()
throws PropertyParseException, DavException, IOException
{
return calDavStore.getCalendarHomeSet();
}
@Override
public Optional<HidingCalDavCollection> getCollection(String path) throws DavException, IOException {
HidingCalDavCollection targetCollection = new HidingCalDavCollection(calDavStore, path, masterCipher);
DavPropertyNameSet collectionProps = targetCollection.getPropertyNamesForFetch();
PropFindMethod propFindMethod = new PropFindMethod(path, collectionProps, PropFindMethod.DEPTH_0);
try {
calDavStore.getClient().execute(propFindMethod);
MultiStatus multiStatus = propFindMethod.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
List<CalDavCollection> returnedCollections = CalDavStore.getCollectionsFromMultiStatusResponses(calDavStore, responses);
if (returnedCollections.size() == 0)
Optional.absent();
return Optional.of(new HidingCalDavCollection(returnedCollections.get(0), masterCipher));
} catch (DavException e) {
if (e.getErrorCode() == WebDavConstants.SC_NOT_FOUND)
return Optional.absent();
throw e;
} finally {
propFindMethod.releaseConnection();
}
}
@Override
public List<HidingCalDavCollection> getCollections()
throws PropertyParseException, DavException, IOException
{
Optional<String> calHomeSetUri = getCalendarHomeSet();
if (!calHomeSetUri.isPresent())
throw new PropertyParseException("No calendar-home-set property found for user.",
getHostHREF(), CalDavConstants.PROPERTY_NAME_CALENDAR_HOME_SET);
HidingCalDavCollection hack = new HidingCalDavCollection(calDavStore, "hack", masterCipher);
DavPropertyNameSet calendarProps = hack.getPropertyNamesForFetch();
PropFindMethod method = new PropFindMethod(getHostHREF().concat(calHomeSetUri.get()),
calendarProps,
PropFindMethod.DEPTH_1);
try {
calDavStore.getClient().execute(method);
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
List<HidingCalDavCollection> hidingCollections = new LinkedList<HidingCalDavCollection>();
List<CalDavCollection> collections = CalDavStore.getCollectionsFromMultiStatusResponses(calDavStore, responses);
for (CalDavCollection collection : collections)
hidingCollections.add(new HidingCalDavCollection(collection, masterCipher));
return hidingCollections;
} finally {
method.releaseConnection();
}
}
@Override
public void addCollection(String path)
throws DavException, IOException, GeneralSecurityException
{
DavPropertySet properties = new DavPropertySet();
properties.add(new DefaultDavProperty<Object>(HidingDavCollectionMixin.PROPERTY_FLOCK_COLLECTION, "true"));
calDavStore.addCollection(path, properties);
}
public void addCollection(String path,
String displayName,
Integer color)
throws DavException, IOException, GeneralSecurityException
{
DavPropertySet properties = new DavPropertySet();
String hiddenDisplayName = HidingUtil.encryptEncodeAndPrefix(masterCipher, displayName);
String hiddenColor = HidingUtil.encryptEncodeAndPrefix(masterCipher, color.toString());
properties.add(new DefaultDavProperty<Object>(HidingDavCollectionMixin.PROPERTY_FLOCK_COLLECTION, "true"));
properties.add(new DefaultDavProperty<String>(DavPropertyName.DISPLAYNAME, hiddenDisplayName));
properties.add(new DefaultDavProperty<String>(HidingCalDavCollection.PROPERTY_HIDDEN_COLOR, hiddenColor));
calDavStore.addCollection(path, properties);
}
@Override
public void removeCollection(String path) throws DavException, IOException {
calDavStore.removeCollection(path);
}
public void releaseConnections() {
calDavStore.closeHttpConnection();
}
}