Couple of comments after implementing some of this in the UI.
On 05/11/2011 04:31 PM, Ohly, Patrick wrote:
On Mo, 2010-12-20 at 11:07 +0100, Patrick Ohly wrote:
> I'd like to solicit some feedback about configuring local sync, in
> particular command line options for it. I'm still debating this with
> myself, so consider the following email as "thinking aloud"...
> As you might remember from the "local sync" mail thread, local sync uses
> two configurations (using a "foo" server implementing some protocol
> "bar" as example):
> 1. "source" config @foo defines sources which access "foo"
> the "bar" protocol; source-config@foo provides additional
> per-peer settings like a URL or username/password
> 2. "sync" config foo has syncURL=local://@foo and does a sync
> involving local databases (the same ones also used with other
> peers) and the databases accessible via @foo
> The original plan was to avoid the need for the source-config@foo
> settings. But that neglected that credentials for "foo" should be tried
> to the @foo context, instead of putting them elsewhere, and that there
> was no other property which could have been used for the URL, to name
> just one example.
> This setup with two configs leads to two usability problems:
> * How can such a config be created from a template? "syncevolution
> --configure foo" would be nice.
I said earlier that I wanted to to postpone this until after 1.2.
There's now more interest again in SyncEvolution in MeeGo also as the
main sync daemon with its own configuration, and for that we need a
solution. So let's revisit the topic.
Another open issue is storing credentials and advanced authentication
methods. We now have the situation that the Google username/password are
needed for the "google" template (= SyncML, contacts) and
"google-calendar" (= CalDAV, events). There should be some way of only
storing them once such that they get used everywhere.
Advanced authentication methods are primarily for CalDAV/CardDAV: some
servers might work with special cookies in the HTTP requests, with those
cookies obtained by some SSO daemon (like the one in Maemo Harmattan).
> Templates for local sync
> The current set of templates provide properties for just one
> configuration, the one which uses SyncML to talk to a server or a
> client. Creating a local sync involves creating two configs.
> There is no 1:1 mapping between the two. It is possible to define the
> @foo sources, then synchronize them with a) the @default sources with
> foo@default and b) with a second set of sources in @bar config with
> In the "syncevolution --configure foo" invocation, "foo" is the
> the sync config. But what is the name of the source config? I propose
> the following heuristic:
> * if syncURL=local:// (no explicit context): use @foo for peer
> name foo[@context]
> * if syncURL=local://@bar: use @bar
I've come to the conclusion that shoe-horning this "create source config
automatically" approach into the command line tool just isn't worth it.
"syncevolution --configure ... foo" should touch config "foo" and
alone. Otherwise we get into lots of tricky corner cases, like which
sources will be configured in "configure foo bar".
It's still useful to have the extended templates with default values for
sync and source config. That way it is possible to define that
"google-calendar" is a local sync with CalDAV in the source config.
An extended template "foo" would define properties for the sync config
"foo" and properties for one or more configs; only one would be used in
Then the command line operations pick up the values from the extended
template depending on which config they are manipulating. Let's look at
> A template for "foo" then might look like this:
> === template.ini ===
> fingerprint = Foo Server
> description = sync with Foo using protocol Bar
> === config.ini ===
> PeerIsClient = 1
> syncURL = local://
This needs to be "local://@foo" under the revised proposal.
> === sources/addressbook/config.ini ===
> sync = two-way
> uri = addressbook
> === config.ini@source-config@foo ===
> syncURL = http://foo.com/
> === sources/addressbook/config.ini@foo ===
> uri = /contacts
> type = Bar Protocol
"--configure foo" => use config.ini and sources/addressbook/config.ini
from template "foo"
"--configure --template=foo xyz" => same
"--configure source-config@foo" => pick template "foo", use
config.ini@source-config@foo and sources/addressbook/config.ini@foo
"--configure @foo" => pick template "foo", use only
This is not that big of a deal to do in the client but it does create a
need for yet another check in quite a few places. It's probably possible
to do these in a way that isn't a mess, but the gtk ui has definitely
organically grown into one :)
> In the D-Bus interface, this would be returned by GetConfig()
with "" as
> key for "config.ini", "source-config@foo" for config.ini inside
> source-config@foo config, "sources/addressbook" for
> sources/addressbook/config.ini and sources/addressbook@foo for
Now, in the D-Bus interface such an extension of the API is a different
matter. The hashes in GetConfig/SetConfig extend much more naturally to
the additional entries than the command line parameters.
Damn, I actually missed this one on the first read -- I had read/written
the configs separately and Gabriel no doubt did the same on my que
(sorry about that Gabriel). All the better, I'd really rather get rid
of those extra calls: using source configs "embedded" in the config hash
does sound better.
Is this (D-Bus configs expanding into multiple real configs) usable
already or just the plan? The template does not seem to work that way...
> My hope is that sync-ui will simply preserve these additional
> the hash. When it does a "SetConfig()" call with the modified hash
> (credentials inserted, sync mode for "adddressbook" set), these
> additional entries tell the syncevo-dbus-server to do its magic and also
> configure the @foo context. The advantage is that no or only minimal
> changes to sync-ui and D-Bus interface will be needed.
> The drawback is that this additional magic increases the complexity. For
> example, SetConfig() is called for the "foo" config, but suddenly ends
> up modifying a different config.
I think this is acceptable.
Yes, definitely better than doing the same magic in the ui.
I'm wondering how the templates should look: If I ask for
google_calendar template over dbus, should I get the webdav source
template like I do now or this "enhanced local template" with the
source-config as a sub-hashtable? It would make sense to get the
enhanced version: this way the client really wouldn't have to understand
about the extended configs (as long as they preserved the extra config
keys and values...)
> Password handling in local sync
> Credentials in the sync config are not needed for the sync itself,
> because the peer is part of the same process. But users and frontends
> like the GTK sync-ui are used to setting credentials in the sync config.
> Therefore I suggest that local sync should always apply sync credentials
> to the context it is synchronizing with, if they are set in the sync
> config. If they are empty, the values from the source config are used.
That's how it works now and I intend to keep it.
But it needs to be extended for advanced credentials. Here's my
proposal. Let's look at the current status.
We have "username", "password", "syncURL" properties. If
"-", then reading credentials looks up the password based on the given
username and the syncURL in the GNOME keyring (or soon, KWallet). The
"server" and "user" keys are used as search filter, with
to the syncURL minus the method prefix (i.e., http:// and https://
Storing a "password" not equal to "-" will automatically set the
password value in the keyring if its usage is enabled (on by default in
the D-Bus server, off in the command line).
Retrieving the config via D-Bus transparently retrieves the credentials
and sends them to the D-Bus client.
I'd like to extend this so that the username doesn't have to be know in
advance, and so that CalDAV and SyncML can refer to the same server
despite having different syncURLs.
"credentials = URI": Defines where credentials are stored. The empty
string (default) is the traditional approach.
"gnome://server=<server>[&user=<user>]" takes username and
the corresponding entry. "kde://" does the same for KWallet.
"keyring://" is an alias for the default keyring (depends on how the
binary was compiled and runtime environment). Saving a config will
always update the "credentials" property with the actual location.
Possible switch to org.freedesktop.Secrets should be kept in mind -- and
I don't see any problem with that.
As a sidenote, org.freedesktop.Secrets is now closer than ever as also
the KDE implementation now seems to exists (even if still in unstable
form). Maybe this silliness of having to support two APIs will soon go away.
Here are some use cases for this:
* The "google" and "google-calendar" configs will have
"credentials = keyring://server=google" set. In the case of
"google-calendar", both the sync and source configs have that.
That way all three configs use the same username/password
automatically. It forces command line users who do not want to
or can't use a keyring to configure with empty "credentials";
they can't share credentials.
* After configuring via the D-Bus interface, the command line will
automatically enable the right access method for the
credentials. It is no longer necessary to explicitly say
* A future extension would use either a different method or
additional parameters in the URI to define some other
authorization method. The current implementation must throw an
error when running into something it doesn't know.
Nothing needs to be done in the UI or the command line to support this.
The only changes will be in the current code which talks to the
I mentioned that the source-config password lookup doesn't actually use
the keyring at the moment -- if saving credentials in the local config
works as well, then this is currently an academic problem that doesn't