Commit Graph

6131 Commits

Author SHA1 Message Date
Patrick Ohly d6a3ab3209 autotools, NEWS: SyncEvolution 1.4.99.4 2014-09-12 11:38:57 +02:00
Patrick Ohly 79f98f3df9 testing: ignore Memotoo eds_memo failure
When sent
  SUMMARY:Simple
  DESCRIPTION:Simple
Memotoo returns
  SUMMARY:Simple
  DESCRIPTION:Simple\nSimple

Remove this particular test case until the problem in the server
is fixed.
2014-09-12 11:38:57 +02:00
Patrick Ohly b26f49eaa3 oauth2: refresh token -> oauth2
That the backend is based on a refresh token is an implementation
detail; it might even change at some point if we figure out how
to do OAuth2 internally.

Better use the shorter "oauth2" name in the "username" property.

Also better align .so name and global variable names/defines in
configure and Makefile with the name of the backend.
2014-09-12 11:38:57 +02:00
Patrick Ohly be846f8e60 oauth2: handle errors during password update
There is no guarantee that the password can be updated. Allow the attempt
to fail without treating it as an error (that would be confusing in the most
common case, where "password" was given on the command line) and instead
just print an INFO message with the new token and some instructions.
2014-09-12 11:38:57 +02:00
Patrick Ohly 64fb7212cf oauth2: use simpler username syntax
All the values in the username hash are strings. This is unlikely to
change and if it does, we can always do some string-to-value
conversion in our own code. Therefore use the simpler syntax without
the angle brackets marking a variant value.

