mirror of
https://github.com/etesync/android
synced 2025-02-23 21:02:26 +00:00
Rewrite initial configuration detection
* HttpClient: add Accept-Language header * HttpClient: fix MemoryCookieStore NullPointerException * DavResourceFinder: check for home sets, too
This commit is contained in:
parent
89050d88c6
commit
85a6b68a56
@ -146,8 +146,10 @@ public class HttpClient {
|
|||||||
static class UserAgentInterceptor implements Interceptor {
|
static class UserAgentInterceptor implements Interceptor {
|
||||||
@Override
|
@Override
|
||||||
public Response intercept(Chain chain) throws IOException {
|
public Response intercept(Chain chain) throws IOException {
|
||||||
|
Locale locale = Locale.getDefault();
|
||||||
Request request = chain.request().newBuilder()
|
Request request = chain.request().newBuilder()
|
||||||
.header("User-Agent", userAgent)
|
.header("User-Agent", userAgent)
|
||||||
|
.header("Accept-Language", locale.getLanguage() + "-" + locale.getCountry() + ", " + locale.getLanguage() + ";q=0.7, *;q=0.5")
|
||||||
.build();
|
.build();
|
||||||
return chain.proceed(request);
|
return chain.proceed(request);
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,14 @@
|
|||||||
|
|
||||||
package at.bitfire.davdroid;
|
package at.bitfire.davdroid;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import at.bitfire.davdroid.resource.DavResourceFinder;
|
||||||
import okhttp3.Cookie;
|
import okhttp3.Cookie;
|
||||||
import okhttp3.CookieJar;
|
import okhttp3.CookieJar;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
@ -35,7 +38,12 @@ public class MemoryCookieStore implements CookieJar {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Cookie> loadForRequest(HttpUrl url) {
|
public List<Cookie> loadForRequest(HttpUrl url) {
|
||||||
return store.get(url);
|
List<Cookie> cookies = store.get(url);
|
||||||
|
|
||||||
|
if (cookies == null)
|
||||||
|
cookies = Collections.emptyList();
|
||||||
|
|
||||||
|
return cookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,6 @@ package at.bitfire.davdroid.resource;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.xbill.DNS.Lookup;
|
import org.xbill.DNS.Lookup;
|
||||||
import org.xbill.DNS.Record;
|
import org.xbill.DNS.Record;
|
||||||
@ -22,9 +20,11 @@ import org.xbill.DNS.Type;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import at.bitfire.dav4android.DavResource;
|
import at.bitfire.dav4android.DavResource;
|
||||||
import at.bitfire.dav4android.UrlUtils;
|
import at.bitfire.dav4android.UrlUtils;
|
||||||
@ -46,8 +46,11 @@ import at.bitfire.davdroid.HttpClient;
|
|||||||
import at.bitfire.davdroid.log.StringLogger;
|
import at.bitfire.davdroid.log.StringLogger;
|
||||||
import at.bitfire.davdroid.ui.setup.LoginCredentialsFragment;
|
import at.bitfire.davdroid.ui.setup.LoginCredentialsFragment;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
public class DavResourceFinder {
|
public class DavResourceFinder {
|
||||||
@ -66,13 +69,7 @@ public class DavResourceFinder {
|
|||||||
protected final Logger log = new StringLogger("DavResourceFinder", true);
|
protected final Logger log = new StringLogger("DavResourceFinder", true);
|
||||||
protected OkHttpClient httpClient;
|
protected OkHttpClient httpClient;
|
||||||
|
|
||||||
protected HttpUrl carddavPrincipal, caldavPrincipal;
|
public DavResourceFinder(@NonNull Context context, @NonNull LoginCredentialsFragment.LoginCredentials credentials) {
|
||||||
protected Map<HttpUrl, ServerConfiguration.Collection>
|
|
||||||
addressBooks = new HashMap<>(),
|
|
||||||
calendars = new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
public DavResourceFinder(Context context, LoginCredentialsFragment.LoginCredentials credentials) {
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.credentials = credentials;
|
this.credentials = credentials;
|
||||||
|
|
||||||
@ -82,85 +79,38 @@ public class DavResourceFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ServerConfiguration findInitialConfiguration() {
|
public Configuration findInitialConfiguration() {
|
||||||
addressBooks.clear();
|
final Configuration.ServiceInfo
|
||||||
findInitialConfiguration(Service.CARDDAV);
|
cardDavConfig = findInitialConfiguration(Service.CARDDAV),
|
||||||
|
calDavConfig = findInitialConfiguration(Service.CALDAV);
|
||||||
|
|
||||||
calendars.clear();
|
return new Configuration(cardDavConfig, calDavConfig, log.toString());
|
||||||
findInitialConfiguration(Service.CALDAV);
|
|
||||||
|
|
||||||
return new ServerConfiguration(
|
|
||||||
carddavPrincipal, addressBooks.values().toArray(new ServerConfiguration.Collection[0]),
|
|
||||||
caldavPrincipal, calendars.values().toArray(new ServerConfiguration.Collection[0]),
|
|
||||||
log.toString()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void findInitialConfiguration(Service service) {
|
protected Configuration.ServiceInfo findInitialConfiguration(@NonNull Service service) {
|
||||||
// user-given base URI (mailto or URL)
|
// user-given base URI (either mailto: URI or http(s):// URL)
|
||||||
URI baseURI = credentials.getUri();
|
final URI baseURI = credentials.getUri();
|
||||||
|
|
||||||
// domain for service discovery
|
// domain for service discovery
|
||||||
String domain = null;
|
String discoveryFQDN = null;
|
||||||
|
|
||||||
HttpUrl principal = null;
|
// put discovered information here
|
||||||
|
final Configuration.ServiceInfo config = new Configuration.ServiceInfo();
|
||||||
|
log.info("Finding initial {} service configuration", service.name);
|
||||||
|
|
||||||
// Step 1a (only when user-given URI is URL):
|
|
||||||
// * Check whether URL represents a calendar/address-book collection itself,
|
|
||||||
// * and/or whether it has a current-user-principal,
|
|
||||||
// * or whether it represents a principal itself.
|
|
||||||
if ("http".equalsIgnoreCase(baseURI.getScheme()) || "https".equalsIgnoreCase(baseURI.getScheme())) {
|
if ("http".equalsIgnoreCase(baseURI.getScheme()) || "https".equalsIgnoreCase(baseURI.getScheme())) {
|
||||||
HttpUrl baseURL = HttpUrl.get(baseURI);
|
final HttpUrl baseURL = HttpUrl.get(baseURI);
|
||||||
|
|
||||||
// remember domain for service discovery (if required)
|
// remember domain for service discovery
|
||||||
// try service discovery only for https:// URLs because only secure service discovery is implemented
|
// try service discovery only for https:// URLs because only secure service discovery is implemented
|
||||||
if ("https".equalsIgnoreCase(baseURL.scheme()))
|
if ("https".equalsIgnoreCase(baseURL.scheme()))
|
||||||
domain = baseURI.getHost();
|
discoveryFQDN = baseURI.getHost();
|
||||||
|
|
||||||
log.info("Checking user-given URL: " + baseURL.toString());
|
checkUserGivenURL(baseURL, service, config);
|
||||||
try {
|
|
||||||
DavResource davBase = new DavResource(log, httpClient, baseURL);
|
|
||||||
|
|
||||||
if (service == Service.CARDDAV) {
|
if (config.principal == null)
|
||||||
davBase.propfind(0,
|
|
||||||
AddressbookHomeSet.NAME,
|
|
||||||
ResourceType.NAME, DisplayName.NAME, AddressbookDescription.NAME, CurrentUserPrivilegeSet.NAME,
|
|
||||||
CurrentUserPrincipal.NAME
|
|
||||||
);
|
|
||||||
addIfAddressBook(davBase);
|
|
||||||
} else if (service == Service.CALDAV) {
|
|
||||||
davBase.propfind(0,
|
|
||||||
CalendarHomeSet.NAME, SupportedCalendarComponentSet.NAME,
|
|
||||||
ResourceType.NAME, DisplayName.NAME, CalendarColor.NAME, CalendarDescription.NAME, CalendarTimezone.NAME, CurrentUserPrivilegeSet.NAME,
|
|
||||||
CurrentUserPrincipal.NAME
|
|
||||||
);
|
|
||||||
addIfCalendar(davBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for current-user-principal
|
|
||||||
CurrentUserPrincipal currentUserPrincipal = (CurrentUserPrincipal)davBase.properties.get(CurrentUserPrincipal.NAME);
|
|
||||||
if (currentUserPrincipal != null && currentUserPrincipal.href != null)
|
|
||||||
principal = davBase.location.resolve(currentUserPrincipal.href);
|
|
||||||
|
|
||||||
// check for resourcetype = principal
|
|
||||||
if (principal == null) {
|
|
||||||
ResourceType resourceType = (ResourceType)davBase.properties.get(ResourceType.NAME);
|
|
||||||
if (resourceType.types.contains(ResourceType.PRINCIPAL))
|
|
||||||
principal = davBase.location;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a principal has been detected successfully, ensure that it provides the required service.
|
|
||||||
if (principal != null && !providesService(principal, service))
|
|
||||||
principal = null;
|
|
||||||
|
|
||||||
} catch (IOException|HttpException|DavException e) {
|
|
||||||
log.debug("PROPFIND on user-given URL failed", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1b: Try well-known URL, too
|
|
||||||
if (principal == null)
|
|
||||||
try {
|
try {
|
||||||
principal = getCurrentUserPrincipal(baseURL.resolve("/.well-known/" + service.name), service);
|
config.principal = getCurrentUserPrincipal(baseURL.resolve("/.well-known/" + service.name), service);
|
||||||
} catch (IOException|HttpException|DavException e) {
|
} catch (IOException|HttpException|DavException e) {
|
||||||
log.debug("Well-known URL detection failed", e);
|
log.debug("Well-known URL detection failed", e);
|
||||||
}
|
}
|
||||||
@ -170,36 +120,85 @@ public class DavResourceFinder {
|
|||||||
|
|
||||||
int posAt = mailbox.lastIndexOf("@");
|
int posAt = mailbox.lastIndexOf("@");
|
||||||
if (posAt != -1)
|
if (posAt != -1)
|
||||||
domain = mailbox.substring(posAt + 1);
|
discoveryFQDN = mailbox.substring(posAt + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: If user-given URL didn't reveal a principal, search for it: SERVICE DISCOVERY
|
// Step 2: If user-given URL didn't reveal a principal, search for it: SERVICE DISCOVERY
|
||||||
if (principal == null && domain != null) {
|
if (config.principal == null && discoveryFQDN != null) {
|
||||||
log.info("No principal found at user-given URL, trying to discover");
|
log.info("No principal found at user-given URL, trying to discover");
|
||||||
try {
|
try {
|
||||||
principal = discoverPrincipalUrl(domain, service);
|
config.principal = discoverPrincipalUrl(discoveryFQDN, service);
|
||||||
} catch (IOException|HttpException|DavException e) {
|
} catch (IOException|HttpException|DavException e) {
|
||||||
log.debug(service.name + " service discovery failed", e);
|
log.debug(service.name + " service discovery failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service == Service.CALDAV)
|
return config;
|
||||||
caldavPrincipal = principal;
|
|
||||||
else if (service == Service.CARDDAV)
|
|
||||||
carddavPrincipal = principal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addIfAddressBook(@NonNull DavResource dav) {
|
protected void checkUserGivenURL(@NonNull HttpUrl baseURL, @NonNull Service service, @NonNull Configuration.ServiceInfo config) {
|
||||||
|
log.info("Checking user-given URL: " + baseURL.toString());
|
||||||
|
|
||||||
|
HttpUrl principal = null;
|
||||||
|
try {
|
||||||
|
DavResource davBase = new DavResource(log, httpClient, baseURL);
|
||||||
|
|
||||||
|
if (service == Service.CARDDAV) {
|
||||||
|
davBase.propfind(0,
|
||||||
|
ResourceType.NAME, DisplayName.NAME, AddressbookDescription.NAME,
|
||||||
|
AddressbookHomeSet.NAME,
|
||||||
|
CurrentUserPrincipal.NAME
|
||||||
|
);
|
||||||
|
rememberIfAddressBookOrHomeset(davBase, config);
|
||||||
|
|
||||||
|
} else if (service == Service.CALDAV) {
|
||||||
|
davBase.propfind(0,
|
||||||
|
ResourceType.NAME, DisplayName.NAME, CalendarColor.NAME, CalendarDescription.NAME, CalendarTimezone.NAME, CurrentUserPrivilegeSet.NAME, SupportedCalendarComponentSet.NAME,
|
||||||
|
CalendarHomeSet.NAME,
|
||||||
|
CurrentUserPrincipal.NAME
|
||||||
|
);
|
||||||
|
rememberIfCalendarOrHomeset(davBase, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for current-user-principal
|
||||||
|
CurrentUserPrincipal currentUserPrincipal = (CurrentUserPrincipal)davBase.properties.get(CurrentUserPrincipal.NAME);
|
||||||
|
if (currentUserPrincipal != null && currentUserPrincipal.href != null)
|
||||||
|
principal = davBase.location.resolve(currentUserPrincipal.href);
|
||||||
|
|
||||||
|
// check for resource type "principal"
|
||||||
|
if (principal == null) {
|
||||||
|
ResourceType resourceType = (ResourceType)davBase.properties.get(ResourceType.NAME);
|
||||||
|
if (resourceType.types.contains(ResourceType.PRINCIPAL))
|
||||||
|
principal = davBase.location;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a principal has been detected successfully, ensure that it provides the required service.
|
||||||
|
if (principal != null && providesService(principal, service))
|
||||||
|
config.principal = principal;
|
||||||
|
|
||||||
|
} catch (IOException|HttpException|DavException e) {
|
||||||
|
log.debug("PROPFIND/OPTIONS on user-given URL failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void rememberIfAddressBookOrHomeset(@NonNull DavResource dav, @NonNull Configuration.ServiceInfo config) {
|
||||||
|
// Is the collection an address book?
|
||||||
ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
|
ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
|
||||||
if (resourceType != null && resourceType.types.contains(ResourceType.ADDRESSBOOK)) {
|
if (resourceType != null && resourceType.types.contains(ResourceType.ADDRESSBOOK)) {
|
||||||
dav.location = UrlUtils.withTrailingSlash(dav.location);
|
dav.location = UrlUtils.withTrailingSlash(dav.location);
|
||||||
log.info("Found address book at " + dav.location);
|
log.info("Found address book at " + dav.location);
|
||||||
|
config.collections.put(dav.location, collectionInfo(dav, Configuration.Collection.Type.ADDRESS_BOOK));
|
||||||
addressBooks.put(dav.location, collectionInfo(dav, ServerConfiguration.Collection.Type.ADDRESS_BOOK));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does the collection refer to address book homesets?
|
||||||
|
AddressbookHomeSet homeSets = (AddressbookHomeSet)dav.properties.get(AddressbookHomeSet.NAME);
|
||||||
|
if (homeSets != null)
|
||||||
|
for (String href : homeSets.hrefs)
|
||||||
|
config.homeSets.add(dav.location.resolve(href));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addIfCalendar(@NonNull DavResource dav) {
|
protected void rememberIfCalendarOrHomeset(@NonNull DavResource dav, @NonNull Configuration.ServiceInfo config) {
|
||||||
|
// Is the collection a calendar collection?
|
||||||
ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
|
ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
|
||||||
if (resourceType != null && resourceType.types.contains(ResourceType.CALENDAR)) {
|
if (resourceType != null && resourceType.types.contains(ResourceType.CALENDAR)) {
|
||||||
dav.location = UrlUtils.withTrailingSlash(dav.location);
|
dav.location = UrlUtils.withTrailingSlash(dav.location);
|
||||||
@ -212,16 +211,22 @@ public class DavResourceFinder {
|
|||||||
supportsTasks = supportedCalendarComponentSet.supportsTasks;
|
supportsTasks = supportedCalendarComponentSet.supportsTasks;
|
||||||
}
|
}
|
||||||
if (supportsEvents || supportsTasks) {
|
if (supportsEvents || supportsTasks) {
|
||||||
ServerConfiguration.Collection info = collectionInfo(dav, ServerConfiguration.Collection.Type.CALENDAR);
|
Configuration.Collection info = collectionInfo(dav, Configuration.Collection.Type.CALENDAR);
|
||||||
info.supportsEvents = supportsEvents;
|
info.supportsEvents = supportsEvents;
|
||||||
info.supportsTasks = supportsTasks;
|
info.supportsTasks = supportsTasks;
|
||||||
calendars.put(dav.location, info);
|
config.collections.put(dav.location, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does the collection refer to calendar homesets?
|
||||||
|
CalendarHomeSet homeSets = (CalendarHomeSet)dav.properties.get(CalendarHomeSet.NAME);
|
||||||
|
if (homeSets != null)
|
||||||
|
for (String href : homeSets.hrefs)
|
||||||
|
config.homeSets.add(dav.location.resolve(href));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a #{@link at.bitfire.davdroid.resource.ServerInfo.ResourceInfo} from a given
|
* Builds a #{@link at.bitfire.davdroid.resource.DavResourceFinder.Configuration.Collection} from a given
|
||||||
* #{@link DavResource}. Uses these DAV properties:
|
* #{@link DavResource}. Uses these DAV properties:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>calendars: current-user-properties, current-user-privilege-set, displayname, calendar-description, calendar-color</li>
|
* <li>calendars: current-user-properties, current-user-privilege-set, displayname, calendar-description, calendar-color</li>
|
||||||
@ -231,7 +236,7 @@ public class DavResourceFinder {
|
|||||||
* @param type must be ADDRESS_BOOK or CALENDAR
|
* @param type must be ADDRESS_BOOK or CALENDAR
|
||||||
* @return ResourceInfo which represents the DavResource
|
* @return ResourceInfo which represents the DavResource
|
||||||
*/
|
*/
|
||||||
protected ServerConfiguration.Collection collectionInfo(DavResource dav, ServerConfiguration.Collection.Type type) {
|
protected Configuration.Collection collectionInfo(DavResource dav, Configuration.Collection.Type type) {
|
||||||
boolean readOnly = false;
|
boolean readOnly = false;
|
||||||
CurrentUserPrivilegeSet privilegeSet = (CurrentUserPrivilegeSet)dav.properties.get(CurrentUserPrivilegeSet.NAME);
|
CurrentUserPrivilegeSet privilegeSet = (CurrentUserPrivilegeSet)dav.properties.get(CurrentUserPrivilegeSet.NAME);
|
||||||
if (privilegeSet != null)
|
if (privilegeSet != null)
|
||||||
@ -246,11 +251,11 @@ public class DavResourceFinder {
|
|||||||
|
|
||||||
String description = null;
|
String description = null;
|
||||||
Integer color = null;
|
Integer color = null;
|
||||||
if (type == ServerConfiguration.Collection.Type.ADDRESS_BOOK) {
|
if (type == Configuration.Collection.Type.ADDRESS_BOOK) {
|
||||||
AddressbookDescription addressbookDescription = (AddressbookDescription)dav.properties.get(AddressbookDescription.NAME);
|
AddressbookDescription addressbookDescription = (AddressbookDescription)dav.properties.get(AddressbookDescription.NAME);
|
||||||
if (addressbookDescription != null)
|
if (addressbookDescription != null)
|
||||||
description = addressbookDescription.description;
|
description = addressbookDescription.description;
|
||||||
} else if (type == ServerConfiguration.Collection.Type.CALENDAR) {
|
} else if (type == Configuration.Collection.Type.CALENDAR) {
|
||||||
CalendarDescription calendarDescription = (CalendarDescription)dav.properties.get(CalendarDescription.NAME);
|
CalendarDescription calendarDescription = (CalendarDescription)dav.properties.get(CalendarDescription.NAME);
|
||||||
if (calendarDescription != null)
|
if (calendarDescription != null)
|
||||||
description = calendarDescription.description;
|
description = calendarDescription.description;
|
||||||
@ -260,10 +265,9 @@ public class DavResourceFinder {
|
|||||||
color = calendarColor.color;
|
color = calendarColor.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerConfiguration.Collection collection = new ServerConfiguration.Collection(
|
Configuration.Collection collection = new Configuration.Collection(
|
||||||
type,
|
type,
|
||||||
readOnly,
|
readOnly,
|
||||||
UrlUtils.withTrailingSlash(dav.location).toString(),
|
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
color
|
color
|
||||||
@ -273,7 +277,7 @@ public class DavResourceFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean providesService(HttpUrl url, Service service) {
|
boolean providesService(HttpUrl url, Service service) throws IOException {
|
||||||
DavResource davPrincipal = new DavResource(log, httpClient, url);
|
DavResource davPrincipal = new DavResource(log, httpClient, url);
|
||||||
try {
|
try {
|
||||||
davPrincipal.options();
|
davPrincipal.options();
|
||||||
@ -282,7 +286,7 @@ public class DavResourceFinder {
|
|||||||
(service == Service.CALDAV && davPrincipal.capabilities.contains("calendar-access")))
|
(service == Service.CALDAV && davPrincipal.capabilities.contains("calendar-access")))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (IOException|HttpException|DavException e) {
|
} catch (HttpException|DavException e) {
|
||||||
log.error("Couldn't detect services on {}", url);
|
log.error("Couldn't detect services on {}", url);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -399,19 +403,28 @@ public class DavResourceFinder {
|
|||||||
|
|
||||||
// data classes
|
// data classes
|
||||||
|
|
||||||
@Data
|
@RequiredArgsConstructor
|
||||||
@ToString(exclude="logs")
|
@ToString(exclude="logs")
|
||||||
public static class ServerConfiguration {
|
public static class Configuration {
|
||||||
final public HttpUrl cardDavPrincipal;
|
|
||||||
final public Collection[] addressBooks;
|
|
||||||
|
|
||||||
final public HttpUrl calDavPrincipal;
|
public final ServiceInfo cardDAV;
|
||||||
final public Collection[] calendars;
|
public final ServiceInfo calDAV;
|
||||||
|
|
||||||
final String logs;
|
public final String logs;
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
public static class ServiceInfo {
|
||||||
|
@Getter
|
||||||
|
HttpUrl principal;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
Set<HttpUrl> homeSets = new HashSet<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
Map<HttpUrl, Collection> collections = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ToString
|
|
||||||
public static class Collection {
|
public static class Collection {
|
||||||
public enum Type {
|
public enum Type {
|
||||||
ADDRESS_BOOK,
|
ADDRESS_BOOK,
|
||||||
@ -421,9 +434,7 @@ public class DavResourceFinder {
|
|||||||
final Type type;
|
final Type type;
|
||||||
final boolean readOnly;
|
final boolean readOnly;
|
||||||
|
|
||||||
final String url, // absolute URL of resource
|
final String title, description;
|
||||||
title,
|
|
||||||
description;
|
|
||||||
final Integer color;
|
final Integer color;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,10 +24,10 @@ import java.io.StringReader;
|
|||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.resource.DavResourceFinder;
|
import at.bitfire.davdroid.resource.DavResourceFinder;
|
||||||
import at.bitfire.davdroid.resource.DavResourceFinder.ServerConfiguration;
|
import at.bitfire.davdroid.resource.DavResourceFinder.Configuration;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
|
|
||||||
public class DetectConfigurationFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<ServerConfiguration> {
|
public class DetectConfigurationFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Configuration> {
|
||||||
|
|
||||||
static final String ARG_LOGIN_CREDENTIALS = "credentials";
|
static final String ARG_LOGIN_CREDENTIALS = "credentials";
|
||||||
|
|
||||||
@ -51,23 +51,23 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<ServerConfiguration> onCreateLoader(int id, Bundle args) {
|
public Loader<Configuration> onCreateLoader(int id, Bundle args) {
|
||||||
return new ServerConfigurationLoader(getContext(), args);
|
return new ServerConfigurationLoader(getContext(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<ServerConfiguration> loader, ServerConfiguration data) {
|
public void onLoadFinished(Loader<Configuration> loader, Configuration data) {
|
||||||
// show error / continue with next fragment
|
// show error / continue with next fragment
|
||||||
Constants.log.info("detection results: {}", data);
|
Constants.log.info("detection results: {}", data);
|
||||||
dismissAllowingStateLoss();
|
dismissAllowingStateLoss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<ServerConfiguration> loader) {
|
public void onLoaderReset(Loader<Configuration> loader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static class ServerConfigurationLoader extends AsyncTaskLoader<ServerConfiguration> {
|
static class ServerConfigurationLoader extends AsyncTaskLoader<Configuration> {
|
||||||
final Context context;
|
final Context context;
|
||||||
final LoginCredentialsFragment.LoginCredentials credentials;
|
final LoginCredentialsFragment.LoginCredentials credentials;
|
||||||
|
|
||||||
@ -83,16 +83,16 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerConfiguration loadInBackground() {
|
public Configuration loadInBackground() {
|
||||||
DavResourceFinder finder = new DavResourceFinder(context, credentials);
|
DavResourceFinder finder = new DavResourceFinder(context, credentials);
|
||||||
ServerConfiguration configuration = finder.findInitialConfiguration();
|
Configuration configuration = finder.findInitialConfiguration();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@Cleanup BufferedReader logStream = new BufferedReader(new StringReader(configuration.getLogs()));
|
@Cleanup BufferedReader logStream = new BufferedReader(new StringReader(configuration.logs));
|
||||||
Constants.log.info("Successful resource detection:");
|
Constants.log.info("Resource detection finished:");
|
||||||
String line;
|
String line;
|
||||||
while ((line = logStream.readLine()) != null)
|
while ((line = logStream.readLine()) != null)
|
||||||
Constants.log.debug(line);
|
Constants.log.info(line);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.log.error("Couldn't read resource detection logs", e);
|
Constants.log.error("Couldn't read resource detection logs", e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user