Simplifies our C++ code, too, and now also compiles on Ubuntu Trusty
(which doesn't have a recent enough glib for G_VARIANT_TYPE_VARDICT).
2014-09-12 11:38:57 +02:00
Patrick Ohly efca1250fd GVariant: also support conversion to simpler string hash
Extracting actual values from a hash with GVariant as value is more
work than reading string values directly. For cases where only strings
may occur as values, the simpler string hash is therefore prefered.
2014-09-12 11:38:57 +02:00
Patrick Ohly a6079c376e oauth2: README update
Avoid the term HMI because it is only used in certain communities.

Make the example username work for CalDAV and CardDAV and base it on
GOA, because that's what most users will have installed.
2014-09-12 11:38:57 +02:00
Patrick Ohly bfc60f1784 oauth2: support json.pc and json-c.pc
The only difference is the name of the module and the path to json.h,
which can be found as just json.h when using the -I statements from
the .pc files.
2014-09-12 11:38:57 +02:00
Mateusz Polrola 00ff3abbc7 oauth2: new backend using libsoup/libcurl
New backend implements identity provider for obtaining OAuth2 access
token for systems without HMI support.
Access token is obtained by making direct HTTP request to OAuth2 server
and using refresh token obtained by user in some other way.
New provider automatically updates stored refresh token when OAuth2
server is issuing new one.
2014-09-12 11:38:57 +02:00
Patrick Ohly 6298afabcb SoupTransport: avoid uninitialized memory read
Don't depend on setSSL() to initialize the instance, because when used
as part of the upcoming oauth2 backend, setSSL() is never called.
2014-09-12 11:38:56 +02:00
Patrick Ohly f5ae660c70 SoupTransport: drop CA file check
It used to be necessary to specify a CA file for libsoup to enable SSL
certificate checking. Nowadays libsoup uses the default CA store
unless told otherwise, so the check in SyncEvolution became
obsolete. However, now there is a certain risk that no SSL checking is
done although the user asked for it (when libsoup is not recent enough
or compiled correctly).
2014-09-12 11:38:56 +02:00
Mateusz Polrola b747a8c2e4 identity: allow using and updating the "password" property
So far, only the "username" property was used once identity providers
were involved. The upcoming oauth2 provider uses the "password"
property for the refresh token and needs the ability to store a new
token if the OAuth2 server updates it.

Setting the new value will not always be possible (for example,
when running a command line operation where all properties were
provided on the command line without a permanent config). This still
needs to be handled.
2014-09-12 11:38:56 +02:00
Patrick Ohly f2b2ea4271 GVariant: move common code into libsyncevolution
The same code will also be needed by the upcoming oauth2 backend.  The
header file depends on glib, so don't install it as a public header
file of libsyncevolution (i.e. only allow using it internally).

The original signon code used a custom GVariant auto_ptr because it
needed the simple assignment semantic of "transfers ownership". Now
that the GVariantCXX class is in a shared header file, better make it
identical to the other CXX classes (i.e., a shared pointer). Avoid
returning plain pointers because ownership of those cannot be checked
by the compiler.

The signon case can be handled with GVariantStealCXX, which by default
takes ownership in the constructor and the default assignment
operator.
2014-09-12 11:38:56 +02:00
Patrick Ohly a2e990e51f PBAP: use raw text items
This avoids the redundant parse/generate step on the sending
side of the PBAP sync.
2014-09-12 11:38:50 +02:00
Patrick Ohly 626e027d3d datatypes: raw text items with minimal conversion (FDO #52791)
When using "raw/text/calendar" or "raw/text/vcard" as SyncEvolution
"databaseFormat", all parsing and conversion is skipped. The backend's
data is identical to the item data in the engine. Finding duplicates
in a slow sync is very limited when using these types because the entire
item data must match exactly.

This is useful for the file backend when the goal is to store an exact copy
of what a peer has or for limited, read-only backends (PBAP).

The implementation uses the "raw" base type which does nothing but storing
the item content verbatim. That type requires a field named "ITEMDATA". After
renaming the variable used by our MAKETEXTWITHPROFILE/PARSETEXTWITHPROFILE
with other, more complex types, all we have to do is skip this conversion
by not providing a profile name.
In a refresh-from-remote local sync of 1000 contacts with photo data
using the file backend, this reduces the number of CPU cycles from
2861476184 to 1840952543 on the server side.
2014-09-12 11:38:40 +02:00
Patrick Ohly f994f1efb2 SyncSource: flush map items less frequently
The Synthesis API does not say explicitly, but in practice all map
items get updated in a tight loop. Rewriting the m_mappingNode (case
insensitive string comparisons) and serialization to disk
(std::ostrstream) consume a significant amount of CPU cycles and cause
extra disk writes.

It is better to allow changes to be cached in memory instead and only
flush to disk at the end. There is no explicit flush API, so we use
SaveAdminData as trigger for flushing instead.

In a refresh-from-remote local sync of 1000 contacts with photo data
using the file backend, this reduces the number of CPU cycles from
4138538276 to 2861476184 (measured with callgrind on x86_64).
2014-09-10 14:19:22 +02:00
Patrick Ohly e60e0d0955 local sync: exchange SyncML messages via shared memory
Encoding/decoding of the uint8_t array in D-Bus took a surprisingly
large amount of CPU cycles relative to the rest of the SyncML message
processing. Now the actual data resides in memory-mapped temporary
files and the D-Bus messages only contain offset and size inside these
files. Both sides use memory mapping to read and write directly.

For caching 1000 contacts with photos on a fast laptop, total sync
time roughly drops from 6s to 3s.

To eliminate memory copies, memory handling in libsynthesis or rather,
libsmltk is tweaked such that it allocates the buffer used for SyncML
message data in the shared memory buffer directly. This relies on
knowledge of libsmltk internals, but those shouldn't change and if they
do, SyncEvolution will notice ("unexpected send buffer").
2014-09-10 12:06:53 +02:00
Patrick Ohly 345a58abe4 config: sanitize maxMsgSize and maxObjSize while reading from config
Unusually small values were ignored during syncing. Doing this in the config
access methods instead of the sync session setup ensures that all components
in SyncEvolution use the same value.
2014-09-10 12:06:53 +02:00
Patrick Ohly 9ea6379f98 GDBus libdbus: add 64 and double
These types were already added for GDBus on GIO. 64 bit unsigned
will be needed for transmitting size_t during local sync.
2014-09-10 12:06:53 +02:00
Patrick Ohly b4b611002c TmpFile: support IPC via shared memory mapping
For this to work, the memory must be mapped MAP_SHARED (otherwise
writes are not visible outside of the process) and the recipient
of a file descriptor must be able to create a TmpFile for it, which
then can be used to create a memory mapping.
2014-09-10 12:06:53 +02:00
Patrick Ohly 85b570e5db testing: cover disk write avoidance
During TestCmdline.testSyncOutput also verify that syncs which don't
change the database also don't update the ~/.config meta data.

The listall() method from testpim.py is used and extended for that
and therefore moved to test-dbus.py.
2014-09-10 12:06:53 +02:00
Patrick Ohly 8dca19a6cf local sync: avoid updating meta data when nothing changed
The sync meta data (sync anchors, client change log) get updated after
a sync even if nothing changed and the existing meta data could be
used again. This can be skipped for local sync, because then
SyncEvolution can ensure that both sides skip updating the meta
data. With a remote SyncML server that is not possible and thus
SyncEvolution has to update its data.

This optimization is only used for local syncs with one source.  It is
based on the observation that when the server side calls
SaveAdminData, the client has sent its last message and the sync is
complete. At that point, SyncEvolution can check whether anything has
changed and if not, skip saving the server's admin data and stop the
sync without sending the real reply to the client.

Instead the client gets an empty message with "quitsync" as content
type. Then it takes shortcuts to close down without finalizing the
sync engine, because that would trigger writing of meta data
changes. The server continues its shutdown normally.

This optimization is limited to syncs with a single source, because
the assumption about when aborting is possible is harder to verify
when multiple sources are involved.
2014-09-10 12:06:53 +02:00
Patrick Ohly b985da7011 TrackingSyncSource: avoid .ini write when nothing changes
During syncs where nothing changes, reseting the database revision and
setting it again at the end of the sync causes undesirable disk
writes. To avoid that, reset the database revision the first time an
item change is done.
2014-09-10 12:06:53 +02:00
Patrick Ohly 72b4a8b167 IniConfigNode: avoid writing unmodified data
Sometimes the new content of the file is exactly the same as the old
one, for example when the tracking node gets reset and
recreated. Detect that for all cases at the lower level by reading the
existing file first and comparing it against the new content.
2014-09-10 12:06:53 +02:00
Patrick Ohly 7b8a173d2d SyncContext: fix session cleanup
Synthesis cleanup was supposed to happen between "closing session" and
"session closed" log messages. Because we kept additional references
to the session, this only happened later. Need to drop also references
to shared buffers, because those hold a reference to their session.
2014-09-10 12:06:52 +02:00
Patrick Ohly 2d5c60f644 SyncSource: add operation signal handler return code
This allows signal handlers to affect the operation execution and
result without having to throw an exception, which would get logged as
error and is not desirable when the operation gets skipped
intentionally. Needed for skipping SaveAdminData in the next patch.
2014-09-10 12:06:52 +02:00
Patrick Ohly a9f265971b engine: avoid flipping configdate
The engine gets instantiated twice: once for logging, once for
syncing. The config generated in each case is different because
sources only become active for syncing. Therefore the config change
check unnecessarily triggered during each sync (first getConfigXML
call created one hash, then the second another), causing DevInf to be
sent unnecessarily and always rewriting the .ini file.

The check is only needed when instantiating the engine that is getting
used for syncing. However, the config date must always be valid.
2014-09-10 12:06:31 +02:00
Patrick Ohly 9581b682a4 PIM: include CardDAV in CreatePeer()
This adds "protocol: CardDAV" as a valid value, with corresponding
changes to the interpretation of some existing properties and some new
ones. The API itself is not changed.

Suspending a CardDAV sync is possible. This freezes the internal
SyncML message exchange, so data exchange with the CardDAV server may
continue for a while after SuspendPeer().

Photo data is always downloaded immediately. The "pbap-sync" flag
in SyncPeerWithFlags() has no effect.

Syncing can be configured to be one-way (local side is read-only
cache) or two-way (local side is read/write). Meta data must be
written either way, to speed up caching or allow two-way syncing. The
most common case (no changes on either side) will have to be optimized
such that existing meta data is not touched and thus no disk writes
occur.
2014-09-08 11:07:31 +02:00
Patrick Ohly 07292559b7 PIM: handle SuspendPeer() before and after transfer (FDO #82863)
A SuspendPeer() only succeeded while the underlying Bluetooth transfer
was active. Outside of that, Bluez errors caused SyncEvolution to
attempt a cancelation of the transfer and stopped the sync.

When the transfer was still queueing, obexd returns
org.bluez.obex.Error.NotInProgress. This is difficult to handle for
SyncEvolution: it cannot prevent the transfer from starting and has to
let it become active before it can suspend the transfer. Canceling
would lead to difficult to handle error cases (like partially parsed
data) and therefore is not done.

The Bluez team was asked to implement suspending of queued transfers
(see "org.bluez.obex.Transfer1 Suspend/Resume in queued state" on
linux-bluetooth@vger.kernel.org), so this case might not happen
anymore with future Bluez.

When the transfer completes before obexd processes the Suspend(),
org.freedesktop.DBus.Error.UnknownObject gets returned by
obexd. SyncEvolution can ignore errors which occur after the active
transfer completed. In addition, it should prevent starting the next
one. This may be relevant for transfer in chunks, although the sync
engine will also stop asking for data and thus typically no new
transfer gets triggered anyway.
2014-09-08 11:07:31 +02:00
Patrick Ohly 81ea67f74a PIM: fix potential segfault during shutdown
When syncevo-dbus-server was shutting down due to a signal and there
was a sync session running that was triggered via the PIM Manager API,
then a segfault occurred because the manager instance got destroyed
before invoking a Session callback holding a pointer to it.

The fix is to use slot tracking of the weak pointer.
2014-09-08 11:07:31 +02:00
Patrick Ohly b02b83bce0 PIM: add suspend/resume/abort to sync.py
CTRL-C while waiting for the end of a sync causes an interactive
prompt to appear where one can choose been suspend/resume/abort and
continuing to wait. CTRL-C again in the prompt aborts the script.
2014-09-08 11:07:31 +02:00
Patrick Ohly eaf66412d9 PIM: fix sync.py --sync-flags
The help text used single quotes for the JSON example instead of
the required double quotes. Running without --sync-flags was broken
because of trying to parse the empty string as JSON.
2014-09-08 11:07:31 +02:00
Patrick Ohly dec741ea50 VirtualSyncSource, MapSyncSource: implement m_isEmpty
This is relevant for isUsable() and not so much (not at all?) for
slow sync prevention.
2014-09-08 11:07:31 +02:00
Patrick Ohly 8ac69096e8 command line: revise usability checking of datastores
When configuring a new sync config, the command line checks whether a
datastore is usable before enabling it. If no datastores were listed
explicitly, only the usable ones get enabled. If unusable datastores
were explicitly listed, the entire configure operation fails.

This check was based on listing databases, which turned out to be too
unspecific for the WebDAV backend: when "database" was set to some URL
which is good enough to list databases, but not a database URL itself,
the sources where configured with that bad URL.

Now a new SyncSource::isUsable() operation is used, which by default
just falls back to calling the existing Operations::m_isEmpty. In
practice, all sources either check their config in open() or the
m_isEmpty operation, so the source is usable if no error is
enountered.

For WebDAV, the usability check is skipped because it would require
contacting a remote server, which is both confusing (why does a local
configure operation need the server?) and could fail even for valid
configs (server temporarily down). The check was incomplete anyway
because listing databases gave a fixed help text response when no
credentials were given. For usability checking that should have
resulted in "not usable" and didn't.

The output during the check was confusing: it always said "listing
databases" without giving a reason why that was done. The intention
was to give some feedback while a potentially expensive operation
ran. Now the isUsable() method itself prints "checking usability" if
(and only if!) such a check is really done.

Sometimes datastores were checked even when they were about to be
configure as "disabled" already. Now checking such datastores is
skipped.
2014-09-08 11:07:31 +02:00
Patrick Ohly 045bf7aa5b D-Bus server: preserve log prefix
The log prefix seems to be unused (except for some debug message) at
the moment but will be soon, so make sure it gets embedded in the
string sent to the syncevo-dbus-server.
2014-09-08 11:07:31 +02:00
Patrick Ohly ff35aa5ace testing: include prefix in TestCmdline tests
Will become relevant with the next commit, which moves the
source name from being part of the text into the prefix. So far,
the prefix is unused during Cmdline tests.
2014-09-08 11:07:31 +02:00
Patrick Ohly e06d39b5bd InactiveSyncSource: simpler implementation
When deriving from DummySyncSource we need to implement less
pure virtual functions. Only the ones where the behavior
needs to differ from DummySyncSource are needed.
2014-09-08 11:07:31 +02:00
Patrick Ohly 6770237424 EDS: memo syncing as iCalendar 2.0 (FDO #52714)
When syncing memos with a peer which also supports iCalendar 2.0 as
data format, the engine will now pick iCalendar 2.0 instead of
converting to/from plain text. The advantage is that some additional
properties like start date and categories can also be synchronized.

The code is a lot simpler, too, because the EDS specific iCalendar 2.0
<-> text conversion code can be removed.
2014-09-08 11:07:31 +02:00
Patrick Ohly adf2522ad1 datatypes: text/calendar+plain revised heuristic, II
When sending a VEVENT, DESCRIPTION was set to the SUMMARY if empty. This may
have been necessary for some peers, but for notes (= VJOURNAL) we don't know
that (hasn't been used in the past) and don't want to alter the item
unnecessarily, so skip that part and allow empty DESCRIPTION.
2014-09-08 11:07:31 +02:00
Patrick Ohly 3392cbf267 datatypes: text/calendar+plain revised heuristic
When receiving a plain text note, the "text/calendar+plain" type
used to store the first line as summary and the rest as description.
This may be correct in some cases and wrong in others.

The EDS backend implemented a different heuristic: there the first
line is copied into the summary and stays in the description. This
makes a bit more sense (the description alone is always enough to
understand the note). Therefore and to avoid behavioral changes
for EDS users when switching the EDS backend to use text/calendar+plain,
the engine now uses the same approach.

For this to work in all cases, the datatype must always call
MEMO_INCOMING_SCRIPT.
2014-07-31 20:20:34 +02:00
Patrick Ohly 04f11b422e source -> datastore rename, improved terminology
The word "source" implies reading, while in fact access is read/write.
"datastore" avoids that misconception. Writing it in one word emphasizes
that it is single entity.

While renaming, also remove references to explicit --*-property
parameters. The only necessary use today is "--sync-property ?"
and "--datastore-property ?".

--datastore-property was used instead of the short --store-property
because "store" might be mistaken for the verb. It doesn't matter
that it is longer because it doesn't get typed often.

--source-property must remain valid for backward compatility.

As many user-visible instances of "source" as possible got replaced in
text strings by the newer term "datastore". Debug messages were left
unchanged unless some regex happened to match it.

The source code will continue to use the old variable and class names
based on "source".

Various documentation enhancements:
  Better explain what local sync is and how it involves two sync
  configs. "originating config" gets introduces instead of just
  "sync config".

  Better explain the relationship between contexts, sync configs,
  and source configs ("a sync config can use the datastore configs in
  the same context").

  An entire section on config properties in the terminology
  section. "item" added (Todd Wilson correctly pointed out that it was
  missing).

  Less focus on conflict resolution, as suggested by Graham Cobb.

  Fix examples that became invalid when fixing the password
  storage/lookup mechanism for GNOME keyring in 1.4.

  The "command line conventions", "Synchronization beyond SyncML" and
  "CalDAV and CardDAV" sections were updated. It's possible that the
  other sections also contain slightly incorrect usage of the
  terminology or are simply out-dated.
2014-07-28 15:29:41 +02:00
Patrick Ohly 581cee897e Google: remove SyncML template, combine CalDAV/CardDAV
Google has turned off their SyncML server, so the corresponding
"Google Contacts" template became useless and needs to be removed. It
gets replaced by a "Google" template which combines the three
different URLs currently used by Google for CalDAV/CardDAV.

This new template can be used to configure a "target-config@google"
with default calendar and address book database already enabled. The
actual URL of these databases will be determined during the first
sync using them.

The template relies on the WebDAV backend's new capability to search
multiple different entries in the syncURL property for databases. To
avoid listing each calendar twice (once for the legacy URL, once with
the new one) when using basic username/password authentication, the
backend needs a special case for Google and detect that the legacy URL
does not need to be checked.
2014-07-28 15:24:46 +02:00
Patrick Ohly 74143960b9 WebDAV: support multiple URLs in syncURL
The syncURL property may contain multiple different space or tab
separated URLs. Previously, the WebDAV backend only used the first one
when scanning for databases. Now it tries all of them.

This will be useful for configuring all Google endpoints in one
template.
2014-07-28 15:24:46 +02:00
Patrick Ohly cab4d0a98d WebDAV: avoid DNS SRV retry loop for aliases
Certains domains (like googleapis.com) are aliases. The lookup tools
do not fail with NXDOMAIN in this case, causing the
syncevo-webdav-lookup script to return only an unknown lookup error,
in which case the WebDAV backend will retry for a while.

We need to detect aliases resp. missing SRV information and return a
"no information error".
2014-07-28 15:24:46 +02:00
Patrick Ohly 2371f69f97 PIM testing: remove asyncError test
The asyncError relied on calling
folks_individual_aggregator_remove_individual() incorrectly
with a NULL pointer. folks in Debian Testing just crashes
now, so we can no longer do this.
2014-07-25 14:23:30 +02:00
Patrick Ohly 8c6f770e38 local sync: allow config name in syncURL=local://
Previously, only syncURL=local://@<context name> was allowed and used
the "target-config@context name" config as target side in the local
sync.

Now "local://config-name@context-name" or simply "local://config-name"
are also allowed. "target-config" is still the fallback if only a
context is give.

It also has one more special meaning: "--configure
target-config@google-calendar" will pick the "Google_Calendar"
template automatically because it knows that the intention is to
configure the target side of a local sync. It does not know that when
using some other name for the config, in which case the template (if
needed) must be specified explicitly.

The process name in output from the target side now also includes the
configuration name if it is not the default "target-config".
2014-07-25 03:01:52 -07:00
Patrick Ohly 5ab328af07 D-Bus testing: fix race condition in TestLocalSync.testNoParent
The first progress signal gets emitted after sleeping for 10 seconds
at the start of the sync and then killing syncevo-dbus-server races
with completing the sync. What we want is to kill during the 10 second
wait, so we better wait for the debug output directly before it and
then kill directly.
2014-07-24 15:39:52 +02:00
Patrick Ohly 57f44fe607 config: allow storing credentials for email address
When configuring a WebDAV server with username = email address and no
URL (which is possible if the server supports service discovery via
the domain in the email address), then storing the credentials in the
GNOME keyring used to fail with "cannot store password in GNOME
keyring, not enough attributes".

That is because GNOME keyring seemed to get confused when a network
login has no server name and some extra safeguards were added to
SyncEvolution to avoid this.

To store the credentials in the case above, the email address now gets
split into user and domain part and together get used to look up the
password.
2014-07-24 15:39:35 +02:00
Patrick Ohly 76599a8056 autotools, NEWS: SyncEvolution 1.4.99.3 2014-07-23 12:29:44 +02:00
Patrick Ohly 834c1e7a6b ephemeral sync: don't write binfile client files (FDO #55921)
When doing PBAP caching, we don't want any meta data written because
the next sync would not use it anyway. With the latest libsynthesis
we can configure "/dev/null" as datadir for the client's binfiles and
libsynthesis will avoid writing them.

The PIM manager uses this for PBAP syncing automatically. For testing
it can be enabled by setting the SYNCEVOLUTION_EPHEMERAL env variable.
2014-07-23 10:48:19 +02:00